Esempio n. 1
0
        public void Dispatch <T>(DispatcherEvent key, T arg)
        {
            List <object> events = null;

            if (m_Dispatcher.TryGetValue(key, out events))
            {
                object e = null;
                // for (int i = events.Count - 1; i >= 0; i--)
                for (int i = 0; i < events.Count; i++)
                {
                    if (events.Count > i) // for events.Clear()
                    {
                        e = events[i];
                        if (e is System.Action <T> )
                        {
                            ((System.Action <T>)e)(arg);
                        }
                        else if (e is System.Action <object> )
                        {
                            ((System.Action <object>)e)(arg);
                        }
                    }
                }
            }
        }
Esempio n. 2
0
        public void RemoveListener(DispatcherEvent key, System.Action <object> action)
        {
            List <object> events = null;

            if (m_Dispatcher.TryGetValue(key, out events))
            {
                events.Remove(action);
            }
        }
Esempio n. 3
0
        public void RemoveListenerByKey(DispatcherEvent key)
        {
            List <object> events = null;

            if (m_Dispatcher.TryGetValue(key, out events))
            {
                events.Clear();
            }
        }
Esempio n. 4
0
        public void AddListener <T>(DispatcherEvent key, System.Action <T> action)
        {
            List <object> events = null;

            if (!m_Dispatcher.TryGetValue(key, out events))
            {
                events = new List <object>();//new List<TriggerEvent>();
                m_Dispatcher.Add(key, events);
            }

            events.Add(action);
        }
Esempio n. 5
0
        public void Dispatch <T>(DispatcherEvent key, T arg)
        {
            List <object> events = null;

            if (m_Dispatcher.TryGetValue(key, out events))
            {
                object e = null;
                for (int i = events.Count - 1; i >= 0; i--)
                {
                    e = events[i];
                    if (e is System.Action <T> )
                    {
                        ((System.Action <T>)e)(arg);
                    }
                }
            }
        }
Esempio n. 6
0
        public void Dispatcher(DispatcherEvent key, object arg)
        {
            List <object> events = null;

            if (m_Dispatcher.TryGetValue(key, out events))
            {
                object e = null;
                for (int i = events.Count - 1; i >= 0; i--) //倒着执行防止删除后少执行一次bug
                {
                    e = events[i];
                    if (e is System.Action <object> )
                    {
                        ((System.Action <object>)e)(arg);
                    }
                }
            }
        }
Esempio n. 7
0
        internal Yield PublishEvent(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            DispatcherEvent ev;

            try {
                ev = new DispatcherEvent(request);
                _log.DebugFormat("{0} received event '{1}'", this.Self.Uri, ev.Id);
                if (ev.Channel.Scheme == "pubsub")
                {
                    response.Return(DreamMessage.Forbidden("events published into this service cannot be of scheme 'pubsub'"));
                    yield break;
                }
                _dispatcher.Dispatch(ev);
                response.Return(DreamMessage.Ok(ev.GetEventEnvelope()));
            } catch (Exception e) {
                response.Return(DreamMessage.BadRequest(e.Message));
            }
            yield break;
        }
Esempio n. 8
0
 public void AddListener(DispatcherEvent key, System.Action <object> action)
 {
     AddListener <object>(key, action);
 }
Esempio n. 9
0
        protected override Yield GetListenersByChannelResourceMatch(DispatcherEvent ev, Result <Dictionary <XUri, List <PubSubSubscription> > > result)
        {
            if (!ev.Channel.Segments[1].EqualsInvariantIgnoreCase("pages"))
            {
                // not a page DispatcherEvent or a page delete DispatcherEvent, use default matcher
                Result <Dictionary <XUri, List <PubSubSubscription> > > baseResult;
                yield return(baseResult = Coroutine.Invoke(base.GetListenersByChannelResourceMatch, ev, new Result <Dictionary <XUri, List <PubSubSubscription> > >()));

                result.Return(baseResult);
                yield break;
            }
            var matches = new List <PubSubSubscription>();

            if (ev.Channel.Segments.Length <= 2 || !ev.Channel.Segments[2].EqualsInvariantIgnoreCase("delete"))
            {
                // dispatch to all PubSubSubscriptions that listen for this DispatcherEvent and its contents
                XDoc   evDoc  = ev.AsDocument();
                uint?  pageid = evDoc["pageid"].AsUInt;
                string wikiId = evDoc["@wikiid"].AsText;
                bool   first  = true;
                _log.DebugFormat("trying dispatch based on channel & page PubSubSubscriptions for page '{0}' from wiki '{1}'", pageid, wikiId);

                // fetch parent page id's for this page so that we can resolve infinite depth PubSubSubscriptions
                Result <DreamMessage> pageHierarchyResult;
                yield return(pageHierarchyResult = _deki.At("pages", pageid.ToString()).WithHeader("X-Deki-Site", "id=" + wikiId).GetAsync());

                DreamMessage pageHierarchy = pageHierarchyResult.Value;
                if (pageHierarchy.IsSuccessful)
                {
                    XDoc pageDoc = pageHierarchy.ToDocument();
                    while (pageid.HasValue)
                    {
                        List <Tuplet <PubSubSubscription, bool> > subs;
                        _subscriptionsByPage.TryGetValue(pageid.Value, out subs);
                        if (subs != null)
                        {
                            // only the first pageId (the one from the event) triggers on non-infinite depth subs
                            foreach (var sub in subs)
                            {
                                if ((sub.Item2 || first) && !matches.Contains(sub.Item1))
                                {
                                    matches.Add(sub.Item1);
                                }
                            }
                        }

                        // get parent id and then set pageDoc to the parent's subdoc, so we can descend the ancesstor tree further
                        pageid  = pageDoc["page.parent/@id"].AsUInt;
                        pageDoc = pageDoc["page.parent"];
                        first   = false;
                    }
                }
                else
                {
                    _log.WarnFormat("unable to retrieve page doc for page '{0}': {1}", pageid, pageHierarchy.Status);
                }
            }
            ICollection <PubSubSubscription> listeningSubs;

            lock (_channelMap) {
                // get all the PubSubSubscriptions that are wild card matches (which is basically those that didn't
                // have any resources in their PubSubSubscription) and add them to the above matches
                foreach (var sub in _resourceMap.GetMatches(new XUri("http://dummy/dummy")))
                {
                    if (!matches.Contains(sub))
                    {
                        matches.Add(sub);
                    }
                }
                listeningSubs = _channelMap.GetMatches(ev.Channel, matches);
            }
            var listeners = new Dictionary <XUri, List <PubSubSubscription> >();

            foreach (var sub in listeningSubs)
            {
                List <PubSubSubscription> subs;
                if (!listeners.TryGetValue(sub.Destination, out subs))
                {
                    subs = new List <PubSubSubscription>();
                    listeners.Add(sub.Destination, subs);
                    subs.Add(sub);
                }
                else if (!subs.Contains(sub))
                {
                    subs.Add(sub);
                }
            }
            result.Return(listeners);
            yield break;
        }
Esempio n. 10
0
 public static void DispatchInt(this GlobalDispatcher self, DispatcherEvent key, int arg)
 {
     self.Dispatch <int>(key, arg);
 }
Esempio n. 11
0
 public static void RemoveListenerInt(this GlobalDispatcher self, DispatcherEvent key, System.Action <int> action)
 {
     self.RemoveListener <int>(key, action);
 }
Esempio n. 12
0
 public static void DispatchBool(this GlobalDispatcher self, DispatcherEvent key, bool arg)
 {
     self.Dispatch <bool>(key, arg);
 }
Esempio n. 13
0
        public void InstanceKey_authtoken_gets_verified_against_deki()
        {
            var mockDeki            = new XUri("http://mock/deki");
            var dispatcherUri       = new XUri("http://mock/dispatcher");
            var authorizedRecipient = new XUri("http://mock/authorized");
            var dispatcher          = new DekiDispatcher(
                new DispatcherConfig {
                ServiceUri          = dispatcherUri,
                ServiceAccessCookie = new DreamCookie("service-key", "foo", dispatcherUri),
                ServiceConfig       = new XDoc("config").Elem("uri.deki", mockDeki).Elem("authtoken", "abc")
            },
                _mockRepository.Object
                );
            var sub = new XDoc("subscription-set")
                      .Elem("uri.owner", authorizedRecipient)
                      .Start("subscription")
                      .Attr("id", "1")
                      .Elem("channel", "event://default/deki/pages/*")
                      .Start("recipient").Attr("authtoken", "def").Elem("uri", authorizedRecipient).End()
                      .End();

            _log.DebugFormat("registering sub set");
            dispatcher.RegisterSet("abc", sub, "def");
            Assert.IsTrue(Wait.For(
                              () => dispatcher.CombinedSet.Subscriptions
                              .Where(s =>
                                     s.Channels.Where(c => c.ToString() == "event://default/deki/pages/*").Any() &&
                                     !s.Resources.Any()
                                     ).Any(),
                              10.Seconds()));
            MockPlug.Setup(mockDeki)
            .Verb("GET")
            .At("site", "settings")
            .With("apikey", "abc")
            .WithHeader("X-Deki-Site", "id=default")
            .Returns(new XDoc("config").Start("security").Elem("api-key", "def").End())
            .ExpectCalls(Times.Once());
            MockPlug.Setup(authorizedRecipient)
            .Verb("POST")
            .WithMessage(r => {
                if (!r.HasDocument)
                {
                    return(false);
                }
                var doc = r.ToDocument();
                _log.Debug(doc.ToPrettyString());
                return(doc["channel"].AsText == "event://default/deki/pages/update" &&
                       doc["pageid"].AsText == "10");
            })
            .ExpectCalls(Times.Once());
            var evDoc = new XDoc("deki-event")
                        .Attr("wikiid", "default")
                        .Elem("channel", "event://default/deki/pages/update")
                        .Elem("uri", "deki://default/pages/10")
                        .Elem("pageid", "10");
            var ev = new DispatcherEvent(evDoc, new XUri("event://default/deki/pages/update"), new XUri("deki://default/pages/10"), new XUri("http://default/deki/pages/10"));

            _log.DebugFormat("ready to dispatch event");
            dispatcher.Dispatch(ev);
            MockPlug.VerifyAll(TimeSpan.FromSeconds(10));
        }
Esempio n. 14
0
 public void Dispatch(DispatcherEvent key, object arg)
 {
     Dispatch <object>(key, arg);
 }
Esempio n. 15
0
 public static void RemoveListenerVector3(this GlobalDispatcher self, DispatcherEvent key, System.Action <Vector3> action)
 {
     self.RemoveListener <Vector3>(key, action);
 }
Esempio n. 16
0
        public override void Run(DebugAdapterRunner runner)
        {
            // Send the request
            string request = CreateDispatcherRequest(runner);

            // VSCode doesn't send /n at the end. If this is writeline, then concord hangs
            runner.DebugAdapter.StandardInput.Write(request);

            // Process + validate responses
            List <object> responseList = new List <object>();
            int           currentExpectedResponseIndex = 0;

            // Loop until we have received as many expected responses as expected
            while (currentExpectedResponseIndex < this.ExpectedResponses.Count)
            {
                string    receivedMessage      = null;
                Exception getMessageExeception = null;
                try
                {
                    receivedMessage = this.GetMessage(
                        runner.DebugAdapter.StandardOutput.BaseStream,
                        runner.ResponseTimeout,
                        runner.DebugAdapter,
                        runner);
                }
                catch (Exception e)
                {
                    getMessageExeception = e;
                }

                if (getMessageExeception != null)
                {
                    if (!runner.DebugAdapter.HasExited)
                    {
                        // If it hasn't exited yet, wait a little bit longer to make sure it isn't just about to exit
                        try
                        {
                            runner.DebugAdapter.WaitForExit(500);
                        }
                        catch
                        { }
                    }

                    string messageStart;
                    if (runner.DebugAdapter.HasExited)
                    {
                        if (runner.HasAsserted())
                        {
                            messageStart = string.Format(CultureInfo.CurrentCulture, "The debugger process has asserted and exited with code '{0}' without sending all expected responses. See test log for assert details.", runner.DebugAdapter.ExitCode);
                        }
                        else
                        {
                            messageStart = string.Format(CultureInfo.CurrentCulture, "The debugger process has exited with code '{0}' without sending all expected responses.", runner.DebugAdapter.ExitCode);
                        }
                    }
                    else if (getMessageExeception is TimeoutException)
                    {
                        if (runner.HasAsserted())
                        {
                            messageStart = "The debugger process has asserted. See test log for assert details.";
                        }
                        else
                        {
                            messageStart = "Expected response not found before timeout.";
                        }
                    }
                    else
                    {
                        messageStart = "Exception while reading message from debug adpter. " + getMessageExeception.Message;
                    }

                    string expectedResponseText = JsonConvert.SerializeObject(this.ExpectedResponses[currentExpectedResponseIndex].Response);
                    string actualResponseText   = string.Empty;

                    for (int i = 0; i < responseList.Count; i++)
                    {
                        actualResponseText += string.Format(CultureInfo.CurrentCulture, "{0}. {1}\n", (i + 1), JsonConvert.SerializeObject(responseList[i]));
                    }

                    string errorMessage = string.Format(CultureInfo.CurrentCulture, "{0}\nExpected = {1}\nActual Responses =\n{2}",
                                                        messageStart, expectedResponseText, actualResponseText);

                    throw new DARException(errorMessage);
                }

                try
                {
                    DispatcherMessage dispatcherMessage = JsonConvert.DeserializeObject <DispatcherMessage>(receivedMessage);

                    if (dispatcherMessage.type == "event")
                    {
                        DispatcherEvent dispatcherEvent = JsonConvert.DeserializeObject <DispatcherEvent>(receivedMessage);
                        responseList.Add(dispatcherEvent);

                        if (dispatcherEvent.eventType == "stopped")
                        {
                            runner.CurrentThreadId = dispatcherEvent.body.threadId;
                        }

                        var expected = this.ExpectedResponses[currentExpectedResponseIndex];
                        if (Utils.CompareObjects(expected.Response, dispatcherEvent, expected.IgnoreOrder))
                        {
                            expected.Match = dispatcherEvent;
                            currentExpectedResponseIndex++;
                        }
                    }
                    else if (dispatcherMessage.type == "response")
                    {
                        DispatcherResponse dispatcherResponse = JsonConvert.DeserializeObject <DispatcherResponse>(receivedMessage);
                        responseList.Add(dispatcherResponse);

                        var expected = this.ExpectedResponses[currentExpectedResponseIndex];
                        if (Utils.CompareObjects(expected.Response, dispatcherResponse, expected.IgnoreOrder))
                        {
                            expected.Match = dispatcherResponse;
                            currentExpectedResponseIndex++;
                        }
                    }
                    else if (dispatcherMessage.type == "request")
                    {
                        runner.HandleCallbackRequest(receivedMessage);
                    }
                    else
                    {
                        throw new DARException(String.Format(CultureInfo.CurrentCulture, "Unknown Dispatcher Message type: '{0}'", dispatcherMessage.type));
                    }
                }
                catch (JsonReaderException)
                {
                    runner.AppendLineToDebugAdapterOutput("Response could not be parsed as json. This was the response:");
                    runner.AppendLineToDebugAdapterOutput(receivedMessage);
                    throw;
                }
            }
        }
Esempio n. 17
0
 public static void AddListenerFloat(this GlobalDispatcher self, DispatcherEvent key, System.Action <float> action)
 {
     self.AddListener <float>(key, action);
 }
Esempio n. 18
0
        public void Subscribers_to_a_single_page_do_not_get_escalated_by_a_subscriber_with_infinite_depth_on_same_page()
        {
            var mockDekiUri = new XUri("http://mock/deki");
            var mockDeki    = MockPlug.Register(mockDekiUri);

            mockDeki.Expect().Verb("GET").Uri(mockDekiUri.At("pages", "10")).Response(DreamMessage.Ok(new XDoc("page")
                                                                                                      .Attr("id", "10")
                                                                                                      .Start("page.parent")
                                                                                                      .Attr("id", "9")
                                                                                                      .Start("page.parent")
                                                                                                      .Attr("id", "8")
                                                                                                      .Start("page.parent")
                                                                                                      .Attr("id", "7")
                                                                                                      .EndAll()));
            var dispatcherUri = new XUri("http://mock/dispatcher");
            var dispatcher    = new DekiDispatcher(
                new DispatcherConfig {
                ServiceUri          = dispatcherUri,
                ServiceAccessCookie = new DreamCookie("service-key", "foo", dispatcherUri),
                ServiceConfig       = new XDoc("config").Elem("uri.deki", mockDekiUri).Elem("authtoken", "abc")
            },
                _mockRepository.Object
                );
            var combinedSetUpdated = 0;

            dispatcher.CombinedSetUpdated += (o, e) => {
                combinedSetUpdated++;
            };

            // subscribe to page 7 and all children
            var mockHierarchyRecipientUri = new XUri("http://mock/recipient/hierarchy");
            var mockHierarchyRecipient    = MockPlug.Register(mockHierarchyRecipientUri);

            mockHierarchyRecipient.Expect().Verb("POST");
            dispatcher.RegisterSet(
                "location1",
                new XDoc("subscription-set")
                .Elem("uri.owner", mockHierarchyRecipientUri)
                .Start("subscription")
                .Attr("id", "3")
                .Elem("uri.resource", "deki://default/pages/7#depth=infinity")
                .Elem("channel", "event://default/deki/pages/*")
                .Start("recipient").Attr("authtoken", "abc").Elem("uri", mockHierarchyRecipientUri).End()
                .End(),
                "def"
                );

            // subscribe to only page 7
            var mockPageonlyRecipientUri    = new XUri("http://mock/recipient/pageonly");
            var mockPageonlyRecipientCalled = 0;

            MockPlug.Register(mockPageonlyRecipientUri, delegate(Plug p, string v, XUri u, DreamMessage r, Result <DreamMessage> r2) {
                _log.DebugFormat("mockPageonlyRecipient called at: {0}", u);
                mockPageonlyRecipientCalled++;
                r2.Return(DreamMessage.Ok());
            });
            dispatcher.RegisterSet(
                "location2",
                new XDoc("subscription-set")
                .Elem("uri.owner", mockPageonlyRecipientUri)
                .Start("subscription")
                .Attr("id", "3")
                .Elem("uri.resource", "deki://default/pages/7")
                .Elem("channel", "event://default/deki/pages/*")
                .Start("recipient").Attr("authtoken", "abc").Elem("uri", mockPageonlyRecipientUri).End()
                .End(),
                "def"
                );

            // wait for subscriptions to be set up
            _log.DebugFormat("wait for subscriptions to be updated");
            Assert.IsTrue(
                Wait.For(() => combinedSetUpdated == 2, TimeSpan.FromSeconds(10)),
                string.Format("timeout waiting for subscriptions, expected 2, got {0} dispatches", combinedSetUpdated));

            // fire page change for page 10 (sub-child of page 7)
            XDoc evDoc = new XDoc("deki-event")
                         .Attr("wikiid", "default")
                         .Elem("channel", "event://default/deki/pages/update")
                         .Elem("uri", "deki://default/pages/10")
                         .Elem("pageid", "10");
            var ev = new DispatcherEvent(evDoc, new XUri("event://default/deki/pages/update"), new XUri("deki://default/pages/10"), new XUri("http://default/deki/pages/10"));

            _log.DebugFormat("ready to dispatch event");
            dispatcher.Dispatch(ev);

            // wait for deki to have been called
            _log.DebugFormat("wait for deki call");
            Assert.IsTrue(mockDeki.WaitAndVerify(TimeSpan.FromSeconds(10)), mockDeki.VerificationFailure);

            // wait for recipients to be notified
            _log.DebugFormat("wait for hierarchy notification");
            Assert.IsTrue(mockHierarchyRecipient.WaitAndVerify(TimeSpan.FromSeconds(10)), mockHierarchyRecipient.VerificationFailure);

            // only 'hierarchy' subscriber should have been notified
            _log.DebugFormat("make sure page only doesn't get called");
            Assert.IsFalse(Wait.For(() => mockPageonlyRecipientCalled > 0, TimeSpan.FromSeconds(5)));
        }
Esempio n. 19
0
        public void Page_delete_events_skip_page_auth()
        {
            XUri mockDeki   = new XUri("http://mock/deki");
            int  dekiCalled = 0;

            MockPlug.Register(mockDeki, delegate(Plug p, string v, XUri u, DreamMessage r, Result <DreamMessage> r2) {
                _log.DebugFormat("mockDeki called at: {0}", u);
                dekiCalled++;
                r2.Return(DreamMessage.BadRequest("shouldn't have called deki"));
            });

            XUri           authorizedRecipient  = new XUri("http://mock/authorized2");
            AutoResetEvent authorizedResetEvent = new AutoResetEvent(false);
            XDoc           authorizedReceived   = null;

            MockPlug.Register(authorizedRecipient, delegate(Plug p, string v, XUri u, DreamMessage r, Result <DreamMessage> r2) {
                _log.DebugFormat("authorizedRecipient called at: {0}", u);
                authorizedReceived = r.ToDocument();
                authorizedResetEvent.Set();
                r2.Return(DreamMessage.Ok());
            });

            XUri mockRecipient       = new XUri("http://mock/r1");
            int  mockRecipientCalled = 0;

            MockPlug.Register(mockRecipient, delegate(Plug p, string v, XUri u, DreamMessage r, Result <DreamMessage> r2) {
                _log.DebugFormat("mockRecipient called at: {0}", u);
                mockRecipientCalled++;
                r2.Return(DreamMessage.Ok());
            });

            XUri           dispatcherUri = new XUri("http://mock/dispatcher");
            DekiDispatcher dispatcher    = new DekiDispatcher(
                new DispatcherConfig {
                ServiceUri          = dispatcherUri,
                ServiceAccessCookie = new DreamCookie("service-key", "foo", dispatcherUri),
                ServiceConfig       = new XDoc("config").Elem("uri.deki", mockDeki).Elem("authtoken", "abc")
            },
                _mockRepository.Object
                );

            XDoc sub1 = new XDoc("subscription-set")
                        .Elem("uri.owner", authorizedRecipient)
                        .Start("subscription")
                        .Attr("id", "1")
                        .Elem("channel", "event://default/deki/pages/*")
                        .Start("recipient").Attr("authtoken", "abc").Elem("uri", authorizedRecipient).End()
                        .End();

            Thread.Sleep(100);
            _log.DebugFormat("registering sub set 1");
            dispatcher.RegisterSet("abc", sub1, "def");
            XDoc sub2 = new XDoc("subscription-set")
                        .Elem("uri.owner", mockRecipient.At("1"))
                        .Start("subscription")
                        .Attr("id", "1")
                        .Elem("uri.resource", "deki://default/pages/10")
                        .Elem("channel", "event://default/deki/pages/*")
                        .Start("recipient").Attr("userid", "1").Elem("uri", "http://mock/r1/match").End()
                        .End();

            Thread.Sleep(100);
            _log.DebugFormat("registering sub set 2");
            dispatcher.RegisterSet("abc", sub2, "def");

            XDoc evDoc = new XDoc("deki-event")
                         .Attr("wikiid", "default")
                         .Elem("channel", "event://default/deki/pages/delete")
                         .Elem("uri", "deki://default/pages/10")
                         .Elem("pageid", "10");
            var ev = new DispatcherEvent(evDoc, new XUri("event://default/deki/pages/delete"), new XUri("deki://default/pages/10"), new XUri("http://default/deki/pages/10"));

            _log.DebugFormat("ready to dispatch event");

            // Meh. Testing multithreaded code is wonky. This 1000ms sleep is required, otherwise the event below never fires
            Thread.Sleep(1000);
            dispatcher.Dispatch(ev);

            // since we're waiting for more than one dekiPageAuthEvent, we give it a chance to finish after the first triggers
            Assert.IsTrue(authorizedResetEvent.WaitOne(5000, false));
            Assert.AreEqual(0, dekiCalled);
            Assert.AreEqual(0, mockRecipientCalled);
            Assert.AreEqual(evDoc, authorizedReceived);
        }
Esempio n. 20
0
        public void Page_events_uses_deki_to_check_parent_wildcard_resource_matches()
        {
            var  dekiPageAuthEvent           = new ManualResetEvent(false);
            var  authorizedRecipientCalledEv = new ManualResetEvent(false);
            var  mockMatchCalledEv           = new ManualResetEvent(false);
            var  mockWildcardCalledEv        = new ManualResetEvent(false);
            XUri mockDeki           = new XUri("http://mock/deki");
            int  dekiPageAuthCalled = 0;
            int  dekiPageCalled     = 0;

            MockPlug.Register(mockDeki, delegate(Plug p, string v, XUri u, DreamMessage r, Result <DreamMessage> r2) {
                XDoc rDoc = null;
                _log.DebugFormat("mockDeki called at: {0}", u);
                if (u.Segments.Length == 3)
                {
                    _log.DebugFormat("getting page xml");
                    if (u.LastSegment == "10")
                    {
                        dekiPageCalled++;
                    }
                    rDoc = new XDoc("page")
                           .Attr("id", "10")
                           .Start("page.parent")
                           .Attr("id", "9")
                           .Start("page.parent")
                           .Attr("id", "8")
                           .Start("page.parent")
                           .Attr("id", "7")
                           .EndAll();
                }
                else
                {
                    _log.DebugFormat("getting users for page: {0}", u.LastSegment);
                    dekiPageAuthCalled++;
                    rDoc = new XDoc("users");
                    foreach (XDoc user in r.ToDocument()["user/@id"])
                    {
                        rDoc.Start("user").Attr("id", user.AsText).End();
                    }
                    if (dekiPageAuthCalled == 2)
                    {
                        dekiPageAuthEvent.Set();
                    }
                }
                r2.Return(DreamMessage.Ok(rDoc));
            });
            XUri authorizedRecipient       = new XUri("http://mock/authorized2");
            int  authorizedRecipientCalled = 0;
            XDoc authorizedReceived        = null;

            MockPlug.Register(authorizedRecipient, delegate(Plug p, string v, XUri u, DreamMessage r, Result <DreamMessage> r2) {
                _log.DebugFormat("authorizedRecipient called at: {0}", u);
                authorizedRecipientCalled++;
                authorizedReceived = r.ToDocument();
                authorizedRecipientCalledEv.Set();
                r2.Return(DreamMessage.Ok());
            });
            XUri mockRecipient       = new XUri("http://mock/r1");
            int  mockRecipientCalled = 0;
            int  mockMatchCalled     = 0;
            int  mockWildcardCalled  = 0;

            MockPlug.Register(mockRecipient, delegate(Plug p, string v, XUri u, DreamMessage r, Result <DreamMessage> r2) {
                _log.DebugFormat("mockRecipient called at: {0}", u);
                mockRecipientCalled++;
                if (u == mockRecipient.At("match"))
                {
                    mockMatchCalled++;
                    mockMatchCalledEv.Set();
                }
                else if (u == mockRecipient.At("wildcard"))
                {
                    mockWildcardCalled++;
                    mockWildcardCalledEv.Set();
                }
                r2.Return(DreamMessage.Ok());
            });
            XUri           dispatcherUri = new XUri("http://mock/dispatcher");
            DekiDispatcher dispatcher    = new DekiDispatcher(
                new DispatcherConfig()
            {
                ServiceUri          = dispatcherUri,
                ServiceAccessCookie = new DreamCookie("service-key", "foo", dispatcherUri),
                ServiceConfig       = new XDoc("config").Elem("uri.deki", mockDeki).Elem("authtoken", "abc")
            },
                _mockRepository.Object
                );
            XDoc sub1 = new XDoc("subscription-set")
                        .Elem("uri.owner", authorizedRecipient)
                        .Start("subscription")
                        .Attr("id", "1")
                        .Elem("channel", "event://default/deki/pages/*")
                        .Start("recipient").Attr("authtoken", "abc").Elem("uri", authorizedRecipient).End()
                        .End();

            _log.DebugFormat("registering sub set 1");
            dispatcher.RegisterSet("location1", sub1, "def");
            Assert.IsTrue(Wait.For(() =>
                                   dispatcher.CombinedSet.Subscriptions
                                   .Where(s =>
                                          s.Channels.Where(c => c.ToString() == "event://default/deki/pages/*").Any() &&
                                          !s.Resources.Any()
                                          ).Any(),
                                   10.Seconds()));

            XDoc sub2 = new XDoc("subscription-set")
                        .Elem("uri.owner", mockRecipient.At("1"))
                        .Start("subscription")
                        .Attr("id", "1")
                        .Elem("uri.resource", "deki://default/pages/10")
                        .Elem("channel", "event://default/deki/pages/*")
                        .Start("recipient").Attr("userid", "1").Elem("uri", "http://mock/r1/match").End()
                        .End();

            _log.DebugFormat("registering sub set 2");
            dispatcher.RegisterSet("location2", sub2, "def");
            Assert.IsTrue(Wait.For(() =>
                                   dispatcher.CombinedSet.Subscriptions
                                   .Where(s =>
                                          s.Channels.Where(c => c.ToString() == "event://default/deki/pages/*").Any() &&
                                          s.Resources.Where(r => r.ToString() == "deki://default/pages/10").Any()
                                          ).Any(),
                                   10.Seconds()));

            XDoc sub3 = new XDoc("subscription-set")
                        .Elem("uri.owner", mockRecipient.At("2"))
                        .Start("subscription")
                        .Attr("id", "2")
                        .Elem("uri.resource", "deki://default/pages/11")
                        .Elem("channel", "event://default/deki/pages/*")
                        .Start("recipient").Attr("userid", "1").Elem("uri", "http://mock/r1/miss").End()
                        .End();

            _log.DebugFormat("registering sub set 3");
            dispatcher.RegisterSet("location3", sub3, "def");
            Assert.IsTrue(Wait.For(() =>
                                   dispatcher.CombinedSet.Subscriptions
                                   .Where(s =>
                                          s.Channels.Where(c => c.ToString() == "event://default/deki/pages/*").Any() &&
                                          s.Resources.Where(r => r.ToString() == "deki://default/pages/11").Any()
                                          ).Any(),
                                   10.Seconds()));

            XDoc sub4 = new XDoc("subscription-set")
                        .Elem("uri.owner", mockRecipient.At("3"))
                        .Start("subscription")
                        .Attr("id", "3")
                        .Elem("uri.resource", "deki://default/pages/8#depth=infinity")
                        .Elem("channel", "event://default/deki/pages/*")
                        .Start("recipient").Attr("userid", "1").Elem("uri", "http://mock/r1/wildcard").End()
                        .End();

            _log.DebugFormat("registering sub set 4");
            dispatcher.RegisterSet("location4", sub4, "def");
            Assert.IsTrue(Wait.For(() =>
                                   dispatcher.CombinedSet.Subscriptions
                                   .Where(s =>
                                          s.Channels.Where(c => c.ToString() == "event://default/deki/pages/*").Any() &&
                                          s.Resources.Where(r => r.ToString() == "deki://default/pages/8#depth%3Dinfinity").Any()
                                          ).Any(),
                                   10.Seconds()));

            XDoc evDoc = new XDoc("deki-event")
                         .Attr("wikiid", "default")
                         .Elem("channel", "event://default/deki/pages/update")
                         .Elem("uri", "deki://default/pages/10")
                         .Elem("pageid", "10");
            var ev = new DispatcherEvent(evDoc, new XUri("event://default/deki/pages/update"), new XUri("deki://default/pages/10"), new XUri("http://default/deki/pages/10"));

            _log.DebugFormat("ready to dispatch event");
            dispatcher.Dispatch(ev);
            Assert.IsTrue(dekiPageAuthEvent.WaitOne(5000, true));
            Assert.IsTrue(authorizedRecipientCalledEv.WaitOne(5000, true));
            Assert.IsTrue(mockMatchCalledEv.WaitOne(5000, true));
            Assert.IsTrue(mockWildcardCalledEv.WaitOne(5000, true));
            Assert.AreEqual(1, dekiPageCalled);
            Assert.AreEqual(2, dekiPageAuthCalled);
            Assert.AreEqual(1, authorizedRecipientCalled);
            Assert.AreEqual(2, mockRecipientCalled);
            Assert.AreEqual(1, mockMatchCalled);
            Assert.AreEqual(1, mockWildcardCalled);
            Assert.AreEqual(evDoc, authorizedReceived);
        }
Esempio n. 21
0
 //--- Constructors ---
 /// <summary>
 /// Create a new dispatch item
 /// </summary>
 /// <param name="uri">Uri the event will be dispatched to.</param>
 /// <param name="event">Event to dispatch.</param>
 /// <param name="location">Location string identifying the <see cref="PubSubSubscriptionSet"/> the event is being dispatched for.</param>
 public DispatchItem(XUri uri, DispatcherEvent @event, string location)
 {
     Uri = uri;
     Event = @event;
     Location = location;
 }
Esempio n. 22
0
 public static void DispatchVector3(this GlobalDispatcher self, DispatcherEvent key, Vector3 arg)
 {
     self.Dispatch <Vector3>(key, arg);
 }
Esempio n. 23
0
 public static void AddListenerVector2(this GlobalDispatcher self, DispatcherEvent key, System.Action <Vector2> action)
 {
     self.AddListener <Vector2>(key, action);
 }
Esempio n. 24
0
 public static void RemoveListenerBool(this GlobalDispatcher self, DispatcherEvent key, System.Action <bool> action)
 {
     self.RemoveListener <bool>(key, action);
 }
Esempio n. 25
0
 public static void DispatchFloat(this GlobalDispatcher self, DispatcherEvent key, float arg)
 {
     self.Dispatch <float>(key, arg);
 }
Esempio n. 26
0
        protected override Yield FilterRecipients(DispatcherEvent ev, PubSubSubscription subscription, Result <DispatcherEvent> result)
        {
            var    recipients2 = new List <DispatcherRecipient>();
            uint?  pageid      = null;
            string wikiId      = null;

            if (ev.HasDocument)
            {
                var changeDoc = ev.AsDocument();
                pageid = changeDoc["pageid"].AsUInt;
                wikiId = changeDoc["@wikiid"].AsText;
            }
            var userIds = new Dictionary <int, DispatcherRecipient>();

            foreach (var recipient in subscription.Recipients)
            {
                var authtoken = recipient.Doc["@authtoken"].AsText;
                if (string.IsNullOrEmpty(authtoken))
                {
                    // if the recipient has no authtoken, but has a userid, collect the Id so we can authorize it against the page
                    int?userId = recipient.Doc["@userid"].AsInt;
                    if (userId.HasValue)
                    {
                        userIds.Add(userId.Value, recipient);
                    }
                }
                else if (authtoken == _authtoken)
                {
                    // master authtoken means the recipient doesn't need page level authorization (such as lucene)
                    recipients2.Add(recipient);
                }
                else if (!string.IsNullOrEmpty(wikiId))
                {
                    var key = authtoken + ":" + wikiId;
                    if (!_validatedKeys.Contains(key))
                    {
                        // no valid key found, need to check with API to validate
                        XDoc settings = null;
                        yield return(_deki.At("site", "settings")
                                     .With("apikey", _authtoken)
                                     .WithHeader("X-Deki-Site", "id=" + wikiId)
                                     .Get(new Result <DreamMessage>())
                                     .Set(x => settings = x.IsSuccessful ? x.ToDocument() : null));

                        if (settings == null || !authtoken.EqualsInvariant(settings["security/api-key"].AsText))
                        {
                            continue;
                        }
                        _validatedKeys.Add(key);
                    }

                    // instance authtoken means the recipient doesn't need page level authorization (such as lucene)
                    recipients2.Add(recipient);
                }
            }
            if (userIds.Count > 0 && (ev.Channel.Segments.Length <= 2 || !ev.Channel.Segments[2].EqualsInvariantIgnoreCase("delete")))
            {
                // check all userId's against the page to prune set to authorized users
                var users = new XDoc("users");
                foreach (int userid in userIds.Keys)
                {
                    users.Start("user").Attr("id", userid).End();
                }
                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;
        }