private bool IsFiltered(MessageHandlerInfo info, MessageHandlerContext context)
        {
            if (context.Notification != null && info.NotificationNames != null && !info.NotificationNames.Contains(context.Notification.Notification))
            {
                return(true);
            }
            if (context.Command != null && info.CommandNames != null && !info.CommandNames.Contains(context.Command.Command))
            {
                return(true);
            }
            if (info.DeviсeGuids != null && !info.DeviсeGuids.Contains(context.Device.GUID, StringComparer.OrdinalIgnoreCase))
            {
                return(true);
            }
            if (info.DeviсeClassIds != null && !info.DeviсeClassIds.Contains(context.Device.DeviceClassID))
            {
                return(true);
            }
            if (info.NetworkIds != null && !info.NetworkIds.Contains(context.Device.NetworkID ?? 0))
            {
                return(true);
            }

            return(false);
        }
        /// <summary>
        /// Handles the incoming notification.
        /// </summary>
        /// <param name="context">MessageHandlerContext object.</param>
        public void HandleNotification(MessageHandlerContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (context.Notification == null)
            {
                throw new ArgumentNullException("context.Notification");
            }

            // prepare array of matching handlers
            var handlers = _messageHandlerInfos.Where(info => !IsFiltered(info, context)).Select(i => i.MessageHandler).ToArray();

            // invoke NotificationReceived on handlers; return if IgnoreMessage was set
            InvokeHandlers(handlers, context, handler => handler.NotificationReceived(context));
            if (context.IgnoreMessage)
            {
                return;
            }

            // save notification into the database
            _deviceNotificationRepository.Save(context.Notification);

            // invoke NotificationInserted on handlers
            InvokeHandlers(handlers, context, handler => handler.NotificationInserted(context));

            // notify other nodes about new notification
            _messageBus.Notify(new DeviceNotificationAddedMessage(context.Device.ID, context.Notification.ID, context.Notification.Notification));
        }
        public JObject Post(string deviceGuid, JObject json)
        {
            var device = GetDeviceEnsureAccess(deviceGuid);

            var notification = Mapper.Map(json);
            notification.Device = device;
            Validate(notification);

            var context = new MessageHandlerContext(notification, CallContext.CurrentUser);
            _messageManager.HandleNotification(context);

            return Mapper.Map(notification, oneWayOnly: true);
        }
        public JObject Post(string deviceGuid, JObject json)
        {
            var device = GetDeviceEnsureAccess(deviceGuid);

            var command = Mapper.Map(json);
            command.Device = device;
            command.UserID = CallContext.CurrentUser.ID;
            Validate(command);

            var context = new MessageHandlerContext(command, CallContext.CurrentUser);
            _messageManager.HandleCommand(context);

            return Mapper.Map(command, oneWayOnly: true);
        }
        private void InvokeHandlers(MessageHandler[] handlers, MessageHandlerContext context, Action <MessageHandler> action)
        {
            foreach (var handler in handlers)
            {
                try
                {
                    action(handler);
                }
                catch (Exception ex)
                {
                    LogManager.GetLogger(GetType()).Error("Message handler generated exception!", ex);
                }

                if (context.IgnoreMessage)
                {
                    break;
                }
            }
        }
        /// <summary>
        /// Handles the command update request.
        /// </summary>
        /// <param name="context">MessageHandlerContext object.</param>
        public void HandleCommandUpdate(MessageHandlerContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (context.Command == null)
            {
                throw new ArgumentNullException("context.Command");
            }

            // prepare array of matching handlers
            var handlers = _messageHandlerInfos.Where(info => !IsFiltered(info, context)).Select(i => i.MessageHandler).ToArray();

            // save command into the database
            _deviceCommandRepository.Save(context.Command);

            // invoke CommandUpdated on handlers
            InvokeHandlers(handlers, context, handler => handler.CommandUpdated(context));

            // notify other nodes about command update
            _messageBus.Notify(new DeviceCommandUpdatedMessage(context.Device.ID, context.Command.ID));
        }
 /// <summary>
 /// Invoked when a new command is inserted.
 /// </summary>
 /// <param name="context">MessageHandlerContext object.</param>
 public virtual void CommandInserted(MessageHandlerContext context)
 {
 }
 /// <summary>
 /// Invoked when a new command is retrieved, but not yet processed.
 /// Set context.IgnoreMessage to True to ignore the command.
 /// </summary>
 /// <param name="context">MessageHandlerContext object.</param>
 public virtual void CommandReceived(MessageHandlerContext context)
 {
 }
 /// <summary>
 /// Invoked when a new notification is inserted.
 /// </summary>
 /// <param name="context">MessageHandlerContext object.</param>
 public virtual void NotificationInserted(MessageHandlerContext context)
 {
 }
 /// <summary>
 /// Invoked when a new notification is retrieved, but not yet processed.
 /// Set context.IgnoreMessage to True to ignore the notification.
 /// </summary>
 /// <param name="context">MessageHandlerContext object.</param>
 public virtual void NotificationReceived(MessageHandlerContext context)
 {
 }
        public void UpdateDeviceCommand(string deviceGuid, int commandId, JObject command)
        {
            if (string.IsNullOrEmpty(deviceGuid))
                throw new WebSocketRequestException("Please specify valid deviceGuid");

            if (commandId == 0)
                throw new WebSocketRequestException("Please specify valid commandId");
            
            if (command == null)
                throw new WebSocketRequestException("Please specify command");

            var device = DataContext.Device.Get(deviceGuid);
            if (device == null || !IsDeviceAccessible(device, "UpdateDeviceCommand"))
                throw new WebSocketRequestException("Device not found");

            var commandEntity = DataContext.DeviceCommand.Get(commandId);
            if (commandEntity == null || commandEntity.DeviceID != device.ID)
                throw new WebSocketRequestException("Device command not found");

            GetMapper<DeviceCommand>().Apply(commandEntity, command);
            commandEntity.Device = device;
            Validate(commandEntity);

            var context = new MessageHandlerContext(commandEntity, CurrentUser);
            _messageManager.HandleCommandUpdate(context);

            SendSuccessResponse();
        }
        public void Put(string deviceGuid, int id, JObject json)
        {
            var device = GetDeviceEnsureAccess(deviceGuid);

            var command = DataContext.DeviceCommand.Get(id);
            if (command == null || command.DeviceID != device.ID)
                ThrowHttpResponse(HttpStatusCode.NotFound, "Device command not found!");

            Mapper.Apply(command, json);
            command.Device = device;
            Validate(command);

            var context = new MessageHandlerContext(command, CallContext.CurrentUser);
            _messageManager.HandleCommandUpdate(context);
        }
 private bool IsFiltered(MessageHandlerInfo info, MessageHandlerContext context)
 {
     if (context.Notification != null && info.NotificationNames != null && !info.NotificationNames.Contains(context.Notification.Notification))
         return true;
     if (context.Command != null && info.CommandNames != null && !info.CommandNames.Contains(context.Command.Command))
         return true;
     if (info.DeviсeGuids != null && !info.DeviсeGuids.Contains(context.Device.GUID, StringComparer.OrdinalIgnoreCase))
         return true;
     if (info.DeviсeClassIds != null && !info.DeviсeClassIds.Contains(context.Device.DeviceClassID))
         return true;
     if (info.NetworkIds != null && !info.NetworkIds.Contains(context.Device.NetworkID ?? 0))
         return true;
     
     return false;
 }
 /// <summary>
 /// Invoked when a new notification is inserted.
 /// </summary>
 /// <param name="context">MessageHandlerContext object.</param>
 public virtual void NotificationInserted(MessageHandlerContext context)
 {
 }
 /// <summary>
 /// Invoked when a new command is retrieved, but not yet processed.
 /// Set context.IgnoreMessage to True to ignore the command.
 /// </summary>
 /// <param name="context">MessageHandlerContext object.</param>
 public virtual void CommandReceived(MessageHandlerContext context)
 {
 }
 /// <summary>
 /// Invoked when a new notification is retrieved, but not yet processed.
 /// Set context.IgnoreMessage to True to ignore the notification.
 /// </summary>
 /// <param name="context">MessageHandlerContext object.</param>
 public virtual void NotificationReceived(MessageHandlerContext context)
 {
 }
        /// <summary>
        /// Handles the incoming notification.
        /// </summary>
        /// <param name="context">MessageHandlerContext object.</param>
        public void HandleNotification(MessageHandlerContext context)
        {
            if (context == null)
                throw new ArgumentNullException("context");
            if (context.Notification == null)
                throw new ArgumentNullException("context.Notification");

            // prepare array of matching handlers
            var handlers = _messageHandlerInfos.Where(info => !IsFiltered(info, context)).Select(i => i.MessageHandler).ToArray();

            // invoke NotificationReceived on handlers; return if IgnoreMessage was set
            InvokeHandlers(handlers, context, handler => handler.NotificationReceived(context));
            if (context.IgnoreMessage)
                return;

            // save notification into the database
            _deviceNotificationRepository.Save(context.Notification);

            // invoke NotificationInserted on handlers
            InvokeHandlers(handlers, context, handler => handler.NotificationInserted(context));

            // notify other nodes about new notification
            _messageBus.Notify(new DeviceNotificationAddedMessage(context.Device.ID, context.Notification.ID, context.Notification.Notification));
        }
        private void InvokeHandlers(MessageHandler[] handlers, MessageHandlerContext context, Action<MessageHandler> action)
        {
            foreach (var handler in handlers)
            {
                try
                {
                    action(handler);
                }
                catch (Exception ex)
                {
                    LogManager.GetLogger(GetType()).Error("Message handler generated exception!", ex);
                }

                if (context.IgnoreMessage)
                    break;
            }
        }
 /// <summary>
 /// Invoked when an existing command is updated.
 /// </summary>
 /// <param name="context">MessageHandlerContext object.</param>
 public virtual void CommandUpdated(MessageHandlerContext context)
 {
 }
        public void InsertDeviceCommand(string deviceGuid, JObject command)
        {
            if (string.IsNullOrEmpty(deviceGuid))
                throw new WebSocketRequestException("Please specify valid deviceGuid");

            if (command == null)
                throw new WebSocketRequestException("Please specify command");

            var device = DataContext.Device.Get(deviceGuid);
            if (device == null || !IsDeviceAccessible(device, "CreateDeviceCommand"))
                throw new WebSocketRequestException("Device not found");

            var commandEntity = GetMapper<DeviceCommand>().Map(command);
            commandEntity.Device = device;
            commandEntity.UserID = CurrentUser.ID;
            Validate(commandEntity);

            var context = new MessageHandlerContext(commandEntity, CurrentUser);
            _messageManager.HandleCommand(context);
            if (!context.IgnoreMessage)
                _commandSubscriptionManager.Subscribe(Connection, commandEntity.ID);

            command = GetMapper<DeviceCommand>().Map(commandEntity, oneWayOnly: true);
            SendResponse(new JProperty("command", command));
        }
        public void UpdateDeviceCommand(int commandId, JObject command)
        {
            if (commandId == 0)
                throw new WebSocketRequestException("Please specify valid commandId");

            if (command == null)
                throw new WebSocketRequestException("Please specify command");

            var commandEntity = DataContext.DeviceCommand.Get(commandId);
            if (commandEntity == null || commandEntity.DeviceID != CurrentDevice.ID)
                throw new WebSocketRequestException("Device command not found");

            GetMapper<DeviceCommand>().Apply(commandEntity, command);
            commandEntity.Device = CurrentDevice;
            Validate(commandEntity);

            var context = new MessageHandlerContext(commandEntity, null);
            _messageManager.HandleCommandUpdate(context);

            SendSuccessResponse();
        }
        /// <summary>
        /// Handles the command update request.
        /// </summary>
        /// <param name="context">MessageHandlerContext object.</param>
        public void HandleCommandUpdate(MessageHandlerContext context)
        {
            if (context == null)
                throw new ArgumentNullException("context");
            if (context.Command == null)
                throw new ArgumentNullException("context.Command");

            // prepare array of matching handlers
            var handlers = _messageHandlerInfos.Where(info => !IsFiltered(info, context)).Select(i => i.MessageHandler).ToArray();

            // save command into the database
            _deviceCommandRepository.Save(context.Command);

            // invoke CommandUpdated on handlers
            InvokeHandlers(handlers, context, handler => handler.CommandUpdated(context));

            // notify other nodes about command update
            _messageBus.Notify(new DeviceCommandUpdatedMessage(context.Device.ID, context.Command.ID));
        }
 /// <summary>
 /// Invoked when a new command is inserted.
 /// </summary>
 /// <param name="context">MessageHandlerContext object.</param>
 public virtual void CommandInserted(MessageHandlerContext context)
 {
 }
        public void InsertDeviceNotification(string deviceGuid, JObject notification)
        {
            if (string.IsNullOrEmpty(deviceGuid))
                throw new WebSocketRequestException("Please specify valid deviceGuid");

            if (notification == null)
                throw new WebSocketRequestException("Please specify notification");

            var device = DataContext.Device.Get(deviceGuid);
            if (device == null || !IsDeviceAccessible(device, "CreateDeviceNotification"))
                throw new WebSocketRequestException("Device not found");

            var notificationEntity = GetMapper<DeviceNotification>().Map(notification);
            notificationEntity.Device = device;
            Validate(notificationEntity);

            var context = new MessageHandlerContext(notificationEntity, CurrentUser);
            _messageManager.HandleNotification(context);

            notification = GetMapper<DeviceNotification>().Map(notificationEntity, oneWayOnly: true);
            SendResponse(new JProperty("notification", notification));
        }
 /// <summary>
 /// Invoked when an existing command is updated.
 /// </summary>
 /// <param name="context">MessageHandlerContext object.</param>
 public virtual void CommandUpdated(MessageHandlerContext context)
 {
 }
        public void InsertDeviceNotification(JObject notification)
        {
            if (notification == null)
                throw new WebSocketRequestException("Please specify notification");

            var notificationEntity = GetMapper<DeviceNotification>().Map(notification);
            notificationEntity.Device = CurrentDevice;
            Validate(notificationEntity);

            var context = new MessageHandlerContext(notificationEntity, null);
            _messageManager.HandleNotification(context);

            notification = GetMapper<DeviceNotification>().Map(notificationEntity, oneWayOnly: true);
            SendResponse(new JProperty("notification", notification));
        }