public when_using_listener_start_with_custom_stream_synched_bus(StreamStoreConnectionFixture fixture)
        {
            conn = fixture.Connection;
            conn.Connect();

            // Build an origin stream from strings to which the the events are appended
            var originStreamName = $"testStream-{Guid.NewGuid():N}";

            var result = fixture.Connection.AppendToStream(
                originStreamName,
                ExpectedVersion.NoStream,
                null,
                _eventSerializer.Serialize(new TestEvent()));

            Assert.True(result.NextExpectedVersion == 0);

            // Wait for the stream to be written
            CommonHelpers.WaitForStream(conn, originStreamName);

            listener = new QueuedStreamListener(
                originStreamName,
                fixture.Connection,
                new PrefixedCamelCaseStreamNameBuilder(),
                _eventSerializer,
                "BUS_NAME",
                LiveProcessingStarted);
            SubscriptionDisposer = listener.EventStream.Subscribe(new AdHocHandler <Event>(Handle));
            listener.Start(originStreamName);
        }
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            IEventStoreConnection conn = EventStoreConnection.Create("ConnectTo=tcp://admin:changeit@localhost:1113");

            conn.Connected += (_, __) => Console.WriteLine("Connected");
            conn.ConnectAsync().Wait();

            conn.AppendToStreamAsync("Test", ExpectedVersion.Any, new[] {
                new EventData(
                    Guid.NewGuid(),
                    "TestEvent",
                    false,
                    Encoding.UTF8.GetBytes("Test event data"),
                    Encoding.UTF8.GetBytes("Test event Metadata"))
            });

            Console.WriteLine("Event Written");

            var evt = conn.ReadStreamEventsForwardAsync("Test", StreamPosition.Start, 1, false).Result;

            Console.WriteLine(Encoding.UTF8.GetString(evt.Events[0].Event.Data));
            Console.ReadKey();
            return;

            IStreamStoreConnection streamConn  = new EventStoreConnectionWrapper(conn);
            IStreamNameBuilder     nameBuilder = new PrefixedCamelCaseStreamNameBuilder();
            IEventSerializer       serializer  = new JsonMessageSerializer();
            IRepository            repo        = new StreamStoreRepository(nameBuilder, streamConn, serializer);

            repo.Save(new Account(Guid.NewGuid()));

            IListener myListener = new StreamListener("Account Listener", streamConn, nameBuilder, serializer);
        }
Exemple #3
0
        public void AllowReconnectionAfterDisconnection()
        {
            Mock <IResourceFacade> resource  = new Mock <IResourceFacade>();
            Mock <IAdapterPlugin>  connector = new Mock <IAdapterPlugin>();
            Mock <IEventState>     state     = new Mock <IEventState>();
            Mock <ISettings>       settings  = new Mock <ISettings>();

            var provider = new StateManager(settings.Object, connector.Object);

            Fixture fixture = new Fixture {
                Id = "Reconnect", Sequence = 1, MatchStatus = ((int)MatchStatus.InRunning).ToString()
            };

            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning);
            resource.Setup(r => r.Id).Returns("Reconnect");
            resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected += null, EventArgs.Empty);
            resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture));

            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, settings.Object);

            listener.Start();

            listener.IsStreaming.Should().BeTrue();

            listener.ResourceOnStreamDisconnected(this, EventArgs.Empty);

            listener.IsStreaming.Should().BeFalse();

            listener.UpdateResourceState(resource.Object);

            listener.IsStreaming.Should().BeTrue();
        }
Exemple #4
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            //if (env.IsDevelopment())
            //{
            //    app.UseDeveloperExceptionPage();
            //}
            //else
            //{
            //    app.UseExceptionHandler("/Home/Error");
            //}

            app.UseDeveloperExceptionPage();

            app.UseCors(builder =>
                        builder.AllowAnyOrigin()
                        //builder.WithOrigins("http://quincy.com")
                        );

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });

            StreamListener.Init(app.ApplicationServices).ConfigureAwait(false);
        }
        public virtual RequestHandle bindSession(BindSessionRequest request, StreamListener reqListener, long tcpConnectTimeout, long tcpReadTimeout, ListenableFuture requestFuture)
        {
            RequestHandle handle = transport.sendRequest(protocol, request, reqListener, options.HttpExtraHeadersOnSessionCreationOnly ? null : options.HttpExtraHeaders, options.Proxy, tcpConnectTimeout, tcpReadTimeout);

            requestFuture.fulfill();
            return(handle);
        }
        public void ShouldStartAndStopListening()
        {
            var fixtureSnapshot = new Fixture { Id = "TestId", MatchStatus = "30", Sequence = 1 };
            var plugin = new Mock<IAdapterPlugin>();

            var resource = new Mock<IResourceFacade>();
            var connector = new Mock<IAdapterPlugin>();
            var eventState = new Mock<IEventState>();
            
            var marketFilterObjectStore = new StateManager(_settings.Object,plugin.Object);
            
            resource.Setup(r => r.Sport).Returns("Football");
            resource.Setup(r => r.Content).Returns(new Summary());
            resource.Setup(r => r.StartStreaming()).Raises(r => r.StreamConnected += null, EventArgs.Empty);
            resource.Setup(r => r.StopStreaming()).Raises(r => r.StreamDisconnected += null, EventArgs.Empty);
            resource.Setup(r => r.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixtureSnapshot));
            resource.Setup(r => r.Id).Returns("TestId");
            eventState.Setup(e => e.GetCurrentSequence(It.IsAny<string>(), It.IsAny<string>())).Returns(-1);

            var listener = new StreamListener(resource.Object, connector.Object, eventState.Object, marketFilterObjectStore,_settings.Object);
            
            listener.MonitorEvents();
            
            listener.Start();

            listener.Stop();

            listener.ShouldRaise("OnConnected");
            listener.ShouldNotRaise("OnError");
            listener.ShouldRaise("OnStop");
            listener.ShouldNotRaise("OnDisconnected","The disconnection is triggered by the user");

            connector.Verify(c => c.ProcessSnapshot(It.IsAny<Fixture>(), false), Times.Once());
        }
        public void DoNotSuspendFixtureOnDisconeectIfDeletedTest()
        {
            // STEP 1: prepare stub data
            Mock <IResourceFacade> resource  = new Mock <IResourceFacade>();
            Mock <IAdapterPlugin>  connector = new Mock <IAdapterPlugin>();
            Mock <IEventState>     state     = new Mock <IEventState>();
            Mock <ISettings>       settings  = new Mock <ISettings>();
            var provider = new StateManager(settings.Object, connector.Object);


            // STEP 3: prepare the fixture data
            Fixture fixture = new Fixture {
                Id = "ABC", Sequence = 1, MatchStatus = ((int)MatchStatus.InRunning).ToString()
            };

            fixture.Tags.Add("Sport", "Football"); // add at least one tags, so the MarketsRulesManager recognize it as a full-snapshot

            fixture.Markets.Add(new Market("MKT-1"));
            var mkt = new Market("MKT-2");

            mkt.AddOrUpdateTagValue("traded_in_play", "false");
            fixture.Markets.Add(mkt);

            // ...and MatchStatus=MatchOver
            Fixture update = new Fixture
            {
                Id                    = "ABC",
                Sequence              = 2,
                MatchStatus           = ((int)MatchStatus.InRunning).ToString(),
                Epoch                 = 2,
                LastEpochChangeReason = new[] { (int)EpochChangeReason.Deleted }
            };

            StreamMessage message = new StreamMessage {
                Content = update
            };


            resource.Setup(x => x.Id).Returns("ABC");
            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning);
            resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected   += null, EventArgs.Empty);
            resource.Setup(x => x.StopStreaming()).Raises(x => x.StreamDisconnected += null, EventArgs.Empty);
            resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture));

            // STEP 4: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, settings.Object);

            listener.Start();

            listener.IsStreaming.Should().BeTrue();

            // STEP 5: send the update
            listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message)));


            // STEP 6: check the result, note tha MKT-2 is not in-play
            connector.Verify(x => x.ProcessStreamUpdate(It.Is <Fixture>(y => y.Id == "ABC" && y.Markets.Count == 0), It.IsAny <bool>()));
        }
Exemple #8
0
        public void DisposalTest()
        {
            using (var stream = new MemoryStream())
            {
                var listener = new StreamListener(stream);

                // no errors on dispose
                stream.Dispose();
            }
        }
        public void SuspendFixtureOnDisconnectTest()
        {
            // STEP 1: prepare stub data
            Mock <IResourceFacade> resource  = new Mock <IResourceFacade>();
            Mock <IAdapterPlugin>  connector = new Mock <IAdapterPlugin>();
            Mock <IEventState>     state     = new Mock <IEventState>();
            Mock <ISettings>       settings  = new Mock <ISettings>();
            var provider = new StateManager(settings.Object, connector.Object);

            provider.SuspensionManager.RegisterAction(provider.SuspensionManager.SuspendInPlayMarketsStrategy, SuspensionReason.DISCONNECT_EVENT);

            // STEP 3: prepare the fixture data
            Fixture fixture = new Fixture {
                Id = "ABC", Sequence = 1, MatchStatus = ((int)MatchStatus.InRunning).ToString()
            };

            fixture.Tags.Add("Sport", "Football"); // add at least one tags, so the MarketsRulesManager recognize it as a full-snapshot

            var mkt = new Market("MKT-1");

            mkt.Selections.Add(new Selection {
                Id = "SELN-1", Status = SelectionStatus.Active
            });
            fixture.Markets.Add(mkt);

            mkt = new Market("MKT-2");
            mkt.AddOrUpdateTagValue("traded_in_play", "false");
            fixture.Markets.Add(mkt);

            resource.Setup(x => x.Id).Returns("ABC");
            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning);
            resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected += null, EventArgs.Empty);
            resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture));

            // STEP 4: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, settings.Object);

            listener.Start();

            listener.IsStreaming.Should().BeTrue();


            // STEP 5: send the disconnect event
            listener.ResourceOnStreamDisconnected(this, EventArgs.Empty);


            // STEP 6: check the result, note tha MKT-2 is not in-play
            connector.Verify(x => x.ProcessStreamUpdate(It.Is <Fixture>(
                                                            y => y.Id == "ABC" &&
                                                            y.Markets.Count == 1 &&
                                                            y.Markets.FirstOrDefault(z => z.Id == "MKT-1") != null &&
                                                            y.Markets.FirstOrDefault(z => z.Id == "MKT-2") == null),
                                                        It.IsAny <bool>()));
        }
Exemple #10
0
        public void DisposalStreamClosedEventTest()
        {
            var Signal = new ManualResetEvent(false);

            using (var stream = new MemoryStream())
            {
                var listener = new StreamListener(stream);
                listener.StreamClosed += (s, e) => { Signal.Set(); };
            }
            Assert.IsTrue(Signal.WaitOne(1000)); // allow stream closed to run
        }
        public void Bootstrap()
        {
            IEventStoreConnection esConnection = EventStoreConnection.Create("ConnectTo=tcp://admin:changeit@localhost:1113");

            conn = new EventStoreConnectionWrapper(esConnection);
            esConnection.Connected += (_, __) => Console.WriteLine("Connected");
            esConnection.ConnectAsync().Wait();
            IStreamNameBuilder namer = new PrefixedCamelCaseStreamNameBuilder();
            IEventSerializer   ser   = new JsonMessageSerializer();

            repo = new StreamStoreRepository(namer, conn, ser);
            OrderAggregate order = null;

            IListener listener = new StreamListener("Order", conn, namer, ser);

            _readModel = new OrderReadModel(() => listener);
        }
Exemple #12
0
        protected AccountTestsBase()
        {
            AccountId = Guid.NewGuid();
            IEventStoreConnection esConnection = EventStoreConnection.Create("ConnectTo=tcp://admin:changeit@localhost:1113");
            var conn = new EventStoreConnectionWrapper(esConnection);

            esConnection.Connected += (_, __) => { };
            esConnection.ConnectAsync().Wait();
            IStreamNameBuilder namer = new PrefixedCamelCaseStreamNameBuilder("Tests");
            IEventSerializer   ser   = new JsonMessageSerializer();

            Repo       = new StreamStoreRepository(namer, conn, ser);
            CmdHandler = new AccountCommandHandler(Repo);

            var listener = new StreamListener("AccountAggregate", conn, namer, ser);

            ReadModel = new BalanceReadModel(() => listener);
        }
Exemple #13
0
        public AccountService()
        {
            IEventStoreConnection esConnection = EventStoreConnection.Create("ConnectTo=tcp://admin:changeit@localhost:1113");
            var conn = new EventStoreConnectionWrapper(esConnection);

            esConnection.Connected += (_, __) => { };
            //Console.WriteLine("Connected");
            esConnection.ConnectAsync().Wait();
            IStreamNameBuilder namer = new PrefixedCamelCaseStreamNameBuilder();
            IEventSerializer   ser   = new JsonMessageSerializer();

            _repo       = new StreamStoreRepository(namer, conn, ser);
            _cmdHandler = new AccountCommandHandler(_repo);

            var listener = new StreamListener("AccountAggregate", conn, namer, ser);

            _readModel = new BalanceReadModel(() => listener);
        }
Exemple #14
0
        public void ReadWriteTest()
        {
            using (var stream = new MemoryStream())
            {
                var Signal = new ManualResetEvent(false);
                var bytes  = new byte[] { (byte)'t', (byte)'e', (byte)'s', (byte)'t' };

                var listener = new StreamListener(stream);
                listener.MessageAvailable += (s, e) =>
                {
                    Assert.AreEqual("test", e.Message);
                    Signal.Set();
                };

                stream.Write(bytes, 0, bytes.Length);

                Assert.IsTrue(Signal.WaitOne(1000)); // wait for event to complete
            }
        }
        private void UpdateStateFromStreamListener(StreamListener listener)
        {
            //Nothing to update
            if (listener == null)
            {
                return;
            }

            //this is accessing a dictionary object
            var fixtureOverview = GetFixtureOverview(listener.FixtureId) as FixtureOverview;

            fixtureOverview.Id    = listener.FixtureId;
            fixtureOverview.Sport = listener.Sport;
            fixtureOverview.ListenerOverview.IsDeleted   = listener.IsFixtureDeleted;
            fixtureOverview.ListenerOverview.IsStreaming = listener.IsStreaming;
            fixtureOverview.ListenerOverview.IsOver      = listener.IsFixtureEnded;
            fixtureOverview.ListenerOverview.IsErrored   = listener.IsErrored;

            fixtureOverview.TimeStamp = DateTime.UtcNow;
        }
Exemple #16
0
        public void Bootstrap()
        {
            IEventStoreConnection esConnection = EventStoreConnection.Create("ConnectTo=tcp://admin:changeit@localhost:1113");

            conn = new EventStoreConnectionWrapper(esConnection);
            esConnection.Connected += (_, __) => Console.WriteLine("Connected");
            esConnection.ConnectAsync().Wait();
            IStreamNameBuilder namer = new PrefixedCamelCaseStreamNameBuilder();
            IEventSerializer   ser   = new JsonMessageSerializer();

            repo = new StreamStoreRepository(namer, conn, ser);
            Account acct = null;

            try {
                repo.Save(new Account(_accountId));
            }
            catch (Exception e) {
            }
            IListener listener = new StreamListener("Account", conn, namer, ser);

            _readModel = new BalanceReadModel(() => listener, _accountId);
        }
        /// <summary>
        /// {@inheritDoc}
        /// If the socket is not open, calls <seealso cref="#openSocket(String, StreamListener)"/>.
        /// </summary>
        public virtual RequestHandle bindSession(BindSessionRequest request, StreamListener reqListener, long tcpConnectTimeout, long tcpReadTimeout, ListenableFuture bindFuture)
        {
            if (wsTransport == null)
            {
                // no transport: this case can happen when transport is polling
                bindRequest = new PendingBind(request, reqListener, bindFuture);
                openWS(protocol, request.TargetServer, reqListener);
            }
            else
            {
                // there is a transport, so openSocket was already called: the state is CONNECTED or CONNECTING
                WebSocket.InternalState state = wsTransport.State;
                switch (state)
                {
                case WebSocket.InternalState.CONNECTED:
                    sendBindRequest(request, reqListener, bindFuture);
                    break;

                case WebSocket.InternalState.CONNECTING:
                    // buffer the request, which will be flushed when the client state is CONNECTED
                    Debug.Assert(bindRequest == null);
                    bindRequest = new PendingBind(request, reqListener, bindFuture);
                    break;

                case WebSocket.InternalState.BROKEN:
                    // discard bind request: must be sent in HTTP
                    break;

                default:
                    // Debug.Assert(false, state);
                    sessionLog.Warn("Unexpected bind request in state " + state);
                    break;
                }
            }
            // this request handle close the stream connection
            return(new RequestHandleAnonymousInnerClass(this));
        }
Exemple #18
0
        /// <summary>
        /// Opens a WebSocket connection.
        /// </summary>
        /// <param name="serverAddress"> target address </param>
        /// <param name="streamListener"> is exposed to the following connection events: opening, closing, reading a message, catching an error.
        /// For each event the corresponding listener method is executed on the SessionThread. </param>
        /// <param name="connListener"> is only exposed to the event opening connection. The listener method is executed on the SessionThread. </param>
        private void open(string serverAddress, StreamListener streamListener, ConnectionListener connListener)
        {
            Debug.Assert(sessionListener.state == InternalState.NOT_CONNECTED);

            sessionThread.registerWebSocketShutdownHook(wsClient.ThreadShutdownHook);
            Uri uri;

            try
            {
                uri = new Uri(serverAddress + "lightstreamer");

                string cookies = CookieHelper.getCookieHeader(uri);
                log.Info("Requested cookies for uri " + uri + ": " + cookies);
                wsClient.connect(uri.ToString(), sessionListener, options.HttpExtraHeadersOnSessionCreationOnly ? null : options.HttpExtraHeaders, cookies, options.Proxy, options.RetryDelay);
                sessionListener.state = InternalState.CONNECTING;
            }
            catch (Exception e)
            {
                //  throw new System.InvalidOperationException(e.Message); // should never happen; But it happened!!!!!!
                log.Error("Unexpected error during URI validation. " + e.Message);
                sessionListener.state = InternalState.UNEXPECTED_ERROR;
                sessionListener.onBroken();
            }
        }
        public void ShouldSequenceAndEpochBeValid()
        {
            var resource = new Mock<IResourceFacade>();
            var connector = new Mock<IAdapterPlugin>();
            var eventState = new Mock<IEventState>();

            var marketFilterObjectStore = new StateManager(_settings.Object,_plugin.Object);
            int matchStatusDelta = 40;
            var fixtureDeltaJson = TestHelper.GetRawStreamMessage(matchStatus: matchStatusDelta);
            
            var fixtureSnapshot = new Fixture { Id = "y9s1fVzAoko805mzTnnTRU_CQy8", Epoch = 1, MatchStatus = "30", Sequence = 1 };

            resource.Setup(r => r.MatchStatus).Returns((MatchStatus)matchStatusDelta);
            resource.Setup(r => r.Sport).Returns("Football");
            resource.Setup(r => r.Content).Returns(new Summary());
            resource.Setup(r => r.Id).Returns("y9s1fVzAoko805mzTnnTRU_CQy8");
            resource.Setup(r => r.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixtureSnapshot));
            resource.Setup(r => r.StartStreaming()).Raises(r => r.StreamConnected += null, EventArgs.Empty);

            var listener = new StreamListener(resource.Object, connector.Object, eventState.Object, marketFilterObjectStore, _settings.Object);

            listener.Start();

            listener.ResourceOnStreamEvent(null, new StreamEventArgs(fixtureDeltaJson));
            listener.IsFixtureEnded.Should().BeFalse();
            listener.IsFixtureSetup.Should().BeFalse();

            connector.Verify(c => c.ProcessStreamUpdate(It.IsAny<Fixture>(), It.IsAny<bool>()), Times.Once());
            connector.Verify(c => c.Suspend(It.IsAny<string>()), Times.Never());
            resource.Verify(r => r.StopStreaming(), Times.Never());
            eventState.Verify(es => es.UpdateFixtureState("Football", It.IsAny<string>(), 2, resource.Object.MatchStatus, 1), Times.Once());
        }
Exemple #20
0
 public NngResult <INngStreamListener> StreamListenerCreate(string addr)
 {
     return(StreamListener.Alloc(addr));
 }
        public void ShouldReturnOnAlreadyProcessedSequence()
        {

            // STEP 1: prepare the stub data
            Mock<IResourceFacade> resource = new Mock<IResourceFacade>();
            Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>();
            Mock<IEventState> state = new Mock<IEventState>();
            
            IStateManager provider = new StateManager(_settings.Object, connector.Object);

            // Please note Sequence = 3
            Fixture fixture = new Fixture { Id = "ABC", Sequence = 3, MatchStatus = ((int)MatchStatus.InRunning).ToString() };

            // ...and Sequence = 2
            Fixture update = new Fixture
            {
                Id = "ABC",
                Sequence = 2,
                MatchStatus = ((int)MatchStatus.MatchOver).ToString()
            };

            StreamMessage message = new StreamMessage { Content = update };

            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning);
            resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected += null, EventArgs.Empty);
            resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture));
            resource.Setup(x => x.Id).Returns("ABC");

            // STEP 2: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, _settings.Object);

            listener.Start();

            listener.IsStreaming.Should().BeTrue();

            listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message)));

            connector.Verify(x => x.ProcessStreamUpdate(It.IsAny<Fixture>(), It.IsAny<bool>()), Times.Never, "Update should be processed");
        }
        public void ShouldGetSnasphotOnInvalidSequence()
        {

            // STEP 1: prepare the stub data
            Mock<IResourceFacade> resource = new Mock<IResourceFacade>();
            Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>();
            Mock<IEventState> state = new Mock<IEventState>();
            
            _settings.Setup(x => x.MarketFiltersDirectory).Returns(".");
            var provider = new StateManager(_settings.Object, connector.Object);
            
            Fixture fixture = new Fixture { Id = "ABC", Sequence = 1, MatchStatus = ((int)MatchStatus.InRunning).ToString() };

            Fixture update = new Fixture
            {
                Id = "ABC",
                Sequence = 2,
                MatchStatus = ((int)MatchStatus.Paused).ToString(),
                Epoch = 2,
                LastEpochChangeReason = new[] { (int)EpochChangeReason.MatchStatus }
            };

            StreamMessage message = new StreamMessage { Content = update };

            resource.Setup(x => x.Id).Returns("ABC");
            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning);
            resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected += null, EventArgs.Empty);
            resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture));

            // STEP 2: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, _settings.Object);

            listener.Start();

            listener.IsStreaming.Should().BeTrue();

            //Snapshot need to have sequence at least equal to the current sequence otherwise it will error on sequence validation
            fixture.Sequence = 2;
            resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture));

            // STEP 4: send the update containing a the epoch change
            listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message)));


            // STEP 5: check that ProcessStreamUpdate is called only once (for suspension)!
            connector.Verify(x => x.Suspend(It.Is<string>(y => y == "ABC")));
            connector.Verify(x => x.ProcessSnapshot(It.IsAny<Fixture>(), It.IsAny<bool>()), Times.Exactly(2));
            resource.Verify(x => x.GetSnapshot(), Times.Exactly(2), "The streamlistener was supposed to acquire a new snapshot");
        }
        public void ShouldTakeASnapshotOnUpdateIfItIsInAnErrorState()
        {

            // STEP 1: prepare the stub data
            Mock<IResourceFacade> resource = new Mock<IResourceFacade>();
            Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>();
            Mock<IEventState> state = new Mock<IEventState>();
            
            _settings.Setup(x => x.MarketFiltersDirectory).Returns(".");
            var provider = new StateManager(_settings.Object, connector.Object);

            Fixture fixture = new Fixture { Id = "ABCD", Sequence = 1, MatchStatus = ((int)MatchStatus.InRunning).ToString() };
            Fixture update = new Fixture
            {
                Id = "ABCD",
                Sequence = 2,
                MatchStatus = ((int)MatchStatus.MatchOver).ToString(),
                Epoch = 2,
                LastEpochChangeReason = new[] { (int)EpochChangeReason.MatchStatus }
            };

            StreamMessage message = new StreamMessage { Content = update };

            resource.Setup(x => x.Id).Returns("ABCD");
            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning);
            resource.Setup(r => r.StartStreaming()).Raises(r => r.StreamConnected += null, EventArgs.Empty);

            // if we return an emptry string, the StreamListener is supposed to raise an exception
            resource.Setup(x => x.GetSnapshot()).Returns(String.Empty);


            // STEP 2: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, _settings.Object);

            listener.Start();

            // STEP 3: check the result

            resource.Verify(x => x.GetSnapshot(), Times.Exactly(2), "The StreamListener was supposed to acquire 2 snasphots");
            connector.Verify(x => x.ProcessSnapshot(It.IsAny<Fixture>(), It.IsAny<bool>()), Times.Never);

            // here we are in an error state...

            // STEP 4: 
            resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture));

            listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message)));

            // STEP 5: verify the results

            connector.Verify(x => x.ProcessStreamUpdate(It.IsAny<Fixture>(), It.IsAny<bool>()), Times.Never, "The StreamListener was not supposed to process any updates");
            connector.Verify(x => x.ProcessSnapshot(It.IsAny<Fixture>(), It.IsAny<bool>()), Times.Once);
        }
        public void ShouldStartStreamingOnlyOnce()
        {

            // STEP 1: prepare the stub data
            Mock<IResourceFacade> resource = new Mock<IResourceFacade>();
            Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>();
            Mock<IEventState> state = new Mock<IEventState>();
            
            IStateManager provider = new StateManager(_settings.Object, connector.Object);

            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning);
            resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected += null, EventArgs.Empty);
            resource.Setup(r => r.Id).Returns("TestFixtureId");

            // STEP 2: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, _settings.Object);


            // STEP 3: raise 100 calls at random (short) delayes to listener.Start()
            for (int i = 0; i < 100; i++)
            {
                Task.Delay(new Random(DateTime.Now.Millisecond).Next(100)).ContinueWith(x => listener.Start());
            }

            // give a change to the thread to start and finish
            Thread.Sleep(1000);

            // STEP 4: verify that only one call to resource.StartStreaming() has been made...
            resource.Verify(x => x.StartStreaming(), Times.Once, "Streaming must start only once!");

            // ... and we are indeed streaming
            listener.IsStreaming.Should().BeTrue();
        }
        public void ShouldSequenceBeInvalid()
        {
            var resource = new Mock<IResourceFacade>();
            var connector = new Mock<IAdapterPlugin>();
            var eventState = new Mock<IEventState>();

            var marketFilterObjectStore = new StateManager(_settings.Object, _plugin.Object);

            var fixtureDeltaJson = TestHelper.GetRawStreamMessage();

            resource.Setup(x => x.GetSnapshot()).Returns(() => TestHelper.GetSnapshotJson(1, 5, 0, 30));
            resource.Setup(r => r.Content).Returns(new Summary());
            resource.Setup(r => r.StartStreaming()).Raises(r => r.StreamConnected += null, EventArgs.Empty);
            resource.Setup(r => r.Id).Returns("TestFixtureId");


            var listener = new StreamListener(resource.Object, connector.Object, eventState.Object, marketFilterObjectStore, _settings.Object);

            listener.Start();
            listener.ResourceOnStreamEvent(null, new StreamEventArgs(fixtureDeltaJson));

            listener.IsFixtureEnded.Should().BeFalse();
            listener.IsFixtureSetup.Should().BeFalse();

            connector.Verify(c => c.ProcessStreamUpdate(It.IsAny<Fixture>(), It.IsAny<bool>()), Times.Never());
            resource.Verify(r => r.StopStreaming(), Times.Never());
            resource.Verify(r => r.GetSnapshot(), Times.Once());
            eventState.Verify(es => es.UpdateFixtureState(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>(), It.IsAny<MatchStatus>(), 1), Times.Once());
        }
        public void DontSendSuspensionOnDisposingIfFixtureEndedOrDeletedTest()
        {
            // STEP 1: prepare data

            Mock<IResourceFacade> resource = new Mock<IResourceFacade>();
            Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>();
            Mock<IEventState> state = new Mock<IEventState>();
            
            var provider = new StateManager(_settings.Object, connector.Object);

            bool disposed = false;
            bool matchover = false;
            bool deleted = false;

            Action<IMarketStateCollection> disponsing_strategy = x => {disposed = true;};
            Action<IMarketStateCollection> matchover_strategy = x => { matchover = true; };
            Action<IMarketStateCollection> deleted_strategy = x => { deleted = true; };

            provider.SuspensionManager.RegisterAction(disponsing_strategy, SuspensionReason.FIXTURE_DISPOSING);
            provider.SuspensionManager.RegisterAction(deleted_strategy, SuspensionReason.FIXTURE_DELETED);
            provider.SuspensionManager.RegisterAction(matchover_strategy, SuspensionReason.SUSPENSION);
           

            Fixture fixture = new Fixture { Id = "ABCDE", Sequence = 1, MatchStatus = ((int)MatchStatus.InRunning).ToString(), Epoch = 1 };

            Market mkt = new Market { Id = "MKT" };

            fixture.Markets.Add(mkt);

            Fixture update = new Fixture
            {
                Id = "ABCDE",
                Sequence = 2,
                MatchStatus = ((int)MatchStatus.InRunning).ToString(),
                Epoch = 2,
                LastEpochChangeReason = new[] { (int)EpochChangeReason.Deleted }
            };

            StreamMessage message = new StreamMessage { Content = update };

            resource.Setup(x => x.Id).Returns("ABCDE");
            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning);
            resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected += null, EventArgs.Empty);
            resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture));

            // STEP 2: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider,_settings.Object);

            listener.Start();

            listener.IsStreaming.Should().BeTrue();

            disposed.Should().BeFalse();
            matchover.Should().BeFalse();
            deleted.Should().BeFalse();

            // STEP 3: send a delete command and check the result
            listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message)));

            //Update snapshot sequence
            fixture.Sequence = 2;
            resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture));

            disposed.Should().BeFalse();
            matchover.Should().BeFalse();
            deleted.Should().BeTrue();

            // STEP 4: reset the flags and send the dispose command
            // (no other suspension commands should be raised);
            disposed = false;
            matchover = false;
            deleted = false;

            listener.Dispose();

            deleted.Should().BeFalse();
            disposed.Should().BeFalse();
            matchover.Should().BeFalse();

            // STEP 5: do the same, but for MatchOver 
            disposed = false;
            matchover = false;
            deleted = false;

            listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, _settings.Object);

            listener.Start();

            listener.IsStreaming.Should().BeTrue();

            disposed.Should().BeFalse();
            matchover.Should().BeFalse();
            deleted.Should().BeFalse();

            update = new Fixture
            {
                Id = "ABCDE",
                Sequence = 2,
                MatchStatus = ((int)MatchStatus.MatchOver).ToString(),
                Epoch = 2,
                LastEpochChangeReason = new[] { (int)EpochChangeReason.MatchStatus }
            };

            message = new StreamMessage { Content = update };

            // STEP 3: send a delete command and check the result
            listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message)));

            disposed.Should().BeFalse();
            matchover.Should().BeTrue();
            deleted.Should().BeFalse();

            // STEP 4: reset the flags and send the dispose command
            // (no other suspension commands should be raised);
            disposed = false;
            matchover = false;
            deleted = false;

            listener.Dispose();

            deleted.Should().BeFalse();
            disposed.Should().BeFalse();
            matchover.Should().BeFalse();
        }
        public void MarkFixtureAsUnpublishedTest()
        {
            // STEP 1: prepare the stub data
            Mock<IResourceFacade> resource = new Mock<IResourceFacade>();
            Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>();
            Mock<IEventState> state = new Mock<IEventState>();
            
            _settings.Setup(x => x.DeltaRuleEnabled).Returns(true);
            var provider = new StateManager(_settings.Object, connector.Object);

            //var suspended = false;
            //Action<IMarketStateCollection> suspension_strategy = x => {suspended = true;};
            //suspension.RegisterAction(suspension_strategy, SuspensionReason.FIXTURE_DELETED);

            // Please note Sequence = 1
            Fixture fixture = new Fixture { Id = "ABCDE", Sequence = 1, MatchStatus = ((int)MatchStatus.InRunning).ToString(), Epoch = 1 };

            Market mkt = new Market { Id = "MKT" };

            fixture.Markets.Add(mkt);

            // ...and Sequence = 3
            Fixture update = new Fixture
            {
                Id = "ABCDE",
                Sequence = 2,
                MatchStatus = ((int)MatchStatus.MatchOver).ToString(), 
                Epoch = 2, 
                LastEpochChangeReason = new [] {(int)EpochChangeReason.Deleted}
            };

            StreamMessage message = new StreamMessage { Content = update };

            resource.Setup(x => x.Id).Returns("ABCDE");
            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning);
            resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected += null, EventArgs.Empty);
            resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture));

            // STEP 2: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, _settings.Object);

            listener.Start();

            listener.IsStreaming.Should().BeTrue();

            // STEP 3: let create at lea
            listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message)));

            connector.Verify(x => x.ProcessStreamUpdate(It.Is<Fixture>(y => y.Markets.All(k => k.IsSuspended)), It.IsAny<bool>()));

            update = new Fixture
            {
                Id = "ABCDE",
                Sequence = 3,
                MatchStatus = ((int)MatchStatus.MatchOver).ToString(), 
                Epoch = 2
            };

            mkt = new Market {Id = "MKT"};

            update.Markets.Add(mkt);

            update.Tags.Add("tag", "tag");

            message = new StreamMessage { Content = update };

            listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message)));

            // STEP 4: if the delta rule was executed, the market would have been removed
            fixture.Markets.FirstOrDefault(x => x.Id == "MKT").Should().NotBeNull();
        }
        public void MarkMarkedAsForcedSuspended()
        {
            Mock<IResourceFacade> resource = new Mock<IResourceFacade>();
            Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>();
            Mock<IEventState> state = new Mock<IEventState>();
            
            _settings.Setup(x => x.DeltaRuleEnabled).Returns(true);
            var provider = new StateManager(_settings.Object, connector.Object);
            
            provider.SuspensionManager.RegisterAction(provider.SuspensionManager.SuspendAllMarketsStrategy, SuspensionReason.SUSPENSION);

            //var suspended = false;
            //Action<IMarketStateCollection> suspension_strategy = x => {suspended = true;};
            //suspension.RegisterAction(suspension_strategy, SuspensionReason.FIXTURE_DELETED);

            // Please note Sequence = 1
            Fixture fixture = new Fixture { Id = "ABCDE", Sequence = 1, MatchStatus = ((int)MatchStatus.InRunning).ToString(), Epoch = 1 };

            Market mkt = new Market { Id = "MKT" };

            fixture.Markets.Add(mkt);

            // ...and Sequence = 3
            Fixture update = new Fixture
            {
                Id = "ABCDE",
                Sequence = 2,
                MatchStatus = ((int)MatchStatus.MatchOver).ToString(),
                Epoch = 2,
                LastEpochChangeReason = new[] { (int)EpochChangeReason.BaseVariables }
            };

            StreamMessage message = new StreamMessage { Content = update };

            resource.Setup(x => x.Id).Returns("ABCDE");
            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning);
            resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected += null, EventArgs.Empty);
            resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture));

            // STEP 2: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider,_settings.Object);

            listener.Start();

            listener.IsStreaming.Should().BeTrue();


            //Update snapshot sequence
            fixture.Sequence = 2;
            resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture));

            // STEP 3: let create at lea
            listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message)));

            var fixtureState = provider.CreateNewMarketRuleManager("ABCDE").CurrentState;
            fixtureState.Markets.All(x => fixtureState[x].IsForcedSuspended).Should().BeFalse();
        }
        public void ShouldNotStartStreamingPrematchIfErroredOnSnapshot()
        {
            Mock<IResourceFacade> resource = new Mock<IResourceFacade>();
            Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>();
            Mock<IEventState> state = new Mock<IEventState>();
            
            IStateManager provider = new StateManager(_settings.Object, connector.Object);

            Fixture fixture = new Fixture { Id = "ABC", Sequence = 1, MatchStatus = ((int)MatchStatus.Prematch).ToString() };

            resource.Setup(x => x.Id).Returns("ABC");
            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.Setup);

            // FIRST TEST -> if an error is raised, don't reach the error state

            // with returning an empty string we force the stream listener to raise an exception
            resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture));
            connector.Setup(x => x.ProcessSnapshot(It.IsAny<Fixture>(), It.IsAny<bool>())).Throws<Exception>();

            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, _settings.Object);

            listener.Start().Should().BeFalse();

            // make sure that the listener has not call StartStreaming
            // but has instead hit the procedure to acquire the first snapshot
            resource.Verify(x => x.StartStreaming(), Times.Never);

            // GetSnapshot should immediatelly retry when the first snapshot failed
            resource.Verify(x => x.GetSnapshot(), Times.Exactly(2));

            //if the first snapshot fails it will be marked as errored unless a second one 
            listener.IsErrored.Should().BeTrue();
            resource.Verify(x => x.StartStreaming(It.IsAny<int>(), It.IsAny<int>()), Times.Never);
        }
        public void ShouldNotProcessStreamUpdateIfSnapshotWasProcessed()
        {
            var resource = new Mock<IResourceFacade>();
            var connector = new Mock<IAdapterPlugin>();
            var eventState = new Mock<IEventState>();
            var marketFilterObjectStore = new StateManager(_settings.Object,_plugin.Object);

            var fixtureDeltaJson = TestHelper.GetRawStreamMessage();

            resource.Setup(r => r.Content).Returns(new Summary());
            resource.Setup(r => r.StartStreaming()).Raises(r => r.StreamConnected += null, EventArgs.Empty);
            resource.Setup(r => r.GetSnapshot()).Returns(() => TestHelper.GetSnapshotJson(1, 20, 0, 30));
            resource.Setup(r => r.Id).Returns("TestFixtureId");

            var listener = new StreamListener(resource.Object, connector.Object, eventState.Object, marketFilterObjectStore, _settings.Object);

            listener.Start();

            listener.ResourceOnStreamEvent(null, new StreamEventArgs(fixtureDeltaJson));

            connector.Verify(x => x.ProcessStreamUpdate(It.IsAny<Fixture>(), It.IsAny<bool>()), Times.Never());

        }
        public void ShouldTakeASnapshotOnFirstTimeWeSeeAFixture()
        {
            Mock<IResourceFacade> resource = new Mock<IResourceFacade>();
            Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>();
            Mock<IEventState> state = new Mock<IEventState>();
            
            IStateManager provider = new StateManager(_settings.Object, connector.Object);

            Fixture fixture = new Fixture { Id = "ABC", Sequence = 1, MatchStatus = ((int)MatchStatus.Setup).ToString() };

            resource.Setup(x => x.Id).Returns("ABC");
            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.Setup);

            // FIRST TEST -> if an error is raised, don't reach the error state

            // with returning an empty string we force the stream listener to raise an exception
            resource.Setup(x => x.GetSnapshot()).Returns(string.Empty);

            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, _settings.Object);

            listener.Start();

            // make sure that the listener has not call StartStreaming
            // but has instead hit the procedure to acquire the first snapshot
            resource.Verify(x => x.StartStreaming(), Times.Never);
            
            // GetSnapshot should immediatelly retry when the first snapshot failed
            resource.Verify(x => x.GetSnapshot(), Times.Exactly(2));

            //if the first snapshot fails it will be marked as errored unless a second one 
            listener.IsErrored.Should().BeTrue();

            listener.Stop();

            // SECOND TEST -> make sure we only acquire one snapshot (locking mechanism)

            resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture));

            // until the procedure of getting and processing the first snapshot is over,
            // no other snapshots should be acquired. To check this, we try to acquire 
            // a new snapshot while we are processing the previous one.
            connector.Setup(x => x.ProcessSnapshot(It.IsAny<Fixture>(), It.IsAny<bool>())).Callback(() =>
            {
                listener.UpdateResourceState(resource.Object);
                resource.Verify(x => x.StartStreaming(), Times.Never);

                // check that GetSnapshot is only called once!
                // 3 = this test + previous one
                resource.Verify(x => x.GetSnapshot(), Times.Exactly(3));
            }
            );


            listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, _settings.Object);

            listener.Start().Should().BeTrue();
            listener.IsErrored.Should().BeFalse();


            // THIRD TEST -> make sure that if we acquired the first snapshot but
            // while processing we raised an exception, then a new snapshot should
            // be taken

            // until the procedure of getting and processing the first snapshot is over,
            // no other snapshots should be acquired. To check this, we try to acquire 
            // a new snapshot while we are processing the previous one.
            connector.Setup(x => x.ProcessSnapshot(It.IsAny<Fixture>(), It.IsAny<bool>()))
                .Throws(new Exception("While processing the first snapshot, the plugin raised an exception"));

            listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, _settings.Object);

            // an exception is raised while we process the first snapshot
            listener.Start().Should().BeFalse();

            listener.IsErrored.Should().BeTrue();

            //3 calls to get snapshot + 2 retries
            resource.Verify(x => x.GetSnapshot(), Times.Exactly(3+2));

            // ...clear the callback so we don't raise any exception
            connector.Setup(x => x.ProcessSnapshot(It.IsAny<Fixture>(), It.IsAny<bool>())).Callback(() => { });

            // ... retry....and it should be fine
            listener.UpdateResourceState(resource.Object);
            
            resource.Verify(x => x.GetSnapshot(), Times.Exactly(6));

            // ... retry again but this time the stream listener should not do anything
            listener.UpdateResourceState(resource.Object);

            resource.Verify(x => x.GetSnapshot(), Times.Exactly(6));
        }
Exemple #32
0
 internal MySessionRequestListener(SessionThread sessionThread, StreamListener streamListener, ConnectionListener connListener)
 {
     this.sessionThread      = sessionThread;
     this.streamListener     = streamListener;
     this.connectionListener = connListener;
 }
        /// <summary>
        /// Opens a WebSocket connection without binding a session (see the flag isEarlyWSOpenEnabled).
        /// If a connection is already open, the connection is closed and a new connection is opened. </summary>
        /// <param name="serverAddress"> server address </param>
        /// <param name="streamListener"> stream connection listener </param>
        public virtual ListenableFuture openWS(Protocol protocol, string serverAddress, StreamListener streamListener)
        {
            if (wsTransport != null)
            {
                // close old connection
                wsTransport.close();
            }
            wsTransport = new WebSocket(sessionThread, options, serverAddress, streamListener, new MyConnectionListener(this));

            Debug.Assert(wsTransport.State.Equals(WebSocket.InternalState.CONNECTING));
            openWsFuture = new ListenableFuture();
            /* abort connection if opening takes too long */
            WebSocket        _wsTransport  = wsTransport;
            ListenableFuture _openWsFuture = openWsFuture;

            if (log.IsDebugEnabled)
            {
                log.Debug("Status timeout in " + options.CurrentConnectTimeout + " [currentConnectTimeoutWS]");
            }
            sessionThread.schedule(new Task(() =>
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("Timeout event [currentConnectTimeoutWS]");
                }
                if ((_wsTransport.State.Equals(InternalState.CONNECTING)) || (_wsTransport.State.Equals(InternalState.UNEXPECTED_ERROR)))
                {
                    sessionLog.Debug("WS connection: aborted");
                    _openWsFuture.reject();
                    _wsTransport.close();
                    options.increaseConnectTimeout();
                }
            }), options.CurrentConnectTimeout);
            return(openWsFuture);
        }
        private void UpdateStateFromStreamListener(StreamListener listener)
        {
            //Nothing to update
            if (listener == null)
                return;

            //this is accessing a dictionary object
            var fixtureOverview = GetFixtureOverview(listener.FixtureId) as FixtureOverview;

            fixtureOverview.Id = listener.FixtureId;
            fixtureOverview.Sport = listener.Sport;
            fixtureOverview.ListenerOverview.IsDeleted = listener.IsFixtureDeleted;
            fixtureOverview.ListenerOverview.IsStreaming = listener.IsStreaming;
            fixtureOverview.ListenerOverview.IsOver = listener.IsFixtureEnded;
            fixtureOverview.ListenerOverview.IsErrored = listener.IsErrored;

            fixtureOverview.TimeStamp = DateTime.UtcNow;
        }
        public void ShouldEpochBeValidAsMatchStatusChanged()
        {
            var resource = new Mock<IResourceFacade>();
            var connector = new Mock<IAdapterPlugin>();
            var eventState = new Mock<IEventState>();

            var marketFilterObjectStore = new StateManager(_settings.Object, _plugin.Object);

            resource.Setup(r => r.GetSnapshot()).Returns(TestHelper.GetSnapshotJson(3, 2, 40));
            resource.Setup(r => r.Sport).Returns("Football");
            resource.Setup(r => r.Id).Returns("TestFixtureId");

            var fixtureDeltaJson = TestHelper.GetRawStreamMessage();   // Start Time has changed

            resource.Setup(r => r.Content).Returns(new Summary());
            resource.Setup(r => r.StartStreaming()).Raises(r => r.StreamConnected += null, EventArgs.Empty);

            var listener = new StreamListener(resource.Object, connector.Object, eventState.Object, marketFilterObjectStore, _settings.Object);

            listener.Start();
            listener.ResourceOnStreamEvent(null, new StreamEventArgs(fixtureDeltaJson));

            listener.IsFixtureEnded.Should().BeFalse();
            listener.IsFixtureSetup.Should().BeFalse();
        }
        public void ShouldNotStreamOnFailedConnectingAttempt()
        {

            // STEP 1: prepare the stub data
            Mock<IResourceFacade> resource = new Mock<IResourceFacade>();
            Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>();
            Mock<IEventState> state = new Mock<IEventState>();
            
            IStateManager provider = new StateManager(_settings.Object, connector.Object);


            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning);
            resource.Setup(r => r.Id).Returns("TestFixtureId");

            // please note that we raise the disconnect event here
            resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamDisconnected += null, EventArgs.Empty);

            // STEP 2: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, _settings.Object);

            listener.Start();

            // STEP 3: check the result
            listener.IsStreaming.Should().BeFalse();
            listener.IsFixtureEnded.Should().BeFalse();

            resource.Verify(x => x.GetSnapshot(), Times.Never);

            // STEP 4: now we want to check something similar....that 
            // if StartStreaming raises an exception, then the streamlistener
            // is not on a streaing state

            resource.Setup(x => x.StartStreaming()).Throws(new Exception());

            listener.Start();

            // STEP 5: check results
            listener.IsFixtureEnded.Should().BeFalse();
            listener.IsStreaming.Should().BeFalse();

            resource.Verify(x => x.GetSnapshot(), Times.Never);
        }
        public void ShouldEpochBeInvalidAndFixtureEndedAsFixtureIsDeleted()
        {
            var resource = new Mock<IResourceFacade>();
            var connector = new Mock<IAdapterPlugin>();
            var eventState = new Mock<IEventState>();

            var marketFilterObjectStore = new StateManager(_settings.Object, _plugin.Object);

            var fixtureDeltaJson = TestHelper.GetRawStreamMessage(3, 2, matchStatus: 50, epochChangeReason: 10); // deleted

            resource.Setup(r => r.StartStreaming()).Raises(r => r.StreamConnected += null, EventArgs.Empty);
            resource.Setup(r => r.Content).Returns(new Summary());
            resource.Setup(r => r.Id).Returns("TestFixtureId");

            var listener = new StreamListener(resource.Object, connector.Object, eventState.Object, marketFilterObjectStore, _settings.Object);

            listener.Start();
            listener.ResourceOnStreamEvent(null, new StreamEventArgs(fixtureDeltaJson));
            
            listener.IsFixtureSetup.Should().BeFalse();

            connector.Verify(c => c.ProcessStreamUpdate(It.IsAny<Fixture>(), It.IsAny<bool>()), Times.Never());
            connector.Verify(c => c.ProcessSnapshot(It.IsAny<Fixture>(), true), Times.Never());
        }
        public void ShouldNotGetASnapshotIfNothingHasChanged()
        {

            // STEP 1: prepare the stub data
            Mock<IResourceFacade> resource = new Mock<IResourceFacade>();
            Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>();
            Mock<IEventState> state = new Mock<IEventState>();
            
            IStateManager provider = new StateManager(_settings.Object, connector.Object);

            FixtureState fixture_state = new FixtureState
            {
                Id = "ABC",
                MatchStatus = MatchStatus.InRunning,
                Sequence = 5
            };

            // please not Sequence = 5
            resource.Setup(x => x.Content).Returns(new Summary { Id = "ABC", Sequence = 5 });
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning);
            resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected += null, EventArgs.Empty);
            resource.Setup(x => x.Id).Returns("ABC");
            state.Setup(x => x.GetFixtureState("ABC")).Returns(fixture_state);

            // STEP 2: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, _settings.Object);

            listener.Start();

            // STEP 3: check the result

            resource.Verify(x => x.GetSnapshot(), Times.Never, "A new snapshot should not have been retrieved!");
            connector.Verify(x => x.UnSuspend(It.IsAny<Fixture>()), Times.Once);
            listener.IsStreaming.Should().BeTrue();
        }
        public void ShouldProcessSnapshopWhenReconnecting()
        {
            var resource = new Mock<IResourceFacade>();
            var connector = new Mock<IAdapterPlugin>();
            var eventState = new Mock<IEventState>();
            
            var marketFilterObjectStore = new StateManager(_settings.Object,_plugin.Object);

            var snapshot = TestHelper.GetSnapshotJson();
            resource.Setup(r => r.GetSnapshot()).Returns(snapshot);
            resource.Setup(r => r.StartStreaming()).Raises(r => r.StreamConnected += null, EventArgs.Empty);
            resource.Setup(r => r.Content).Returns(new Summary());
            resource.Setup(r => r.Id).Returns("TestFixtureId");


            var listener = new StreamListener(resource.Object, connector.Object, eventState.Object, marketFilterObjectStore, _settings.Object);

            listener.ResourceOnStreamConnected(this, EventArgs.Empty);
            listener.ResourceOnStreamDisconnected(this, EventArgs.Empty);
            listener.ResourceOnStreamConnected(this, EventArgs.Empty);

            listener.IsFixtureEnded.Should().BeFalse();
            listener.IsFixtureSetup.Should().BeFalse();

            connector.Verify(c => c.ProcessSnapshot(It.IsAny<Fixture>(), false), Times.Exactly(2));
            resource.Verify(r => r.GetSnapshot(), Times.Exactly(2));
        }
        public void ShouldNotProcessDeltaAsSequenceIsSmaller()
        {
            var fixtureSnapshot = new Fixture { Id = "TestId", Epoch = 0, MatchStatus = "30", Sequence = 11 };

            var resource = new Mock<IResourceFacade>();
            var connector = new Mock<IAdapterPlugin>();
            var eventState = new Mock<IEventState>();
            //var marketFilterObjectStore = new Mock<IObjectProvider<IUpdatableMarketStateCollection>>();
            var marketFilterObjectStore = new StateManager(_settings.Object,_plugin.Object);

            resource.Setup(r => r.StartStreaming()).Raises(r => r.StreamConnected += null, EventArgs.Empty);
            resource.Setup(r => r.StopStreaming()).Raises(r => r.StreamDisconnected += null, EventArgs.Empty);
            resource.Setup(r => r.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixtureSnapshot));
            resource.Setup(r => r.Content).Returns(new Summary());
            resource.Setup(r => r.Id).Returns("TestId");
            eventState.Setup(e => e.GetFixtureState(It.IsAny<string>())).Returns( new FixtureState {Sequence = 10});
            //marketFilterObjectStore.Setup(x => x.GetObject(It.IsAny<string>())).Returns(new MarketStateCollection());


            var listener = new StreamListener(resource.Object, connector.Object, eventState.Object, marketFilterObjectStore,_settings.Object);

            listener.Start();
            listener.Stop();

            connector.Verify(c => c.ProcessSnapshot(It.IsAny<Fixture>(), false), Times.Once());
            connector.Verify(c => c.ProcessStreamUpdate(It.IsAny<Fixture>(), It.IsAny<bool>()), Times.Never());
            resource.VerifyAll();
        }
        public void ShouldNotStreamOnSetupState()
        {

            // STEP 1: prepare the stub data
            Mock<IResourceFacade> resource = new Mock<IResourceFacade>();
            Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>();
            Mock<IEventState> state = new Mock<IEventState>();
            
            IStateManager provider = new StateManager(_settings.Object, connector.Object);

            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.Setup);
            resource.Setup(r => r.Id).Returns("TestFixtureId");

            // STEP 2: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, _settings.Object);

            listener.Start();

            // STEP 3: check that is not streaming
            listener.IsStreaming.Should().BeFalse();

            // STEP 4: we do the same but with status Ready

            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.Ready);

            listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, _settings.Object);

            listener.IsStreaming.Should().BeFalse();
        }
        public void ShouldGetASnapshotOnInvalidEpoch()
        {

            // STEP 1: prepare the stub data
            Mock<IResourceFacade> resource = new Mock<IResourceFacade>();
            Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>();
            Mock<IEventState> state = new Mock<IEventState>();
            
            var provider = new StateManager(_settings.Object, connector.Object);

            // Please note Sequence = 1
            Fixture fixture = new Fixture { Id = "ABC", Sequence = 1, MatchStatus = ((int)MatchStatus.InRunning).ToString() };

            // ...and Sequence = 3
            Fixture update = new Fixture
            {
                Id = "ABC",
                Sequence = 3,
                MatchStatus = ((int)MatchStatus.MatchOver).ToString()
            };

            StreamMessage message = new StreamMessage { Content = update };

            resource.Setup(x => x.Id).Returns("ABC");
            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning);
            resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected += null, EventArgs.Empty);
            resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture));

            // STEP 2: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider,_settings.Object);

            listener.Start();

            listener.IsStreaming.Should().BeTrue();

            // STEP 4: send the update containing a wrong sequence number
            listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message)));


            // STEP 5: check that ProcessStreamUpdate is called only once (due suspension)!
            connector.Verify(x => x.Suspend(It.Is<string>(y => y == "ABC")));
            connector.Verify(x => x.ProcessSnapshot(It.IsAny<Fixture>(), It.IsAny<bool>()), Times.Exactly(2));
            resource.Verify(x => x.GetSnapshot(), Times.Exactly(2), "The streamlistener was supposed to acquire a new snapshot");
        }
        public void ShouldStartStreamingOnMatchStatusChange()
        {

            // STEP 1: prepare the stub data
            Mock<IResourceFacade> resource = new Mock<IResourceFacade>();
            Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>();
            Mock<IEventState> state = new Mock<IEventState>();
            
            IStateManager provider = new StateManager(_settings.Object, connector.Object);

            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.Setup);
            resource.Setup(r => r.StartStreaming()).Raises(r => r.StreamConnected += null, EventArgs.Empty);
            resource.Setup(r => r.Id).Returns("TestFixtureId");

            // STEP 2: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, _settings.Object);

            listener.Start();

            // STEP 3: check that is NOT streaming
            listener.IsStreaming.Should().BeFalse();

            // STEP 4: put the resource object in "InRunningState" and notify the listener
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning);
            listener.UpdateResourceState(resource.Object);

            // STEP 5: check that the streaming is activated
            listener.IsStreaming.Should().BeTrue();

        }
        public void GenerateSuspensionOnlyOnceWhenMissedDeletion()
        {

            // STEP 1: prepare the stub data
            Mock<IResourceFacade> resource = new Mock<IResourceFacade>();
            Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>();
            Mock<IEventState> state = new Mock<IEventState>();
            
            IStateManager provider = new StateManager(_settings.Object, connector.Object);

            var firstSnapshot = TestHelper.GetFixtureFromResource("rugbydata_snapshot_2");
            var secondSnapshot = TestHelper.GetFixtureFromResource("rugbydata_snapshot_withRemovedMarkets_5");

            var update = new Fixture
            {
                Id = firstSnapshot.Id,
                //invalid sequence
                Sequence = firstSnapshot.Sequence + 2,
                MatchStatus = firstSnapshot.MatchStatus
            };


            StreamMessage message = new StreamMessage { Content = update };

            resource.Setup(x => x.Id).Returns(firstSnapshot.Id);
            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning);
            resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected += null, EventArgs.Empty);
            
            // it needs to set up as many snapshots as there will be taken
            resource.SetupSequence(x => x.GetSnapshot())
                .Returns(FixtureJsonHelper.ToJson(firstSnapshot))
                .Returns(FixtureJsonHelper.ToJson(secondSnapshot))
                .Returns(FixtureJsonHelper.ToJson(secondSnapshot));
            
            // STEP 2: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, _settings.Object);
            
            listener.Start();

            listener.IsStreaming.Should().BeTrue();

            // STEP 4: send the update containing a wrong sequence number
            listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message)));

            update.Sequence += 10;
            message.Content = update;
            
            // should cause a snapshot as we missed a sequence
            listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message)));

            connector.Verify(x => x.ProcessStreamUpdate(It.IsAny<Fixture>(), It.IsAny<bool>()), Times.Never);
            connector.Verify(x => x.Suspend(It.IsAny<string>()), Times.Exactly(2));
            connector.Verify(x => x.ProcessSnapshot(It.IsAny<Fixture>(), It.IsAny<bool>()), Times.Exactly(3));
            resource.Verify(x => x.GetSnapshot(), Times.Exactly(3), "The streamlistener is supposed to send second");

            var marketsRemoved = firstSnapshot.Markets.Where(m => !secondSnapshot.Markets.Exists(m2 => m.Id == m2.Id)).ToList();
            marketsRemoved.Exists(m => m.Id == "_3z0qZjBERuS8kLYiqhuESaDZDM").Should().BeTrue();

            connector.Verify(
                x =>
                    x.ProcessSnapshot(
                        It.Is<Fixture>(
                            f =>
                                f.Sequence == secondSnapshot.Sequence
                                    && marketsRemoved.Any(removedMarket => f.Markets.Exists(m => m.Id == removedMarket.Id && m.IsSuspended))
                                ),
                        It.IsAny<bool>()), Times.Once);
        }
        public void ShouldSuspendOnEarlyDisconnection()
        {

            // STEP 1: prepare the stub data
            Mock<IResourceFacade> resource = new Mock<IResourceFacade>();
            Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>();
            Mock<IEventState> state = new Mock<IEventState>();
            
            var provider = new StateManager(_settings.Object, connector.Object);            
            
            Fixture fixture = new Fixture { Id = "ABC", Sequence = 1, MatchStatus = ((int)MatchStatus.InRunning).ToString() };

            resource.Setup(r => r.Id).Returns("ABC");
            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning);
            resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected += null, EventArgs.Empty);
            resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture));

            // STEP 2: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider,_settings.Object);

            listener.Start();

            // just to be sure that we are streaming
            listener.IsStreaming.Should().BeTrue();

            listener.ResourceOnStreamDisconnected(this, EventArgs.Empty);

            // STEP 3: Check the resoults
            listener.IsStreaming.Should().BeFalse();
            listener.IsFixtureEnded.Should().BeFalse();

            connector.Verify(x => x.Suspend(It.Is<string>(y => y == "ABC")), "StreamListener did not suspend the fixture");
        }
        public void UnsuspendFixtureAndMarketsTest()
        {
            // STEP 1: prepare stub data
            Mock <IResourceFacade> resource  = new Mock <IResourceFacade>();
            Mock <IAdapterPlugin>  connector = new Mock <IAdapterPlugin>();
            Mock <IEventState>     state     = new Mock <IEventState>();
            Mock <ISettings>       settings  = new Mock <ISettings>();
            var provider = new StateManager(settings.Object, connector.Object);

            provider.SuspensionManager.RegisterAction(provider.SuspensionManager.SuspendInPlayMarketsStrategy, SuspensionReason.DISCONNECT_EVENT);

            // STEP 2: prepare the fixture data
            Fixture fixture = new Fixture {
                Id = "ABC", Sequence = 1, MatchStatus = ((int)MatchStatus.InRunning).ToString()
            };

            fixture.Tags.Add("Sport", "Football"); // add at least one tags, so the MarketsRulesManager recognize it as a full-snapshot

            var mkt1 = new Market {
                Id = "MKT-1"
            };

            mkt1.Selections.Add(new Selection {
                Id = "SELN", Status = SelectionStatus.Active, Tradable = true
            });
            fixture.Markets.Add(mkt1);

            var mkt = new Market("MKT-2");

            mkt.AddOrUpdateTagValue("traded_in_play", "false");
            fixture.Markets.Add(mkt);

            resource.Setup(x => x.Id).Returns("ABC");
            resource.Setup(x => x.Content).Returns(new Summary()
            {
                Sequence = 1
            });
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning);
            resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected   += null, EventArgs.Empty);
            resource.Setup(x => x.StopStreaming()).Raises(x => x.StreamDisconnected += null, EventArgs.Empty);
            resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture));

            // STEP 4: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, settings.Object);

            listener.Start();

            listener.IsStreaming.Should().BeTrue();

            connector.Verify(x => x.ProcessStreamUpdate(It.IsAny <Fixture>(), It.IsAny <bool>()), Times.Never);

            listener.Dispose();


            //Should suspend at the fixture level only
            connector.Verify(x => x.Suspend(It.Is <string>(fId => fId == "ABC")), Times.Once);


            //recreate listener
            //must have state setup otherwise it will process snapshot not unsuspend
            state.Setup(x => x.GetFixtureState(It.Is <string>(fId => fId == fixture.Id)))
            .Returns(new FixtureState()
            {
                Id          = fixture.Id,
                MatchStatus = MatchStatus.InRunning,
                Sequence    = fixture.Sequence
            });

            listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, settings.Object);
            listener.Start();

            // Unsuspend should be called on reconnect
            connector.Verify(x => x.UnSuspend(It.IsAny <Fixture>()), Times.Once);
        }
        public void ShouldNotSuspendFixtureOnProperDisconnection()
        {

            // STEP 1: prepare the stub data
            Mock<IResourceFacade> resource = new Mock<IResourceFacade>();
            Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>();
            Mock<IEventState> state = new Mock<IEventState>();
            
            _settings.Setup(x => x.MarketFiltersDirectory).Returns(".");
            var provider = new StateManager(_settings.Object, connector.Object);

            Fixture fixture = new Fixture { Id = "ABC", Sequence = 1, MatchStatus = ((int)MatchStatus.InRunning).ToString() };
            Fixture update = new Fixture
            {
                Id = "ABC",
                Sequence = 2,
                MatchStatus = ((int)MatchStatus.MatchOver).ToString(),
                Epoch = 2,
                LastEpochChangeReason = new[] { (int)EpochChangeReason.MatchStatus }
            };

            StreamMessage message = new StreamMessage { Content = update };

            resource.Setup(r => r.Id).Returns("ABC");
            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning);
            resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected += null, EventArgs.Empty);
            resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture));
            
            // STEP 2: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider,_settings.Object);

            listener.Start();

            // just to be sure that we are streaming
            listener.IsStreaming.Should().BeTrue();

            //Update snapshot sequence
            fixture.Sequence = 2;
            resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture));

            // send the update that contains the match status change
            listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message)));
            
            listener.ResourceOnStreamDisconnected(this, EventArgs.Empty);

            // STEP 3: Check the resoults
            listener.IsStreaming.Should().BeFalse();
            listener.IsFixtureEnded.Should().BeTrue();

            // suspend is called when the stream listener correctly handles the "IsFixtureEnded" case, 
            // so we need to make sure that is only called once

            connector.Verify(x => x.Suspend(It.Is<string>(y => y == "ABC")));
            
        }
Exemple #48
0
        public WebSocket(SessionThread sessionThread, InternalConnectionOptions options, string serverAddress, StreamListener streamListener, ConnectionListener connListener)
        {
            this.sessionThread = sessionThread;
            this.options       = options;
            if (TransportFactory <WebSocketProvider> .DefaultWebSocketFactory == null)
            {
                /* Note:
                 * this is a temporary hack. If the WebSocket support is not available, the transport uses a void implementation
                 * which just ignores the requests.
                 * The goal is to emulate the behavior of the old (non TLCP) Android compact client.
                 * That client doesn't support WebSocket, so when a user forces WebSocket transport
                 * the client simply ignores the requests.
                 * In the future we must address this question and work out a more user-friendly API behavior.
                 */
                this.wsClient = new DummyWebSocketClient();
            }
            else
            {
                this.wsClient = TransportFactory <WebSocketProvider> .DefaultWebSocketFactory.getInstance(sessionThread);
            }

            this.sessionListener = new MySessionRequestListener(sessionThread, streamListener, connListener);
            open(serverAddress, streamListener, connListener);

            if (log.IsDebugEnabled)
            {
                log.Debug("WebSocket transport - : " + sessionListener.state);
            }
        }
        public void ShouldTakeASnapshotOnError()
        {

            // STEP 1: prepare the stub data
            Mock<IResourceFacade> resource = new Mock<IResourceFacade>();
            Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>();
            Mock<IEventState> state = new Mock<IEventState>();
            
            var provider = new StateManager(_settings.Object, connector.Object);
            _settings.Setup(x => x.MarketFiltersDirectory).Returns(".");
            
            resource.Setup(x => x.Id).Returns("ABC");
            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning);
            resource.Setup(r => r.StartStreaming()).Raises(r => r.StreamConnected += null, EventArgs.Empty);

            // if we return an emptry string, the StreamListener is supposed to raise an exception
            resource.Setup(x => x.GetSnapshot()).Returns(String.Empty);


            // STEP 2: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, _settings.Object);

            listener.Start();

            // STEP 3: check the result

            resource.Verify(x => x.GetSnapshot(), Times.Exactly(2), "The StreamListener was supposed to acquire 2 snasphots");
            connector.Verify(x => x.ProcessSnapshot(It.IsAny<Fixture>(), It.IsAny<bool>()), Times.Never);            
        }
 public virtual RequestHandle recoverSession(RecoverSessionRequest request, StreamListener reqListener, long tcpConnectTimeout, long tcpReadTimeout)
 {
     return(transport.sendRequest(protocol, request, reqListener, options.HttpExtraHeadersOnSessionCreationOnly ? null : options.HttpExtraHeaders, options.Proxy, tcpConnectTimeout, tcpReadTimeout));
 }
        public void PrematchSuspensionShouldSuspendAsNormalWhenEnabledTest()
        {

            // STEP 1: prepare the stub data
            Mock<IResourceFacade> resource = new Mock<IResourceFacade>();
            Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>();
            Mock<IEventState> state = new Mock<IEventState>();

            _settings.Setup(x => x.MarketFiltersDirectory).Returns(".");

            //default
            _settings.Setup(x => x.DisablePrematchSuspensionOnDisconnection).Returns(false);

            //suspension should occur if time we are within 15mins 
            _settings.Setup(x => x.PreMatchSuspensionBeforeStartTimeInMins).Returns(15);
            state.Setup(x => x.GetFixtureState(It.Is<string>(id => id == "TestAbc")))
                .Returns(new FixtureState() { Id = "TestAbc", MatchStatus = MatchStatus.Prematch });

            var startTime = DateTime.UtcNow.AddMinutes(27);

            var provider = new StateManager(_settings.Object, connector.Object);

            Fixture fixture = new Fixture { Id = "TestAbc", Sequence = 1, MatchStatus = ((int)MatchStatus.Prematch).ToString(), Epoch = 1, StartTime = startTime };
            Fixture update = new Fixture
            {
                Id = "TestAbc",
                Sequence = 2,
                MatchStatus = ((int)MatchStatus.Prematch).ToString(),
                Epoch = 1,
                LastEpochChangeReason = new[] { (int)EpochChangeReason.MatchStatus },
                StartTime = startTime

            };

            StreamMessage message = new StreamMessage { Content = update };

            resource.Setup(r => r.Id).Returns("TestAbc");
            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.Prematch);
            resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected += null, EventArgs.Empty);
            resource.Setup(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture));

            // STEP 2: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, _settings.Object);

            listener.Start();

            // just to be sure that we are streaming
            listener.IsStreaming.Should().BeTrue();
            
            listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message)));

            listener.ResourceOnStreamDisconnected(this, EventArgs.Empty);

            // STEP 3: Check the disconnection
            listener.IsStreaming.Should().BeFalse();

            // suspend is called when the stream listener processes snapshots
            // so we need to make sure that is only called once
            connector.Verify(x => x.Suspend(It.Is<string>(y => y == "TestAbc")), Times.Once);
        }
        public void StreamListenerEvents()
        {
            // STEP 1: prepare the stub data
            Mock<IResourceFacade> resource = new Mock<IResourceFacade>();
            Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>();
            Mock<IEventState> state = new Mock<IEventState>();

            _settings.Setup(x => x.MarketFiltersDirectory).Returns(".");

            var provider = new StateManager(_settings.Object, connector.Object);

            var suspensionManager = new SuspensionManager(provider, connector.Object);

            var fixtureSnapshot = new Fixture { Id = "ABC", Epoch = 0, MatchStatus = "30", Sequence = 1 };
            var settledSnapshot = new Fixture { Id = "ABC", Epoch = 3, MatchStatus = "50", Sequence = 5 };

            resource.Setup(x => x.Id).Returns("ABC");
            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning);
            resource.Setup(r => r.StartStreaming()).Raises(r => r.StreamConnected += null, EventArgs.Empty);
            resource.Setup(r => r.StopStreaming()).Raises(r => r.StreamDisconnected += (e, o) => { }, EventArgs.Empty);

            //sequence of 3 snapshots middle one should raise an exception
            resource.SetupSequence(r => r.GetSnapshot())
                .Returns(FixtureJsonHelper.ToJson(fixtureSnapshot))
                .Returns(String.Empty)
                .Returns(FixtureJsonHelper.ToJson(settledSnapshot));


            // STEP 2: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider, _settings.Object);

            listener.MonitorEvents();

            listener.Start();

            listener.ShouldRaise("OnConnected");
            listener.ShouldRaise("OnBeginSnapshotProcessing");
            listener.ShouldRaise("OnFinishedSnapshotProcessing");

            //stream event
            var update = new Fixture
            {
                Id = "ABC",
                Sequence = 2,
                MatchStatus = ((int)MatchStatus.MatchOver).ToString(),
                Epoch = 2,
                LastEpochChangeReason = new[] { (int)EpochChangeReason.MatchStatus }
            };

            var message = new StreamMessage { Content = update };
            listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message)));
            listener.ShouldRaise("OnBeginStreamUpdateProcessing");
            listener.ShouldRaise("OnFinishedStreamUpdateProcessing");

            //as a result of match status change it will get a second snapshot which is String.Empty
            listener.ShouldRaise("OnError")
                .WithArgs<StreamListenerEventArgs>(e => e.Exception != null);

            listener.ShouldRaise("OnSuspend");

            //when recovered the IsErrored should clear
            listener.IsErrored.Should().BeFalse();
            listener.ShouldRaise("OnFlagsChanged")
                .WithArgs<StreamListenerEventArgs>(e => ((StreamListener)e.Listener).IsErrored == false);

            //simulate stream disconnection 
            listener.ResourceOnStreamDisconnected(null, null);

            listener.ShouldRaise("OnDisconnected");

            listener.Stop();

            listener.ShouldRaise("OnStop");

            resource.Verify(x => x.GetSnapshot(), Times.Exactly(3), "The StreamListener was supposed to acquire 3 snasphots");
            connector.Verify(x => x.ProcessSnapshot(It.IsAny<Fixture>(), It.IsAny<bool>()), Times.Exactly(2));
        }
        public void ShouldNotSetIsFixtureEndedIfThereWasAnErrorProcessingSnapshot()
        {
            Mock<IResourceFacade> resource = new Mock<IResourceFacade>();
            Mock<IAdapterPlugin> connector = new Mock<IAdapterPlugin>();
            Mock<IEventState> state = new Mock<IEventState>();
            Mock<ISettings> settings = new Mock<ISettings>();
            settings.Setup(x => x.MarketFiltersDirectory).Returns(".");
            var provider = new StateManager(settings.Object,connector.Object);

            var suspensionManager = new SuspensionManager(provider, connector.Object);

            Fixture fixture = new Fixture { Id = "ABC", Sequence = 1, MatchStatus = ((int)MatchStatus.InRunning).ToString() };

            Fixture update = new Fixture
            {
                Id = "ABC",
                Sequence = 2,
                MatchStatus = ((int)MatchStatus.MatchOver).ToString(),
                Epoch = 2,
                LastEpochChangeReason = new[] { (int)EpochChangeReason.MatchStatus }
            };

            StreamMessage message = new StreamMessage { Content = update };

            resource.Setup(x => x.Id).Returns("ABC");
            resource.Setup(x => x.Content).Returns(new Summary());
            resource.Setup(x => x.MatchStatus).Returns(MatchStatus.InRunning);
            resource.Setup(x => x.StartStreaming()).Raises(x => x.StreamConnected += null, EventArgs.Empty);
            resource.SetupSequence(x => x.GetSnapshot()).Returns(FixtureJsonHelper.ToJson(fixture)).Returns(null);

            // STEP 2: start the listener
            StreamListener listener = new StreamListener(resource.Object, connector.Object, state.Object, provider,_settings.Object);

            listener.Start();

            listener.IsStreaming.Should().BeTrue();

            // STEP 4: send the update containing a wrong sequence number
            listener.ResourceOnStreamEvent(this, new StreamEventArgs(JsonConvert.SerializeObject(message)));


            // STEP 5: check that ProcessSnapshot is called only twice (first snapshot and when the fixture is ended, we get another one)!
            connector.Verify(x => x.Suspend(It.Is<string>(y => y == "ABC")));
            connector.Verify(x => x.ProcessSnapshot(It.IsAny<Fixture>(), It.IsAny<bool>()), Times.Once());
            resource.Verify(x => x.GetSnapshot(), Times.AtLeast(2), "The StreamListener was supposed to acquire a new snapshot");

            listener.IsFixtureEnded.Should().BeFalse();
            listener.IsErrored.Should().BeTrue();
        }