Example #1
0
 private void ProcessMessageActions(INyxMessage msg)
 {
     try
     {
         var action      = msg.Action;
         var borgPlugins = _plugman.GetActions <IBorgAction>(p => p.SupportedActions.Contains(action)).ToList();
         if (borgPlugins.Count == 0)
         {
             return;
         }
         var sw = Stopwatch.StartNew();
         _logger.Trace("Plugins with action {0}: {1} in {2}", msg.Action, borgPlugins.Count(), _plugman.GetActions <IBorgAction>().Count());
         void forAction(IBorgAction borgPlug)
         {
             try
             {
                 _logger.Debug("Running action {0} for message {1} on processor {2}", msg.Action, msg, borgPlug.GetType().Name);
                 borgPlug.ProcessMessage(msg.AsReadOnly());
             }
             catch (Exception ex)
             {
                 _logger.Error($"Error running action on {borgPlug.GetType().Name}", ex);
             }
         }
         borgPlugins.ForEach(forAction);
         _logger.Trace("Message actions took {0}ms", sw.ElapsedMilliseconds);
         sw.Stop();
     }
     catch (Exception ex)
     {
         _logger.Error("Error processing actions.", ex);
     }
 }
Example #2
0
        /// <summary>
        /// Broadcast message to the given channel(s)
        /// </summary>
        /// <param name="msg"></param>
        public void BroadcastMessage(INyxMessage msg)
        {
            if (!_isStarted || _hubActor == null)
            {
                _logger.Warn("Hub is not started.");
                return;
            }
            _logger.Debug("Broadcasting message to channel {0}...", StringExtensions.Trimmer(msg.Target));
            ((NyxMessage)msg).Direction = MessageDirection.Out;
            var error = string.Empty;

            try
            {
                var filterFound = _plugman.GetFilters(f => f.Direction.HasFlag(MessageDirection.Out) && f.CanFilter(this)).FirstOrDefault(filter => !filter.AllowMessage(msg, this, out error));
                if (filterFound != null)
                {
                    _logger.Warn("Message not sent. Was filtered by {0}. {1}", filterFound.GetType().Name, error);
                    return;
                }
            }
            catch (Exception ex)
            {
                _logger.Error("Error filtering message.", ex);
            }

            _hubActor.SendMoreFrame("broadcast").SendMoreFrame(msg.Target).SendFrame(msg.ToDefault());
            _outMessageStatus.OnNext(msg.AsReadOnly().SuccessfullSent(this));
        }
Example #3
0
        public override bool ProcessMessage(INyxMessage msg)
        {
            if (_hub == null)
            {
                return(true);
            }
            switch (msg.Action)
            {
            case Register:
                _logger.Info("Registered node {0}", StringExtensions.Trimmer(msg.Source));
                _hub.BroadcastMessage(new NyxMessage
                {
                    Target = msg.Source,
                    Action = Callback,
                    Source = NyxId
                }.Set("event", "registered")
                                      );
                break;

            case Ping:
                _logger.Info("Node {0} pinged.", StringExtensions.Trimmer(msg.Source));
                msg.Reply(Pong).BroadcastMessage(_hub);
                break;

            default:
                return(false);
            }
            return(true);
        }
Example #4
0
        /// <summary>
        /// Prepares nodes info
        /// </summary>
        /// <param name="message"></param>
        /// <param name="sender"></param>
        private void PrepareNodeInfo(INyxMessage message, INyxNode sender)
        {
            NodeInfo nodeInfo;

            try
            {
                nodeInfo = NodeInfo.BuildInfo((INyxBorg)sender);
            }
            catch (Exception ex)
            {
                _logger.Error("Error building node info.", ex);
                return;
            }
            var plugs = _pluginManager.GetExtensions().Where(e => e.GetType().IsAssignableTo <IExtendNodeInfo>()).Cast <IExtendNodeInfo>();
            var sw    = Stopwatch.StartNew();
            Action <IExtendNodeInfo> act = p =>
            {
                sw.Restart();
                try
                {
                    p.AddExtraData(nodeInfo);
                }
                catch (Exception ex)
                {
                    _logger.Error($"Error adding extra info from type {p?.GetType().FullName}.", ex);
                }
                _logger.Trace("{0} took {1}ms to add node info.", p.GetType().FullName, sw.ElapsedMilliseconds);
            };

            sw.Stop();
            plugs.ForEach(act);
            message.Set(NodeManagerInfo, nodeInfo);
        }
Example #5
0
 /// <summary>
 ///     Allows all messages to pass, just add new info to them, or removes so they don't get into the borgs by mistake.
 /// </summary>
 /// <param name="message"></param>
 /// <param name="sender"></param>
 /// <param name="error"></param>
 /// <returns></returns>
 public bool AllowMessage(INyxMessage message, INyxNode sender, out string error)
 {
     lock (FilterLock)
     {
         error = string.Empty;
         if (sender is INyxBorg)
         {
             if (message.Direction == MessageDirection.Out)
             {
                 PrepareNodeInfo(message, sender);
             }
             return(true);
         }
         var msg = message.AsReadOnly();
         // We use a queue
         _tasker.QueueTask(() =>
         {
             try
             {
                 RunNodeCollector(msg);
             }
             catch (Exception ex)
             {
                 _logger.Error("Error processing node info.", ex);
             }
         });
     }
     return(true);
 }
Example #6
0
        /// <summary>
        /// Converts a NyxMessage to Json and then to a NetMQMessage
        /// </summary>
        /// <param name="msg">Nyx message</param>
        /// <returns>Converted NetMQMessage</returns>
        public static NetMQMessage ToJsonMessage(this INyxMessage msg)
        {
            var zmsg = new NetMQMessage();

            zmsg.Push(msg.ToJson());
            return(zmsg);
        }
Example #7
0
        /// <summary>
        /// Converts a NyxMessage to the default type and then to a NetMQMessage.
        /// This should be plugable... for future proof
        /// </summary>
        /// <param name="msg">Nyx message</param>
        /// <returns>Converted NetMQMessage</returns>
        public static NetMQMessage ToNetMQMessage(this INyxMessage msg)
        {
            // TODO: Add plugin support or atleast configuration support, so we can
            var zmsg = new NetMQMessage();

            zmsg.Push(msg.ToDefault());
            return(zmsg);
        }
Example #8
0
 /// <summary>
 /// Converts <see cref="INyxMessage"/> into a <see cref="ReadOnlyNyxMessage"/> if it isn't read only yet./>
 /// <remarks>Note that this doesn't create a new message every call, only if needed.</remarks>
 /// </summary>
 /// <param name="msg">Read only <see cref="INyxMessage"/>.</param>
 /// <returns></returns>
 public static INyxMessage AsReadOnly([NotNull] this INyxMessage msg)
 {
     if (msg is ReadOnlyNyxMessage)
     {
         return(msg);
     }
     return(new ReadOnlyNyxMessage(msg));
 }
Example #9
0
 public MessageStatus(INyxNode sender, INyxMessage msg, MessageCondition condition, string description, bool hubReply)
 {
     Sender      = sender;
     Message     = msg;
     Status      = condition;
     IsHubReply  = hubReply;
     Description = description;
 }
Example #10
0
 public bool TransferFiles(INyxMessage message, INyxBorg sender)
 {
     if (message.Has("fileTransfer"))
     {
         return(true);
     }
     _taskQueue.QueueTask(() => AsyncLoadToMessage(message, sender));
     return(false);
 }
Example #11
0
 public bool ExtractFiles(INyxMessage message, INyxBorg nyxBorg)
 {
     if (message.Has("fileExtract"))
     {
         return(true);
     }
     _taskQueue.QueueTask(() => AsyncExtractFiles(message, nyxBorg));
     return(false);
 }
Example #12
0
        /// <summary>
        ///     Queues a message for sending to the hub for distribution.
        /// </summary>
        /// <param name="msg">Nyx message to send.</param>
        /// <param name="skip">Doesn't queue the message if no connection to the hub.</param>
        /// <returns>An observable for checking when the message is delivered to the Hub.</returns>
        public IObservable <MessageStatus> SendMessage(INyxMessage msg, bool skip = false)
        {
            if (msg == null)
            {
                return(Observable.Return(new MessageStatus(this, NyxMessage.EmptyOut, MessageCondition.Failed, "Null message")));
            }
            if (string.IsNullOrWhiteSpace(msg.Source))
            {
                msg.Source = NodeId;
            }
            if (string.IsNullOrWhiteSpace(msg.Target))
            {
                _logger.Error("Message validation failed, missing Target.");
                return(Observable.Return(new MessageStatus(this, msg, MessageCondition.Failed, "Message validation failed, missing Target.")));
            }
            // Processes internal messages like they were external messages.
            if (msg is InternalNyxMessage)
            {
                return(Observable.Start(() => ProcessExternalMessages(msg)));
            }
            if ((!_isConnected && !_queueOnDisconnected) || (!_hubOnline && skip) || (!_isConnected && skip))
            {
                _logger.Debug("Message missed. Not connected to any hub, or hub offline.");
                return(Observable.Return(new MessageStatus(this, msg, MessageCondition.Failed, "Not connected to any hub.")));
            }

            if (_messageLoopCancelation.IsCancellationRequested)
            {
                _logger.Error("Message missed. Not connected to any hub, or hub offline.");
                return(Observable.Return(new MessageStatus(this, msg, MessageCondition.Failed, "Borg is going down.")));
            }

            ((NyxMessage)msg).Direction = MessageDirection.Out;
            var observable = Observable.Create <MessageStatus>(observer =>
            {
                return(OutMessageStream.Where(m => m?.Message.Id == msg.Id).Subscribe(n =>
                {
                    observer.OnNext(n);
                    switch (n.Status)
                    {
                    case MessageCondition.Failed:
                    case MessageCondition.Filtered:
                    case MessageCondition.Sent:
                        observer.OnCompleted();
                        break;
                    }
                }));
            });

            lock (MessageQueueSync)
                _messageQueue.Enqueue(new MessageHelper {
                    Message = msg
                });
            _messageSendResetEvent.Set();

            return(observable);
        }
Example #13
0
        /// <summary>
        ///     Creates a reply message, by switching the target and source and maitaining the previous data bag.
        /// Also adds info from the previous message.
        /// <remarks>All file data is not transfered.</remarks>
        /// </summary>
        /// <param name="msg">Source message</param>
        /// <param name="action">Message action</param>
        /// <returns></returns>
        public static INyxMessage ReplyWithData(this INyxMessage msg, string action)
        {
            var reply = new NyxMessage(msg.Source, action, msg.Target).Set(CoreParamsOriginalMessageId, msg.ShortId());

            foreach (var element in msg.Elements)
            {
                reply.Set(element.Key, element.Value);
            }
            return(reply);
        }
Example #14
0
 public ReadOnlyNyxMessage(INyxMessage message)
 {
     Id        = message.Id;
     _target   = message.Target;
     _source   = message.Source;
     _action   = message.Action;
     Direction = message.Direction;
     Elements  = new ReadOnlyDictionary <string, object>((IDictionary <string, object>)message.Elements);
     Files     = new ReadOnlyCollection <IFile>(message.Files);
 }
Example #15
0
 private MessageStatus ProcessExternalMessages(INyxMessage msg)
 {
     if (FilterMessage(msg))
     {
         return(msg.Filtered(this, "Filtered."));
     }
     if (msg.Direction == MessageDirection.In)
     {
         ProcessMessageActions(msg.AsReadOnly());
     }
     _messageReceived.OnNext(msg.SuccessfullReceived(this));
     return(msg.SuccessfullSent(this));
 }
Example #16
0
        /// <summary>
        ///     Send the info to the requester <see cref="INyxBorg" />.
        /// </summary>
        /// <param name="sourceMessage">Source message</param>
        /// <param name="target">Target for receiveing the updates</param>
        /// <param name="added">Nodes added.</param>
        /// <param name="removed">Nodes removed.</param>
        private void SendNodesInfo([CanBeNull] INyxMessage sourceMessage, [CanBeNull] string target,
                                   [NotNull] IEnumerable <NodeInfo> added, [NotNull] IEnumerable <NodeInfo> removed, bool cleanup = false)
        {
            _logger.Debug("Pushing node updates to {0}", target);
            var msg = string.IsNullOrWhiteSpace(target)
                ? sourceMessage.Reply(NodesInfoReport)
                : new NyxMessage(target, NodesInfoReport, "Nyx");

            msg.Set(NodeManagerAdded, added.ToArray());
            msg.Set(NodeManagerRemoved, removed.ToArray());
            msg.Set(NodeManagerCleanup, cleanup);
            _hub.BroadcastMessage(msg);
        }
Example #17
0
        /// <summary>
        ///     Converts a INyxMessage into a internal message.
        ///     This is used to communicate inside borg, it nevers leaves the borg.
        ///     Internal messages are processed by the message filters and message processors, like they were received.
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public static INyxMessage AsInternal([NotNull] this INyxMessage msg)
        {
            if (msg is InternalNyxMessage)
            {
                return(msg);
            }
            var nmsg = msg as NyxMessage;

            return(nmsg == null ? null : new InternalNyxMessage(nmsg)
            {
                Direction = MessageDirection.In
            });
        }
Example #18
0
        /// <summary>
        ///     Process messages on borg or host conform the case.
        /// </summary>
        /// <param name="message">Message to process.</param>
        /// <returns></returns>
        public bool ProcessMessage(INyxMessage message)
        {
            // We lock here so we can process this without caring too much.
            lock (ProcessLock)
            {
                if (_hub != null)
                {
                    _messageReceivedHub.OnNext(message);
                    switch (message.Action)
                    {
                    case NodesInfo:
                        SendNodesInfo(message, new List <NodeInfo>(_nodesInfo), new List <NodeInfo>(), true);
                        return(true);

                    case NodesUpdateSubscribe:
                        SendNodesInfo(message, new List <NodeInfo>(_nodesInfo), new List <NodeInfo>(), true);
                        lock (UpdaterLock)
                        {
                            if (!_pushUpdates.Contains(message.Source))
                            {
                                _pushUpdates.Add(message.Source);
                            }
                        }
                        break;

                    case NodesPing:
                        // This is just so we update the info of the node, no action required.
                        break;
                    }
                    return(true);
                }
                if (_borg == null)
                {
                    return(true);
                }
                switch (message.Action)
                {
                case NodesInfoReport:
                    BuildReportFromMessage(message);
                    break;
                }
                _messageReceivedBorg.OnNext(message);
            }
            return(true);
        }
Example #19
0
        private bool FilterMessage(INyxMessage msg)
        {
            var abort = false;

            try
            {
                var error   = string.Empty;
                var filters = _plugman.GetFilters(f => f.Direction.HasFlag(msg.Direction) && f.CanFilter(this)).ToList();
                if (!filters.Any())
                {
                    return(true);
                }
                var sw          = Stopwatch.StartNew();
                var filterFound = filters.FirstOrDefault(filter => msg != null && !filter.AllowMessage(msg, this, out error));
                if (filterFound != null)
                {
                    if (error != string.Empty)
                    {
                        _logger.Warn("Message {0} was filtered by {1}. {2}", msg, filterFound.GetType().Name, error);
                    }
                    var messageStatus = msg.Filtered(this, $"Message was filtered by {filterFound.GetType().Name}.");
                    if (!(msg is InternalNyxMessage) && msg.Direction == MessageDirection.In)
                    {
                        _messageReceived.OnNext(messageStatus);
                    }
                    if (!(msg is InternalNyxMessage) && msg.Direction == MessageDirection.Out)
                    {
                        _messageReplyReceived.OnNext(msg.Filtered(this, error));
                    }
                    abort = true;
                }
                _logger.Trace("Message filter took {0}ms", sw.ElapsedMilliseconds);
            }
            catch (Exception ex)
            {
                _logger.Error("Error processing filter.", ex);
            }
            return(abort);
        }
Example #20
0
        private void BuildReportFromMessage(INyxMessage message)
        {
            lock (NodesLock)
            {
                var added   = message.Get <IEnumerable <NodeInfo> >(NodeManagerAdded);
                var removed = message.Get <IEnumerable <NodeInfo> >(NodeManagerRemoved);
                var cleanup = message.Get <bool>(NodeManagerCleanup);
                // Cache all nodes info on borg.
                if (cleanup)
                {
                    _nodesInfo.Clear();
                    removed = new List <NodeInfo>(_nodesInfo);
                }
                else
                {
                    _nodesInfo.RemoveAll(p => removed.Any(r => p?.NodeId == r.NodeId));
                }

                var addedNodes = added as IList <NodeInfo> ?? added.ToList();
                if (added != null)
                {
                    _nodesInfo.RemoveAll(n => addedNodes.Any(o => o.NodeId == n.NodeId));
                    _nodesInfo.AddRange(addedNodes);
                }

                UpdateGroupInfo();
                // Internal broadcast the info to the message bus, so ui can get the updates.
                var managerMessage = new NodesChanges
                {
                    Added   = addedNodes,
                    Removed = removed,
                    All     = new List <NodeInfo>(_nodesInfo)
                };
                _nodesSubject.OnNext(managerMessage);
                _groupSubject.OnNext(_groups.Clone());
            }
        }
Example #21
0
        /// <summary>
        ///     Override this for handling the SubSocket receive
        /// </summary>
        /// <param name="msg"></param>
        private void ReceivedMessage(INyxMessage msg)
        {
            var data = string.Empty;

            try
            {
                _logger.Trace("Received message...");
                _logger.Trace("Message source: {0}", msg.Source);

                if (FilterMessage(msg))
                {
                    return;
                }

                // Run message processing in another thread
                var readOnly = msg.AsReadOnly();
                void processMessages() => ProcessMessageActions(readOnly);

                if (_multithread)
                {
                    _tasker.QueueTask(processMessages);
                }
                else
                {
                    processMessages();
                }

                // Notify
                _messageReceived.OnNext(msg.SuccessfullReceived(this));
            }

            catch (Exception ex)
            {
                _logger.Error($"Exception caught in message {data}.", ex);
            }
        }
Example #22
0
 public MessageStatus(INyxNode sender, INyxMessage msg, MessageCondition condition, bool hubReply) :
     this(sender, msg, condition, string.Empty, hubReply)
 {
 }
Example #23
0
 public MessageStatus(INyxNode sender, INyxMessage msg, MessageCondition condition, string description) :
     this(sender, msg, condition, description, false)
 {
 }
Example #24
0
 public static IObservable <INyxMessage> IsReplyTo(this IObservable <INyxMessage> observable, INyxMessage message)
 {
     return(observable.Where(m => m?.IsReplyTo(message) ?? false));
 }
Example #25
0
 /// <summary>
 ///     Timeouts the message and returns a Failed message status.
 /// </summary>
 /// <param name="observable"></param>
 /// <param name="timeoutSeconds"></param>
 /// <param name="msg"></param>
 /// <returns></returns>
 public static IObservable <MessageStatus> TimeoutMessage(this IObservable <MessageStatus> observable, double timeoutSeconds, INyxMessage msg)
 {
     return(observable
            .Amb(Observable.Return(msg.Timeout(null, "Timeout waiting for message.")).Delay(TimeSpan.FromSeconds(timeoutSeconds * 2))));
 }
Example #26
0
 public bool SeedFiles(INyxMessage message, INyxHub nyxHub)
 {
     // Do nothing just pass the file
     return(true);
 }
Example #27
0
 /// <summary>
 /// Always create a new <see cref="ReadOnlyNyxMessage"/> from a <see cref="INyxMessage"/>./>
 /// </summary>
 /// <param name="msg">Read only <see cref="INyxMessage"/>.</param>
 /// <returns></returns>
 public static INyxMessage ToReadOnly(this INyxMessage msg)
 {
     return(new ReadOnlyNyxMessage(msg));
 }
Example #28
0
 public static INyxMessage FromDefault(this INyxMessage msg, string message)
 {
     return(msg.FromJson(message));
 }
Example #29
0
 /// <summary>
 /// Converts a NyxMessage to json format
 /// </summary>
 /// <param name="msg"></param>
 /// <returns></returns>
 public static string ToJson(this INyxMessage msg)
 {
     return(JsonConvert.SerializeObject(msg));
 }
Example #30
0
 public static string ToDefault(this INyxMessage msg)
 {
     return(msg.ToJson());
 }