Example #1
0
        protected override UntypedChannel Visitor(BroadcastChannel channel)
        {
            var results = new List<UntypedChannel>();
            bool changed = false;

            foreach (UntypedChannel subscriber in channel.Listeners)
            {
                UntypedChannel newSubscriber = Visit(subscriber);

                if (newSubscriber == null || newSubscriber != subscriber)
                {
                    changed = true;
                    if (newSubscriber == null)
                        continue;
                }

                results.Add(newSubscriber);
            }

            if (!_added)
            {
                _added = true;
                results.Add(_newChannel);
                changed = true;
            }

            if (changed)
                return new BroadcastChannel(results);

            return channel;
        }
        private async Task OpenChannels()
        {
            InputChannel = new InputChannel(
                await StartChannelAsync(ServiceType.SystemInput));

            /*
             *  InputTvRemoteChannel fails when connecting non-authenticated
             *  (Either a bug or feature from Microsoft!)
             *  Simply disabling it for now - it serves no use anyways atm
             * InputTvRemoteChannel = new InputTVRemoteChannel(
             *  await StartChannelAsync(ServiceType.SystemInputTVRemote));
             */
            MediaChannel = new MediaChannel(
                await StartChannelAsync(ServiceType.SystemMedia));
            TextChannel = new TextChannel(
                await StartChannelAsync(ServiceType.SystemText));
            BroadcastChannel = new BroadcastChannel(
                await StartChannelAsync(ServiceType.SystemBroadcast));
            if (this.connectedAuthenticated)
            {
                InputTvRemoteChannel = new InputTVRemoteChannel(
                    await StartChannelAsync(ServiceType.SystemInputTVRemote)
                    );
            }
        }
Example #3
0
        protected override UntypedChannel Visitor(BroadcastChannel channel)
        {
            var  results = new List <UntypedChannel>();
            bool changed = false;

            foreach (UntypedChannel subscriber in channel.Listeners)
            {
                UntypedChannel newSubscriber = Visit(subscriber);

                if (newSubscriber == null || newSubscriber != subscriber)
                {
                    changed = true;
                    if (newSubscriber == null)
                    {
                        continue;
                    }
                }

                results.Add(newSubscriber);
            }

            if (!_added)
            {
                _added = true;
                results.Add(_newChannel);
                changed = true;
            }

            if (changed)
            {
                return(new BroadcastChannel(results));
            }

            return(channel);
        }
Example #4
0
        /// <summary>
        /// Starts or restarts the handler listening for the [ProxyUpdateMessage] messages.
        /// </summary>
        private static void StartNotifyHandler()
        {
            lock (syncLock)
            {
                // Use the latest settings to reconnect to the [proxy-notify] channel.

                if (proxyNotifyChannel != null)
                {
                    proxyNotifyChannel.Dispose();
                }

                proxyNotifyChannel = hive.HiveMQ.Internal.GetProxyNotifyChannel(useBootstrap: true).Open();

                // Register a handler for [ProxyUpdateMessage] messages that determines
                // whether the message is meant for this service instance and handle it.

                proxyNotifyChannel.ConsumeAsync <ProxyUpdateMessage>(
                    async message =>
                {
                    // We cannot process updates in parallel so we'll use an
                    // AsyncMutex to prevent this.

                    using (await asyncLock.AcquireAsync())
                    {
                        var forThisInstance = false;

                        if (isPublic)
                        {
                            forThisInstance = message.PublicProxy && !isBridge ||
                                              message.PublicBridge && isBridge;
                        }
                        else
                        {
                            forThisInstance = message.PrivateProxy && !isBridge ||
                                              message.PrivateBridge && isBridge;
                        }

                        if (!forThisInstance)
                        {
                            log.LogInfo(() => $"HAPROXY-SHIM: Received but ignorning: {message}");
                            return;
                        }

                        log.LogInfo(() => $"HAPROXY-SHIM: Received: {message}");

                        var jitter = NeonHelper.RandTimespan(HiveConst.MaxJitter);

                        log.LogDebug(() => $"HAPROXY-SHIM: Jitter delay [{jitter}].");
                        await Task.Delay(jitter);

                        await ConfigureHAProxy();
                    }
                });
            }
        }
Example #5
0
        protected override UntypedChannel Visitor(BroadcastChannel channel)
        {
            _current = GetVertex(channel.GetHashCode(), () => "Router", typeof(BroadcastChannel), typeof(object));

            if (_stack.Count > 0)
            {
                _edges.Add(new Edge(_stack.Peek(), _current, _current.TargetType.Name));
            }

            return(WithVertex(() => base.Visitor(channel)));
        }
Example #6
0
		public void Should_return_false_if_there_are_no_subscribers()
		{
			Fiber fiber = new SynchronousFiber();

			Channel<UserUpdate> channel = new BroadcastChannel<UserUpdate>(new Channel<UserUpdate>[] {});

			var update = new UserUpdate();

			channel.Send(update);

			// exception here? or just ignore
		}
Example #7
0
        public void Should_return_false_if_there_are_no_subscribers()
        {
            Fiber fiber = new SynchronousFiber();

            Channel <UserUpdate> channel = new BroadcastChannel <UserUpdate>(new Channel <UserUpdate>[] {});

            var update = new UserUpdate();

            channel.Send(update);

            // exception here? or just ignore
        }
 private async Task OpenChannels()
 {
     InputChannel = new InputChannel(
         await StartChannelAsync(ServiceType.SystemInput));
     MediaChannel = new MediaChannel(
         await StartChannelAsync(ServiceType.SystemMedia));
     TextChannel = new TextChannel(
         await StartChannelAsync(ServiceType.SystemText));
     BroadcastChannel = new BroadcastChannel(
         await StartChannelAsync(ServiceType.SystemBroadcast));
     InputTvRemoteChannel = new InputTVRemoteChannel(
         await StartChannelAsync(ServiceType.SystemInputTVRemote));
 }
        public void Dispose()
        {
            // TODO: Close opened channels?
            // Assuming so for the time being, but don't know how to send stop messages yet
            InputChannel.Dispose();
            // InputTvRemoteChannel.Dispose();

            TextChannel.Dispose();
            MediaChannel.Dispose();
            BroadcastChannel.Dispose();

            _sessionMessageTransport.Dispose();
            _messageTransport.Dispose();
        }
Example #10
0
        protected override object ExecuteCommand(object message)
        {
            var gs = (TimeGetSet)message;

            if (gs.IsGet)
            {
                BroadcastChannel.TimeGet(gs.IsExecute, gs.DateTime, Client.UniqueKey);
            }
            else
            {
                BroadcastChannel.TimeSet(gs.IsExecute, gs.DateTime, Client.UniqueKey);
            }
            return(null);
        }
        private SmartGlassClient(
            Device device,
            ConnectResponseMessage connectResponse,
            CryptoContext cryptoContext)
        {
            _messageTransport        = new MessageTransport(device.Address.ToString(), cryptoContext);
            _sessionMessageTransport = new SessionMessageTransport(
                _messageTransport,
                new SessionInfo()
            {
                ParticipantId = connectResponse.ParticipantId
            });

            _sessionMessageTransport.MessageReceived += (s, e) =>
            {
                var consoleStatusMessage = e.Message as ConsoleStatusMessage;
                if (consoleStatusMessage != null)
                {
                    CurrentConsoleStatus = new ConsoleStatus()
                    {
                        Configuration = consoleStatusMessage.Configuration,
                        ActiveTitles  = consoleStatusMessage.ActiveTitles
                    };

                    ConsoleStatusChanged?.Invoke(this, new ConsoleStatusChangedEventArgs(
                                                     CurrentConsoleStatus
                                                     ));
                }
            };

            _sessionMessageTransport.SendAsync(new LocalJoinMessage());

            _inputChannel = new DisposableAsyncLazy <InputChannel>(async() =>
            {
                return(new InputChannel(await StartChannelAsync(ServiceType.SystemInput)));
            });

            _mediaChannel = new DisposableAsyncLazy <MediaChannel>(async() =>
            {
                return(new MediaChannel(await StartChannelAsync(ServiceType.SystemMedia)));
            });

            _broadcastChannel = new DisposableAsyncLazy <BroadcastChannel>(async() =>
            {
                var broadcastChannel = new BroadcastChannel(await StartChannelAsync(ServiceType.SystemBroadcast));
                await broadcastChannel.WaitForEnabledAsync();
                return(broadcastChannel);
            });
        }
Example #12
0
        public void Should_filter_out_unwanted_messages()
        {
            var update = new UserUpdate {LastActivity = DateTime.Now - 5.Minutes()};

            Fiber fiber = new SynchronousFiber();

            var future = new FutureChannel<UserUpdate>();

            var filter = new FilterChannel<UserUpdate>(fiber, future, x => x.LastActivity > DateTime.Now);

            Channel<UserUpdate> channel = new BroadcastChannel<UserUpdate>(new[] {filter});

            channel.Send(update);

            Assert.IsFalse(future.WaitUntilCompleted(1.Seconds()));
        }
        protected override Channel <T> Visitor <T>(BroadcastChannel <T> channel)
        {
            bool changed;

            Channel <T>[] subscribers = VisitSubscribers(channel.Listeners, out changed).ToArray();
            if (subscribers.Length == 1)
            {
                return(subscribers[0]);
            }

            if (changed)
            {
                return(new BroadcastChannel <T>(subscribers));
            }

            return(channel);
        }
Example #14
0
        public void Should_filter_out_unwanted_messages()
        {
            var update = new UserUpdate {
                LastActivity = DateTime.Now - 5.Minutes()
            };

            Fiber fiber = new SynchronousFiber();

            var future = new FutureChannel <UserUpdate>();

            var filter = new FilterChannel <UserUpdate>(fiber, future, x => x.LastActivity > DateTime.Now);

            Channel <UserUpdate> channel = new BroadcastChannel <UserUpdate>(new[] { filter });

            channel.Send(update);

            Assert.IsFalse(future.WaitUntilCompleted(1.Seconds()));
        }
Example #15
0
        /// <summary>
        /// Manages the Varnish initial configuration from Consul and Vault settings and
        /// then listens for <see cref="ProxyUpdateMessage"/> messages on the <see cref="HiveMQChannels.ProxyNotify"/>
        /// broadcast by <b>neon-proxy-manager</b> signalling that the configuration has been
        /// updated.
        /// </summary>
        /// <remarks>
        /// <para>
        /// This method will terminate the service with an error if the configuration could
        /// not be retrieved or applied for the first attempt since this very likely indicates
        /// a larger problem with the hive (e.g. Consul is down).
        /// </para>
        /// <para>
        /// If Varnish was configured successfully on the first attempt, subsequent failures
        /// will be logged as warnings but the service will continue running with the out-of-date
        /// configuration to provide some resilience for running hive services.
        /// </para>
        /// </remarks>
        /// <returns>The tracking <see cref="Task"/>.</returns>
        private async static Task VarnishShim()
        {
            // This call ensures that Varnish is started immediately.

            await ConfigureVarnish();

            // Register a handler for [ProxyUpdateMessage] messages that determines
            // whether the message is meant for this service instance and handle it.

            StartNotifyHandler();

            // Register an event handler that will be fired when the HiveMQ bootstrap
            // settings change.  This will restart the [ProxyUpdateMessage] listener
            // using the new settings.

            hive.HiveMQ.Internal.HiveMQBootstrapChanged +=
                (s, a) =>
            {
                StartNotifyHandler();
            };

            // Spin quietly while waiting for a cancellation indicating that
            // the service is stopping.

            var task = new AsyncPeriodicTask(
                TimeSpan.FromMinutes(5),
                onTaskAsync: async() => await Task.FromResult(false),
                onTerminateAsync:
                async() =>
            {
                log.LogInfo(() => "VARNISH-SHIM: Terminating");

                if (proxyNotifyChannel != null)
                {
                    proxyNotifyChannel.Dispose();
                    proxyNotifyChannel = null;
                }

                await Task.CompletedTask;
            },
                cancellationTokenSource: terminator.CancellationTokenSource);

            await task.Run();
        }
Example #16
0
        public void Should_schedule_events()
        {
            var update = new UserUpdate {LastActivity = DateTime.Now - 5.Minutes()};

            Fiber fiber = new SynchronousFiber();

            var future = new FutureChannel<UserUpdate>();

            Channel<UserUpdate> channel = new BroadcastChannel<UserUpdate>(new Channel<UserUpdate>[] {future});

            var scheduler = new TimerScheduler(fiber);

            scheduler.Schedule(1000, fiber, () => channel.Send(update));

            Thread.Sleep(500);

            Assert.IsFalse(future.WaitUntilCompleted(0.Seconds()));

            Assert.IsTrue(future.WaitUntilCompleted(1.Seconds()));
        }
Example #17
0
        public void Should_add_a_consumer_that_is_assignable_to_the_type()
        {
            var firstFuture = new Future<TestMessage>();
            var secondFuture = new Future<ITestMessage>();

            var first = new ConsumerChannel<TestMessage>(_fiber, firstFuture.Complete);
            var subs = new BroadcastChannel<TestMessage>(new[] {first});
            var adapter = new ChannelAdapter<TestMessage>(subs);

            var second = new ConsumerChannel<ITestMessage>(_fiber, secondFuture.Complete);

            using (var scope = adapter.Connect(x => x.AddChannel(second)))
            {
                new TraceChannelVisitor().Visit(adapter);

                adapter.Send(new TestMessage());
            }

            firstFuture.IsCompleted.ShouldBeTrue();
            secondFuture.IsCompleted.ShouldBeTrue();
        }
        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    // TODO: Close opened channels?
                    // Assuming so for the time being, but don't know how to send stop messages yet
                    InputChannel.Dispose();
                    // InputTvRemoteChannel.Dispose();

                    TextChannel.Dispose();
                    MediaChannel.Dispose();
                    BroadcastChannel.Dispose();

                    _sessionMessageTransport.Dispose();
                    _messageTransport.Dispose();
                }
                _disposed = true;
            }
        }
Example #19
0
        public void Should_add_a_consumer_to_an_existing_adapter_chain()
        {
            var firstFuture  = new Future <TestMessage>();
            var secondFuture = new Future <TestMessage>();

            var first   = new ConsumerChannel <TestMessage>(_fiber, firstFuture.Complete);
            var subs    = new BroadcastChannel <TestMessage>(new[] { first });
            var adapter = new ChannelAdapter <TestMessage>(subs);

            var second = new ConsumerChannel <TestMessage>(_fiber, secondFuture.Complete);

            using (var scope = adapter.Connect(x => x.AddChannel(second)))
            {
                new TraceChannelVisitor().Visit(adapter);

                adapter.Send(new TestMessage());
            }

            firstFuture.IsCompleted.ShouldBeTrue();
            secondFuture.IsCompleted.ShouldBeTrue();
        }
    private void CheckScheduleForBroadcastSwitchover(BroadcastChannel channel)
    {
        Broadcast cuedShow           = null;
        Broadcast currentShow        = null;
        bool      foundScheduledShow = false;
        bool      foundCurrentShow   = false;

        foreach (Broadcast show in channel.schedule)
        {
            if (Time.time > show.startTime && !show.isPlaying && !show.finishedPlaying)
            {
                cuedShow           = show;
                foundScheduledShow = true;
            }
            if (show.isPlaying)
            {
                currentShow      = show;
                foundCurrentShow = true;
            }
        }

        if (foundScheduledShow)
        {
            if (foundCurrentShow)
            {
                channel.PlayBroadcast(cuedShow);
                cuedShow.isPlaying = true;
                channel.ResetBroadcast(currentShow);
                currentShow.isPlaying       = false;
                currentShow.finishedPlaying = true;
            }
            else
            {
                if (Time.time > currentShow.startTime + currentShow.duration)
                {
                    channel.ShowOffAirScreens();
                }
            }
        }
    }
Example #21
0
        public void Should_schedule_events()
        {
            var update = new UserUpdate {
                LastActivity = DateTime.Now - 5.Minutes()
            };

            Fiber fiber = new SynchronousFiber();

            var future = new FutureChannel <UserUpdate>();

            Channel <UserUpdate> channel = new BroadcastChannel <UserUpdate>(new Channel <UserUpdate>[] { future });

            var scheduler = new TimerScheduler(fiber);

            scheduler.Schedule(1000, fiber, () => channel.Send(update));

            Thread.Sleep(500);

            Assert.IsFalse(future.WaitUntilCompleted(0.Seconds()));

            Assert.IsTrue(future.WaitUntilCompleted(1.Seconds()));
        }
Example #22
0
        protected override UntypedChannel Visitor(ChannelAdapter channel)
        {
            UntypedChannel original = channel.Output;

            UntypedChannel replacement = Visit(original);

            if (!_added)
            {
                if (replacement.GetType() == typeof(ShuntChannel))
                {
                    replacement = new BroadcastChannel(new[] { _newChannel });
                    _added      = true;
                }
            }

            if (original != replacement)
            {
                channel.ChangeOutputChannel(original, replacement);
            }

            return(channel);
        }
        protected override UntypedChannel Visitor(BroadcastChannel channel)
        {
            var  results = new List <UntypedChannel>();
            bool changed = false;

            foreach (UntypedChannel subscriber in channel.Listeners)
            {
                UntypedChannel newSubscriber = Visit(subscriber);

                if (_channels.Contains(newSubscriber))
                {
                    _channels.Remove(newSubscriber);
                    newSubscriber = null;
                }

                if (newSubscriber == null || newSubscriber != subscriber)
                {
                    changed = true;
                    if (newSubscriber == null)
                    {
                        continue;
                    }
                }

                results.Add(newSubscriber);
            }

            if (results.Count == 0)
            {
                return(null);
            }

            if (changed)
            {
                return(new BroadcastChannel(results));
            }

            return(channel);
        }
Example #24
0
        protected override UntypedChannel Visitor(ChannelAdapter channel)
        {
            bool wasAdded = _added;

            channel.ChangeOutputChannel(original =>
            {
                _added = wasAdded;

                UntypedChannel replacement = Visit(original);

                if (!_added)
                {
                    if (replacement.GetType() == typeof(ShuntChannel))
                    {
                        replacement = new BroadcastChannel(new[] { _newChannel });
                        _added      = true;
                    }
                }

                return(replacement);
            });

            return(channel);
        }
Example #25
0
        protected override UntypedChannel Visitor(BroadcastChannel channel)
        {
            channel.Listeners.OrderBy(x => x.GetType().FullName).Each(subscriber => { Visit(subscriber); });

            return(channel);
        }
Example #26
0
 /// <summary>
 /// Parameterized constructor
 /// </summary>
 /// <param name="channel">The specified channel to use</param>
 public broadcast_channel_indicator(BroadcastChannel channel)
     : base(TlvTag)
 {
     Value = (byte)channel;
 }
Example #27
0
 protected override object ExecuteCommand(object message)
 {
     BroadcastChannel.BroadcastMessage(message == null ? null : message.ToString(), Client.UniqueKey);
     return(null);
 }
Example #28
0
        protected virtual UntypedChannel Visitor(BroadcastChannel channel)
        {
            channel.Listeners.Each(subscriber => { Visit(subscriber); });

            return(channel);
        }
Example #29
0
        protected virtual Channel <T> Visitor <T>(BroadcastChannel <T> channel)
        {
            channel.Listeners.Each(subscriber => { Visit(subscriber); });

            return(channel);
        }
Example #30
0
        /// <summary>
        /// Application entry point.
        /// </summary>
        /// <param name="args">Command line arguments.</param>
        public static async Task Main(string[] args)
        {
            LogManager.Default.SetLogLevel(Environment.GetEnvironmentVariable("LOG_LEVEL"));
            log = LogManager.Default.GetLogger(typeof(Program));
            log.LogInfo(() => $"Starting [{serviceName}]");
            log.LogInfo(() => $"LOG_LEVEL={LogManager.Default.LogLevel.ToString().ToUpper()}");

            // Create process terminator to handle process termination signals.

            terminator = new ProcessTerminator(log);

            terminator.AddHandler(
                () =>
            {
                // Cancel any operations in progress.

                exit = true;

                terminator.CancellationTokenSource.Cancel();

                // This gracefully closes the [proxyNotifyChannel] so HiveMQ will
                // promptly remove the associated queue.

                if (proxyNotifyChannel != null)
                {
                    proxyNotifyChannel.Dispose();
                    proxyNotifyChannel = null;
                }

                try
                {
                    NeonHelper.WaitFor(() => !processingConfigs, terminator.Timeout);
                    log.LogInfo(() => "Tasks stopped gracefully.");
                }
                catch (TimeoutException)
                {
                    log.LogWarn(() => $"Tasks did not stop within [{terminator.Timeout}].");
                }
            });

            // Establish the hive connections.

            if (NeonHelper.IsDevWorkstation)
            {
                var vaultCredentialsSecret = "neon-proxy-manager-credentials";

                Environment.SetEnvironmentVariable("VAULT_CREDENTIALS", vaultCredentialsSecret);

                hive = HiveHelper.OpenHiveRemote(new DebugSecrets().VaultAppRole(vaultCredentialsSecret, "neon-proxy-manager"));
            }
            else
            {
                hive = HiveHelper.OpenHive();
            }

            // [neon-proxy-manager] requires access to the [IHostingManager] implementation for the
            // current environment, so we'll need to initialize the hosting loader.

            HostingLoader.Initialize();

            try
            {
                // Log into Vault using a Docker secret.

                var vaultCredentialsSecret = Environment.GetEnvironmentVariable("VAULT_CREDENTIALS");

                if (string.IsNullOrEmpty(vaultCredentialsSecret))
                {
                    log.LogCritical("[VAULT_CREDENTIALS] environment variable does not exist.");
                    Program.Exit(1, immediate: true);
                }

                var vaultSecret = HiveHelper.GetSecret(vaultCredentialsSecret);

                if (string.IsNullOrEmpty(vaultSecret))
                {
                    log.LogCritical($"Cannot read Docker secret [{vaultCredentialsSecret}].");
                    Program.Exit(1, immediate: true);
                }

                var vaultCredentials = HiveCredentials.ParseJson(vaultSecret);

                if (vaultCredentials == null)
                {
                    log.LogCritical($"Cannot parse Docker secret [{vaultCredentialsSecret}].");
                    Program.Exit(1, immediate: true);
                }

                // Open the hive data services and then start the main service task.

                log.LogInfo(() => $"Connecting: Vault");

                using (vault = HiveHelper.OpenVault(vaultCredentials))
                {
                    log.LogInfo(() => $"Connecting: Consul");

                    using (consul = HiveHelper.OpenConsul())
                    {
                        log.LogInfo(() => $"Connecting: Docker");

                        using (docker = HiveHelper.OpenDocker())
                        {
                            log.LogInfo(() => $"Connecting: {HiveMQChannels.ProxyNotify} channel");

                            // NOTE:
                            //
                            // We're passing [useBootstrap=true] here so that the HiveMQ client will
                            // connect directly to the HiveMQ cluster nodes as opposed to routing
                            // traffic through the private traffic manager.  This is necessary because
                            // the load balancers rely on HiveMQ to broadcast update notifications.
                            //
                            // One consequence of this is that this service will need to be restarted
                            // whenever HiveMQ instances are relocated to different hive hosts.
                            // We're going to monitor for changes to the HiveMQ bootstrap settings
                            // and gracefully terminate the process when this happens.  We're then
                            // depending on Docker to restart the process so we'll be able to pick
                            // up the change.

                            hive.HiveMQ.Internal.HiveMQBootstrapChanged +=
                                (s, a) =>
                            {
                                log.LogInfo("HiveMQ bootstrap settings change detected.  Terminating service with [exitcode=-1] expecting that Docker will restart it.");

                                // Use ExitCode=-1 so that we'll restart even if the service/container
                                // was not configured with [restart=always].

                                terminator.Exit(-1);
                            };

                            using (proxyNotifyChannel = hive.HiveMQ.Internal.GetProxyNotifyChannel(useBootstrap: true).Open())
                            {
                                // Read the service settings, initializing their default values
                                // if they don't already exist.

                                if (!await consul.KV.Exists(certWarnDaysKey))
                                {
                                    log.LogInfo($"Persisting setting [{certWarnDaysKey}=30.0]");
                                    await consul.KV.PutDouble(certWarnDaysKey, 30.0);
                                }

                                if (!await consul.KV.Exists(cacheRemoveSecondsKey))
                                {
                                    log.LogInfo($"Persisting setting [{cacheRemoveSecondsKey}=300.0]");
                                    await consul.KV.PutDouble(cacheRemoveSecondsKey, 300.0);
                                }

                                if (!await consul.KV.Exists(failsafeSecondsKey))
                                {
                                    log.LogInfo($"Persisting setting [{failsafeSecondsKey}=120.0]");
                                    await consul.KV.PutDouble(failsafeSecondsKey, 120);
                                }

                                certWarnTime     = TimeSpan.FromDays(await consul.KV.GetDouble(certWarnDaysKey));
                                cacheRemoveDelay = TimeSpan.FromDays(await consul.KV.GetDouble(cacheRemoveSecondsKey));
                                failsafeInterval = TimeSpan.FromSeconds(await consul.KV.GetDouble(failsafeSecondsKey));

                                log.LogInfo(() => $"Using setting [{certWarnDaysKey}={certWarnTime.TotalSeconds}]");
                                log.LogInfo(() => $"Using setting [{cacheRemoveSecondsKey}={cacheRemoveDelay.TotalSeconds}]");
                                log.LogInfo(() => $"Using setting [{failsafeSecondsKey}={failsafeInterval.TotalSeconds}]");

                                // Run the service tasks.

                                var tasks = new List <Task>();

                                tasks.Add(ConfigGeneratorAsync());
                                tasks.Add(FailsafeBroadcasterAsync());
                                await NeonHelper.WaitAllAsync(tasks);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                log.LogCritical(e);
                Program.Exit(1);
                return;
            }
            finally
            {
                HiveHelper.CloseHive();
                terminator.ReadyToExit();
            }

            Program.Exit(0);
            return;
        }
Example #31
0
        protected override UntypedChannel Visitor(ChannelAdapter channel)
        {
            bool wasAdded = _added;

            channel.ChangeOutputChannel(original =>
                {
                    _added = wasAdded;

                    UntypedChannel replacement = Visit(original);

                    if (!_added)
                    {
                        if (replacement.GetType() == typeof(ShuntChannel))
                        {
                            replacement = new BroadcastChannel(new[] { _newChannel });
                            _added = true;
                        }
                    }

                    return replacement;
                });

            return channel;
        }
Example #32
0
        protected override UntypedChannel Visitor(ChannelAdapter channel)
        {
            UntypedChannel original = channel.Output;

            UntypedChannel replacement = Visit(original);

            if (!_added)
            {
                if (replacement.GetType() == typeof(ShuntChannel))
                {
                    replacement = new BroadcastChannel(new[] {_newChannel});
                    _added = true;
                }
            }

            if (original != replacement)
                channel.ChangeOutputChannel(original, replacement);

            return channel;
        }
Example #33
0
        /// <summary>
        /// Application entry point.
        /// </summary>
        /// <param name="args">Command line arguments.</param>
        public static async Task Main(string[] args)
        {
            LogManager.Default.SetLogLevel(Environment.GetEnvironmentVariable("LOG_LEVEL"));
            log = LogManager.Default.GetLogger(typeof(Program));
            log.LogInfo(() => $"Starting [{serviceName}]");
            log.LogInfo(() => $"LOG_LEVEL={LogManager.Default.LogLevel.ToString().ToUpper()}");

            // Create process terminator to handle process termination signals.

            terminator = new ProcessTerminator(log);

            try
            {
                // Establish the hive connections.

                if (NeonHelper.IsDevWorkstation)
                {
                    var secrets = new DebugSecrets();

                    // NOTE:
                    //
                    // Add your target hive's Vault credentials here for
                    // manual debugging.  Take care not to commit sensitive
                    // credentials for production hives.
                    //
                    // You'll find this information in the ROOT hive login
                    // for the target hive.

                    secrets.Add("neon-hive-manager-vaultkeys",
                                new VaultCredentials()
                    {
                        RootToken    = "cd5831fa-86ec-cc22-b1f3-051f88147382",
                        KeyThreshold = 1,
                        UnsealKeys   = new List <string>()
                        {
                            "8SgwdO/GwqJ7nyxT2tK2n1CCR3084kQVh7gEy8jNQh8="
                        }
                    });

                    hive = HiveHelper.OpenHiveRemote(secrets);
                }
                else
                {
                    hive = HiveHelper.OpenHive(sshCredentialsSecret: "neon-ssh-credentials");
                }

                // Ensure that we're running on a manager node.  We won't be able
                // to query swarm status otherwise.

                var nodeRole = Environment.GetEnvironmentVariable("NEON_NODE_ROLE");

                if (string.IsNullOrEmpty(nodeRole))
                {
                    log.LogCritical(() => "Service does not appear to be running on a neonHIVE.");
                    Program.Exit(1, immediate: true);
                }

                if (!string.Equals(nodeRole, NodeRole.Manager, StringComparison.OrdinalIgnoreCase))
                {
                    log.LogCritical(() => $"[neon-hive-manager] service is running on a [{nodeRole}] hive node.  Running on only [{NodeRole.Manager}] nodes are supported.");
                    Program.Exit(1, immediate: true);
                }

                // Open the hive data services and then start the main service task.

                log.LogDebug(() => $"Connecting: Consul");

                using (consul = HiveHelper.OpenConsul())
                {
                    log.LogDebug(() => $"Connecting: Docker");

                    using (docker = HiveHelper.OpenDocker())
                    {
                        log.LogInfo(() => $"Connecting: {HiveMQChannels.ProxyNotify} channel");

                        // We're passing [useBootstrap=true] here so that the HiveMQ client will
                        // connect directly to the HiveMQ cluster nodes as opposed to routing
                        // traffic through the private traffic manager.  This is necessary because
                        // the load balancers rely on HiveMQ to broadcast update notifications.
                        //
                        // One consequence of this is that this service will need to be restarted
                        // whenever HiveMQ instances are relocated to different hive hosts.
                        // We're going to monitor for changes to the HiveMQ bootstrap settings
                        // and gracefully terminate the process when this happens.  We're then
                        // depending on Docker to restart the process so we'll be able to pick
                        // up the change.

                        hive.HiveMQ.Internal.HiveMQBootstrapChanged +=
                            (s, a) =>
                        {
                            log.LogInfo("HiveMQ bootstrap settings change detected.  Terminating service with [exitcode=-1] expecting that Docker will restart it.");

                            // Use ExitCode=-1 so that we'll restart even if the service/container
                            // was not configured with [restart=always].

                            terminator.Exit(-1);
                        };

                        using (proxyNotifyChannel = hive.HiveMQ.Internal.GetProxyNotifyChannel(useBootstrap: true).Open())
                        {
                            await RunAsync();
                        }
                    }
                }
            }
            catch (Exception e)
            {
                log.LogCritical(e);
                Program.Exit(1);
                return;
            }
            finally
            {
                HiveHelper.CloseHive();
                terminator.ReadyToExit();
            }

            Program.Exit(0);
            return;
        }
Example #34
0
        private void OnBroadcast()
        {
            var source = StreamSource;
            var contentReaderFactory = ContentType;

            if (!CanBroadcast(source, contentReaderFactory, channelName))
            {
                return;
            }
            IYellowPageClient yellowPage = this.yellowPage;
            var channelInfo  = CreateChannelInfo(this);
            var channelTrack = CreateChannelTrack(this);

            var channel_id = BroadcastChannel.CreateChannelID(
                peerCast.BroadcastID,
                networkType,
                channelName,
                genre,
                source.ToString());
            var source_stream =
                selectedSourceStream ??
                peerCast.SourceStreamFactories
                .Where(sstream => (sstream.Type & SourceStreamType.Broadcast) != 0)
                .FirstOrDefault(sstream => sstream.Scheme == source.Scheme);
            var channel = peerCast.BroadcastChannel(
                networkType,
                yellowPage,
                channel_id,
                channelInfo,
                source,
                source_stream,
                contentReaderFactory);

            if (channel != null)
            {
                channel.ChannelTrack = channelTrack;
            }

            var info = new BroadcastInfoViewModel {
                NetworkType = this.NetworkType,
                StreamUrl   = this.StreamUrl,
                StreamType  = this.SelectedSourceStream != null ? this.SelectedSourceStream.Name : null,
                Bitrate     = this.bitrate.HasValue ? this.bitrate.Value : 0,
                ContentType = this.ContentType.Name,
                YellowPage  = this.YellowPage != null ? this.YellowPage.Name : null,
                ChannelName = this.ChannelName,
                Genre       = this.Genre,
                Description = this.Description,
                Comment     = this.Comment,
                ContactUrl  = this.ContactUrl,
                TrackTitle  = this.TrackTitle,
                TrackAlbum  = this.TrackAlbum,
                TrackArtist = this.TrackArtist,
                TrackGenre  = this.TrackGenre,
                TrackUrl    = this.TrackUrl,
                Favorite    = false,
            };

            uiSettings.AddBroadcastHistory(info);
            uiSettings.Save();
        }
Example #35
0
        protected override Channel <T> Visitor <T>(BroadcastChannel <T> channel)
        {
            Trace.WriteLine("ChannelRouter<{0}>, {1} subscribers".FormatWith(typeof(T).Name, channel.Listeners.Count()));

            return(base.Visitor(channel));
        }
Example #36
0
        protected override UntypedChannel Visitor(BroadcastChannel channel)
        {
            Trace.WriteLine("UntypedChannelRouter: {0} subscribers".FormatWith(channel.Listeners.Count()));

            return(base.Visitor(channel));
        }