public void Save(DeviceNotification notification)
        {
            if (notification == null)
                throw new ArgumentNullException("notification");

            if (notification.Device != null)
                notification.DeviceID = notification.Device.ID;

            if (notification.ID == default(int))
            {
                // use findAndModify to get the database-generated timestamp in response
                _mongo.SetIdentity(notification, _mongo.GetIdentityFromBlock(typeof(DeviceNotification).Name));
                var result = _mongo.DeviceNotifications.FindAndModify(new FindAndModifyArgs
                    {
                        Query = Query<DeviceNotification>.EQ(e => e.ID, notification.ID),
                        Update = Update.Combine(
                            notification.Timestamp == default(DateTime) ? 
                                Update<DeviceNotification>.CurrentDate(e => e.Timestamp) :
                                Update<DeviceNotification>.Set(e => e.Timestamp, notification.Timestamp),
                            Update<DeviceNotification>.Set(e => e.Notification, notification.Notification),
                            Update.Set("Parameters", notification.Parameters == null ? BsonNull.Value : BsonSerializer.Deserialize<BsonValue>(notification.Parameters)),
                            Update<DeviceNotification>.Set(e => e.DeviceID, notification.DeviceID)),
                        Upsert = true,
                        VersionReturned = FindAndModifyDocumentVersion.Modified,
                        Fields = Fields<DeviceNotification>.Include(e => e.Timestamp),
                    });
                _mongo.SetTimestamp(notification, result.ModifiedDocument["Timestamp"].ToUniversalTime());
            }
            else
            {
                _mongo.DeviceNotifications.Save(notification);
            }
        }
        /// <summary>
        /// Default constructor for notification messages
        /// </summary>
        /// <param name="notification">Associated DeviceNotification object</param>
        /// <param name="user">Associated User object</param>
        public MessageHandlerContext(DeviceNotification notification, User user = null)
        {
            if (notification == null)
                throw new ArgumentNullException("notification");

            Device = notification.Device;
            Notification = notification;
            User = user;
        }
        /// <summary>
        /// Handles a device notification
        /// </summary>
        /// <param name="notification">DeviceNotification object</param>
        public void Handle(DeviceNotification notification)
        {
            var parameters = JObject.Parse(notification.Parameters);
            var deviceStatus = (string)parameters["status"];
            if (string.IsNullOrEmpty(deviceStatus))
                throw new Exception("Device status notification is missing required 'status' parameter");

            var device = _deviceRepository.Get(notification.Device.ID);
            device.Status = deviceStatus;
            _deviceRepository.Save(device);
        }
        public void Save(DeviceNotification notification)
        {
            if (notification == null)
                throw new ArgumentNullException("notification");

            if (notification.Device != null)
                notification.DeviceID = notification.Device.ID;

            _mongo.EnsureIdentity(notification);
            _mongo.EnsureTimestamp(notification);
            _mongo.DeviceNotifications.Save(notification);
        }
        public void RefreshDeviceStatus()
        {
            var devices = DataContext.Device.GetDisconnectedDevices(OFFLINE_STATUS);
            foreach (var device in devices)
            {
                // update device status
                device.Status = OFFLINE_STATUS;
                DataContext.Device.Save(device);

                // save the status diff notification
                var notification = new DeviceNotification(SpecialNotifications.DEVICE_UPDATE, device);
                notification.Parameters = new JObject(new JProperty("status", OFFLINE_STATUS)).ToString();
                DataContext.DeviceNotification.Save(notification);
                _messageBus.Notify(new DeviceNotificationAddedMessage(device.ID, notification.ID, notification.Notification));
            }
        }
        public void Save(DeviceNotification notification)
        {
            if (notification == null)
                throw new ArgumentNullException("notification");

            using (var context = new DeviceHiveContext())
            {
                context.Devices.Attach(notification.Device);
                context.DeviceNotifications.Add(notification);
                if (notification.ID > 0)
                {
                    context.Entry(notification).State = EntityState.Modified;
                }
                context.SaveChanges();
            }
        }
예제 #7
0
        /// <summary>
        /// Processes income notificaton
        /// </summary>
        /// <param name="notification">DeviceNotification object</param>
        public void ProcessNotification(DeviceNotification notification)
        {
            if (notification == null)
                throw new ArgumentNullException("notification");

            foreach (var handler in _notificationHandlers[notification.Notification])
            {
                try
                {
                    handler.Handle(notification);
                }
                catch (Exception ex)
                {
                    LogManager.GetLogger(GetType()).Error("Notification handler generated exception!", ex);
                }
            }
        }
        /// <summary>
        /// Handles a device notification
        /// </summary>
        /// <param name="notification">DeviceNotification object</param>
        public void Handle(DeviceNotification notification)
        {
            var parameters = JObject.Parse(notification.Parameters);
            var equipmentCode = (string)parameters["equipment"];
            if (string.IsNullOrEmpty(equipmentCode))
                throw new Exception("Equipment notification is missing required 'equipment' parameter");

            parameters.Remove("equipment");
            var equipment = _deviceEquipmentRepository.GetByDeviceAndCode(notification.Device.ID, equipmentCode);
            if (equipment == null)
            {
                equipment = new DeviceEquipment(equipmentCode, notification.Timestamp, notification.Device);
            }
            equipment.Timestamp = notification.Timestamp;
            equipment.Device = notification.Device;
            equipment.Parameters = parameters.ToString();
            _deviceEquipmentRepository.Save(equipment);
        }
예제 #9
0
        /// <summary>
        /// Register new or update existing device
        /// </summary>
        public JObject SaveDevice(Device device, JObject deviceJson,
            bool verifyNetworkKey = true)
        {
            // load original device for comparison
            var sourceDevice = device.ID > 0 ? DataContext.Device.Get(device.ID) : null;

            // map and validate the device object
            var deviceMapper = GetMapper<Device>();

            ResolveNetwork(deviceJson, verifyNetworkKey);
            ResolveDeviceClass(deviceJson, device.ID == 0);
            deviceMapper.Apply(device, deviceJson);
            Validate(device);

            // save device object
            DataContext.Device.Save(device);

            // replace equipments for the corresponding device class
            if (!device.DeviceClass.IsPermanent && deviceJson["equipment"] is JArray)
            {
                foreach (var equipment in DataContext.Equipment.GetByDeviceClass(device.DeviceClass.ID))
                {
                    DataContext.Equipment.Delete(equipment.ID);
                }
                foreach (JObject jEquipment in (JArray)deviceJson["equipment"])
                {
                    var equipment = GetMapper<Equipment>().Map(jEquipment);
                    equipment.DeviceClass = device.DeviceClass;
                    Validate(equipment);
                    DataContext.Equipment.Save(equipment);
                }
            }

            // save the device diff notification
            var diff = deviceMapper.Diff(sourceDevice, device);
            var notificationName = sourceDevice == null ? SpecialNotifications.DEVICE_ADD : SpecialNotifications.DEVICE_UPDATE;
            var notification = new DeviceNotification(notificationName, device);
            notification.Parameters = diff.ToString();
            DataContext.DeviceNotification.Save(notification);
            _messageBus.Notify(new DeviceNotificationAddedMessage(device.ID, notification.ID));

            return deviceMapper.Map(device);
        }
예제 #10
0
        /// <summary>
        /// Register new or update existing device.
        /// </summary>
        /// <param name="device">Source device to update.</param>
        /// <param name="deviceJson">A JSON object with device properties.</param>
        /// <param name="verifyNetworkKey">Whether to verify if a correct network key is passed.</param>
        /// <param name="networkAccessCheck">An optional delegate to verify network access control.</param>
        public JObject SaveDevice(Device device, JObject deviceJson,
            bool verifyNetworkKey = true, Func<Network, bool> networkAccessCheck = null)
        {
            // load original device for comparison
            var sourceDevice = device.ID > 0 ? DataContext.Device.Get(device.ID) : null;

            // map and validate the device object
            var deviceMapper = GetMapper<Device>();
            deviceMapper.Apply(device, deviceJson);
            Validate(device);

            // resolve and verify associated objects
            ResolveNetwork(device, verifyNetworkKey, networkAccessCheck);
            ResolveDeviceClass(device);

            // save device object
            DataContext.Device.Save(device);

            // backward compatibility with 1.2 - equipment was passed on device level
            if (!device.DeviceClass.IsPermanent && deviceJson["equipment"] is JArray)
            {
                device.DeviceClass.Equipment = new List<Equipment>();
                foreach (JObject jEquipment in (JArray)deviceJson["equipment"])
                {
                    var equipment = GetMapper<Equipment>().Map(jEquipment);
                    Validate(equipment);
                    device.DeviceClass.Equipment.Add(equipment);
                }
                DataContext.DeviceClass.Save(device.DeviceClass);
            }

            // save the device diff notification
            var diff = deviceMapper.Diff(sourceDevice, device);
            var notificationName = sourceDevice == null ? SpecialNotifications.DEVICE_ADD : SpecialNotifications.DEVICE_UPDATE;
            var notification = new DeviceNotification(notificationName, device);
            notification.Parameters = diff.ToString();
            DataContext.DeviceNotification.Save(notification);
            _messageBus.Notify(new DeviceNotificationAddedMessage(device.ID, notification.ID, notification.Notification));

            return deviceMapper.Map(device);
        }
        private void Notify(WebSocketConnectionBase connection, Guid subscriptionId, DeviceNotification notification, Device device,
            bool isInitialNotification = false)
        {
            if (!isInitialNotification)
            {
                var initialNotificationList = GetInitialNotificationList(connection, subscriptionId);
                lock (initialNotificationList) // wait until all initial notifications are sent
                {
                    if (initialNotificationList.Contains(notification.ID))
                        return;
                }

                if (!IsDeviceAccessible(connection, device, "GetDeviceNotification"))
                    return;
            }

            connection.SendResponse("notification/insert",
                new JProperty("subscriptionId", subscriptionId),
                new JProperty("deviceGuid", device.GUID),
                new JProperty("notification", GetMapper<DeviceNotification>().Map(notification)));
        }
예제 #12
0
        public void DeviceNotification()
        {
            var network = new Network("N1");
            DataContext.Network.Save(network);
            RegisterTearDown(() => DataContext.Network.Delete(network.ID));

            var deviceClass = new DeviceClass("D1", "V1");
            DataContext.DeviceClass.Save(deviceClass);
            RegisterTearDown(() => DataContext.DeviceClass.Delete(deviceClass.ID));

            var device = new Device(Guid.NewGuid().ToString(), "Test", network, deviceClass);
            DataContext.Device.Save(device);
            RegisterTearDown(() => DataContext.Device.Delete(device.ID));

            var notification = new DeviceNotification("Test", device);
            DataContext.DeviceNotification.Save(notification);
            RegisterTearDown(() => DataContext.DeviceNotification.Delete(notification.ID));

            // test GetByDevice
            var notifications = DataContext.DeviceNotification.GetByDevice(device.ID);
            Assert.Greater(notifications.Count, 0);

            // test Get(id)
            var notification1 = DataContext.DeviceNotification.Get(notification.ID);
            Assert.IsNotNull(notification1);
            Assert.AreEqual("Test", notification1.Notification);
            Assert.AreEqual(device.ID, notification1.DeviceID);

            // test Save
            notification.Notification = "Test2";
            notification.Parameters = "{ }";
            DataContext.DeviceNotification.Save(notification);
            var notification2 = DataContext.DeviceNotification.Get(notification.ID);
            Assert.AreEqual("Test2", notification2.Notification);
            Assert.AreEqual("{ }", notification2.Parameters);

            // test Delete
            DataContext.DeviceNotification.Delete(notification.ID);
            var notification3 = DataContext.DeviceNotification.Get(notification.ID);
            Assert.IsNull(notification3);
        }
예제 #13
0
        public void DeviceNotificationTest()
        {
            var network = new Network("N1");
            NetworkRepository.Save(network);

            var deviceClass = new DeviceClass("D1", "V1");
            DeviceClassRepository.Save(deviceClass);

            var device = new Device(Guid.NewGuid(), "key", "Test", network, deviceClass);
            DeviceRepository.Save(device);

            var notification = new DeviceNotification("Test", device);
            DeviceNotificationRepository.Save(notification);

            // test GetByDevice
            var notifications = DeviceNotificationRepository.GetByDevice(device.ID, null, null);
            Assert.Greater(notifications.Count, 0);

            // test Get(id)
            var notification1 = DeviceNotificationRepository.Get(notification.ID);
            Assert.IsNotNull(notification1);
            Assert.AreEqual("Test", notification1.Notification);
            Assert.AreEqual(device.ID, notification1.DeviceID);

            // test Save
            notification.Notification = "Test2";
            notification.Parameters = "{}";
            DeviceNotificationRepository.Save(notification);
            var notification2 = DeviceNotificationRepository.Get(notification.ID);
            Assert.AreEqual("Test2", notification2.Notification);
            Assert.AreEqual("{}", notification2.Parameters);

            // test Delete
            DeviceNotificationRepository.Delete(notification.ID);
            var notification3 = DeviceNotificationRepository.Get(notification.ID);
            Assert.IsNull(notification3);
        }
예제 #14
0
        private void Notify(WebSocketConnectionBase connection, DeviceNotification notification, Device device)
        {
            var user = (User) connection.Session["user"];
            if (user == null || !IsNetworkAccessible(device.NetworkID, user))
                return;

            connection.SendResponse("notification/insert",
                new JProperty("deviceGuid", device.GUID),
                new JProperty("notification", NotificationMapper.Map(notification)));
        }