Exemple #1
0
        public void SubsrcibeToDeviceNotifications(DateTime?timestamp, string[] deviceGuids = null, string[] names = null)
        {
            var subscriptionId = Guid.NewGuid();
            var devices        = GetDevices(deviceGuids, "GetDeviceNotification");
            var deviceIds      = devices == null ? null : devices.Select(d => d.ID).ToArray();

            var initialNotificationList = GetInitialNotificationList(Connection, subscriptionId);

            lock (initialNotificationList)
            {
                _deviceSubscriptionManagerForNotifications.Subscribe(subscriptionId, Connection, deviceIds, names);
                SendResponse(new JProperty("subscriptionId", subscriptionId));

                if (timestamp != null)
                {
                    var filter = new DeviceNotificationFilter {
                        Start = timestamp, IsDateInclusive = false, Notifications = names
                    };
                    var initialNotifications = DataContext.DeviceNotification.GetByDevices(deviceIds, filter)
                                               .Where(n => IsDeviceAccessible(n.Device, "GetDeviceNotification")).ToArray();

                    foreach (var notification in initialNotifications)
                    {
                        initialNotificationList.Add(notification.ID);
                        Notify(Connection, subscriptionId, notification, notification.Device, isInitialNotification: true);
                    }
                }
            }
        }
Exemple #2
0
        public List <DeviceNotification> GetByDevices(int[] deviceIds, DeviceNotificationFilter filter = null)
        {
            List <DeviceNotification> notifications = null;

            if (filter != null && filter.GridInterval != null)
            {
                // use native MongoDB query for aggregation
                notifications = QueryWithGridInterval(deviceIds, filter);
            }
            else
            {
                var query = _mongo.DeviceNotifications.AsQueryable();
                if (deviceIds != null)
                {
                    query = query.Where(e => deviceIds.Contains(e.DeviceID));
                }
                notifications = query.Filter(filter).ToList();
            }

            if (notifications.Any())
            {
                var actualDeviceIds = notifications.Select(e => e.DeviceID).Distinct().ToArray();
                var deviceLookup    = _mongo.Devices.Find(Query <Device> .In(e => e.ID, actualDeviceIds)).ToDictionary(e => e.ID);

                foreach (var notification in notifications)
                {
                    notification.Device = deviceLookup[notification.DeviceID];
                }
            }

            return(notifications);
        }
Exemple #3
0
 public List <DeviceNotification> GetByDevice(int deviceId, DeviceNotificationFilter filter = null)
 {
     using (var context = new DeviceHiveContext())
     {
         var query = context.DeviceNotifications.Where(e => e.Device.ID == deviceId);
         return(query.Filter(filter, FilterByGridInterval(filter == null ? null : filter.GridInterval)).ToList());
     }
 }
Exemple #4
0
        public List <DeviceNotification> GetByDevice(int deviceId, DeviceNotificationFilter filter = null)
        {
            if (filter != null && filter.GridInterval != null)
            {
                // use native MongoDB query for aggregation
                return(QueryWithGridInterval(new[] { deviceId }, filter));
            }

            return(_mongo.DeviceNotifications.AsQueryable().Where(e => e.DeviceID == deviceId).Filter(filter).ToList());
        }
Exemple #5
0
 public List <DeviceNotification> GetByDevices(int[] deviceIds, DeviceNotificationFilter filter = null)
 {
     using (var context = new DeviceHiveContext())
     {
         var query = context.DeviceNotifications.Include(e => e.Device);
         if (deviceIds != null)
         {
             query = query.Where(e => deviceIds.Contains(e.Device.ID));
         }
         return(query.Filter(filter, FilterByGridInterval(filter == null ? null : filter.GridInterval)).ToList());
     }
 }
        public async Task <JArray> GetMany(string deviceGuids = null, DateTime?timestamp = null, string names = null, int?waitTimeout = null)
        {
            var deviceIds = deviceGuids == null ? null : ParseDeviceGuids(deviceGuids).Select(d => d.ID).ToArray();

            var start             = timestamp ?? _timestampRepository.GetCurrentTimestamp();
            var notificationNames = names != null?names.Split(',') : null;

            if (waitTimeout <= 0)
            {
                var filter = new DeviceNotificationFilter {
                    Start = start, IsDateInclusive = false, Notifications = notificationNames
                };
                var notifications = DataContext.DeviceNotification.GetByDevices(deviceIds, filter);
                return(MapDeviceNotifications(notifications.Where(n => IsDeviceAccessible(n.Device))));
            }

            var config    = DeviceHiveConfiguration.RestEndpoint;
            var delayTask = Task.Delay(1000 * Math.Min(config.NotificationPollMaxInterval, waitTimeout ?? config.NotificationPollDefaultInterval));

            using (var waiterHandle = _notificationByDeviceIdWaiter.BeginWait(
                       deviceIds == null ? new object[] { null } : deviceIds.Cast <object>().ToArray(),
                       notificationNames == null ? null : notificationNames.Cast <object>().ToArray()))
            {
                do
                {
                    var filter = new DeviceNotificationFilter {
                        Start = start, IsDateInclusive = false, Notifications = notificationNames
                    };
                    var notifications = DataContext.DeviceNotification.GetByDevices(deviceIds, filter)
                                        .Where(n => IsDeviceAccessible(n.Device)).ToArray();
                    if (notifications != null && notifications.Any())
                    {
                        return(MapDeviceNotifications(notifications));
                    }
                }while (await Task.WhenAny(waiterHandle.Wait(), delayTask) != delayTask);
            }

            return(new JArray());
        }
Exemple #7
0
        public static IQueryable <DeviceNotification> Filter(this IQueryable <DeviceNotification> query, DeviceNotificationFilter filter,
                                                             Func <IQueryable <DeviceNotification>, IQueryable <DeviceNotification> > additionalFilter = null)
        {
            if (filter == null)
            {
                return(query);
            }

            if (filter.Start != null)
            {
                var start = DateTime.SpecifyKind(filter.Start.Value, DateTimeKind.Utc);
                if (!filter.IsDateInclusive)
                {
                    start = start.AddTicks(10); // SQL Server has 7-digit precision, while JSON mapping 6-digit
                }
                query = filter.IsDateInclusive ? query.Where(e => e.Timestamp >= start) : query.Where(e => e.Timestamp > start);
            }

            if (filter.End != null)
            {
                var end = DateTime.SpecifyKind(filter.End.Value, DateTimeKind.Utc);
                if (!filter.IsDateInclusive)
                {
                    end = end.AddTicks(-10); // SQL Server has 7-digit precision, while JSON mapping 6-digit
                }
                query = filter.IsDateInclusive ? query.Where(e => e.Timestamp <= end) : query.Where(e => e.Timestamp < end);
            }

            if (filter.Notification != null)
            {
                query = query.Where(e => e.Notification == filter.Notification);
            }

            if (filter.Notifications != null)
            {
                query = query.Where(e => filter.Notifications.Contains(e.Notification));
            }

            if (additionalFilter != null)
            {
                query = additionalFilter(query);
            }

            if (filter.SortField != DeviceNotificationSortField.None)
            {
                switch (filter.SortField)
                {
                case DeviceNotificationSortField.Timestamp:
                    query = query.OrderBy(e => e.Timestamp, filter.SortOrder);
                    break;

                case DeviceNotificationSortField.Notification:
                    query = query.OrderBy(e => e.Notification, filter.SortOrder)
                            .ThenBy(e => e.Timestamp, filter.SortOrder);
                    break;
                }
            }

            if (filter.Skip != null)
            {
                query = query.Skip(filter.Skip.Value);
            }

            if (filter.Take != null)
            {
                query = query.Take(filter.Take.Value);
            }

            return(query);
        }
Exemple #8
0
        private List <DeviceNotification> QueryWithGridInterval(int[] deviceIds, DeviceNotificationFilter filter)
        {
            if (filter == null)
            {
                throw new ArgumentNullException("filter");
            }
            if (filter.GridInterval == null)
            {
                throw new ArgumentException("GridInterval property of the filter is null!", "filter.GridInterval");
            }

            var periodStart        = DateTime.SpecifyKind(new DateTime(2000, 1, 1), DateTimeKind.Utc);
            var periodMilliseconds = periodStart.Ticks / 10000;

            // prepare a list of operations for aggregation query
            var operations = new List <BsonDocument>();

            // match by devices
            if (deviceIds != null)
            {
                operations.Add(new BsonDocument {
                    { "$match", new BsonDocument {
                          { "DeviceID",
                                                          new BsonDocument {
                                                              { "$in", new BsonArray(deviceIds) }
                                                          } }
                      } }
                });
            }

            // match by filter criteria
            if (filter.Start != null)
            {
                operations.Add(new BsonDocument {
                    { "$match", new BsonDocument {
                          { "Timestamp",
                                                          new BsonDocument {
                                                              { filter.IsDateInclusive ? "$gte" : "$gt", filter.Start.Value }
                                                          } }
                      } }
                });
            }
            if (filter.End != null)
            {
                operations.Add(new BsonDocument {
                    { "$match", new BsonDocument {
                          { "Timestamp",
                                                          new BsonDocument {
                                                              { filter.IsDateInclusive ? "$lte" : "$lt", filter.End.Value }
                                                          } }
                      } }
                });
            }
            if (filter.Notification != null)
            {
                operations.Add(new BsonDocument {
                    { "$match", new BsonDocument {
                          { "Notification", filter.Notification }
                      } }
                });
            }
            if (filter.Notifications != null)
            {
                operations.Add(new BsonDocument {
                    { "$match", new BsonDocument {
                          { "Notification",
                                                          new BsonDocument {
                                                              { "$in", new BsonArray(filter.Notifications) }
                                                          } }
                      } }
                });
            }

            // process grid interval aggregation
            operations.Add(new BsonDocument {
                { "$sort", new BsonDocument {
                      { "Timestamp", 1 }
                  } }
            });
            operations.Add(new BsonDocument {
                { "$project", new BsonDocument {
                      { "DeviceID", 1 }, { "Timestamp", 1 }, { "Notification", 1 }, { "Parameters", 1 },
                      { "tsmod", new BsonDocument {
                                                          { "$mod", new BsonArray {
                            new BsonDocument {
                                { "$add", new BsonArray {
                                                              new BsonDocument {
                                                                  { "$subtract", new BsonArray {
                                                       "$Timestamp", periodStart
                                                   } }
                                                              }, periodMilliseconds
                                                          } }
                            },
                            new BsonInt64(1000 * filter.GridInterval.Value)
                        } }
                                                      } }
                  } }
            });
            operations.Add(new BsonDocument {
                { "$project", new BsonDocument {
                      { "DeviceID", 1 }, { "Timestamp", 1 }, { "Notification", 1 }, { "Parameters", 1 },
                      { "tsinterval", new BsonDocument {
                                                          { "$subtract", new BsonArray {
                            new BsonDocument {
                                { "$add", new BsonArray {
                                                                   new BsonDocument {
                                                                       { "$subtract", new BsonArray {
                                                       "$Timestamp", periodStart
                                                   } }
                                                                   }, periodMilliseconds
                                                               } }
                            },
                            new BsonString("$tsmod")
                        } }
                                                      } }
                  } }
            });
            operations.Add(new BsonDocument {
                { "$group", new BsonDocument {
                      { "_id", new BsonDocument {
                                                          { "tsinterval", "$tsinterval" }, { "DeviceID", "$DeviceID" }, { "Notification", "$Notification" }
                                                      } },
                      { "ID", new BsonDocument {
                                                          { "$first", "$_id" }
                                                      } },
                      { "Timestamp", new BsonDocument {
                                                          { "$first", "$Timestamp" }
                                                      } },
                      { "DeviceID", new BsonDocument {
                                                          { "$first", "$DeviceID" }
                                                      } },
                      { "Notification", new BsonDocument {
                                                          { "$first", "$Notification" }
                                                      } },
                      { "Parameters", new BsonDocument {
                                                          { "$first", "$Parameters" }
                                                      } }
                  } }
            });
            operations.Add(new BsonDocument {
                { "$project", new BsonDocument {
                      { "_id", "$ID" }, { "DeviceID", 1 }, { "Timestamp", 1 }, { "Notification", 1 }, { "Parameters", 1 }
                  } }
            });

            // apply sorting and pagination
            if (filter.SortField != DeviceNotificationSortField.None)
            {
                var sortOrder = filter.SortOrder == SortOrder.ASC ? 1 : -1;
                switch (filter.SortField)
                {
                case DeviceNotificationSortField.Timestamp:
                    operations.Add(new BsonDocument {
                        { "$sort", new BsonDocument {
                              { "Timestamp", sortOrder }
                          } }
                    });
                    break;

                case DeviceNotificationSortField.Notification:
                    operations.Add(new BsonDocument {
                        { "$sort", new BsonDocument {
                              { "Notification", sortOrder }, { "Timestamp", sortOrder }
                          } }
                    });
                    break;
                }
            }
            if (filter.Skip != null)
            {
                operations.Add(new BsonDocument {
                    { "$skip", filter.Skip.Value }
                });
            }
            if (filter.Take != null)
            {
                operations.Add(new BsonDocument {
                    { "$limit", filter.Take.Value }
                });
            }

            // run the aggregation query
            var result = _mongo.DeviceNotifications.Aggregate(new AggregateArgs {
                Pipeline = operations
            });

            return(result.Select(BsonSerializer.Deserialize <DeviceNotification>).ToList());
        }