Exemple #1
0
        private CollectorRecord CreateRecordList(string macAddress, string websiteName, int sessionCount, int recordCount)
        {
            var now    = DateTime.Now;
            var record = new CollectorRecord()
            {
                DeviceId   = macAddress,
                DeviceName = macAddress,
                UserId     = macAddress,
                RecordList = new List <SiteLookupRecord>()
            };

            int sessionBreak        = recordCount / sessionCount;
            int runningSessionCount = 1;

            for (int i = 1; i <= recordCount; i++)
            {
                record.RecordList.Add(new SiteLookupRecord()
                {
                    WebsiteName = websiteName,
                    Timestamp   = now.ToString("s"),
                    Duration    = 0
                });
                if (i % sessionBreak == 0 && runningSessionCount < sessionCount)
                {
                    now += TimeSpan.FromMinutes(10.0);
                    runningSessionCount++;
                }
                else
                {
                    now += TimeSpan.FromMinutes(2.0);
                }
            }
            return(record);
        }
Exemple #2
0
        const int SessionThreshold = 300;  // sessions elapse after 5 minutes

        public static List <WebSession> ProcessRecords(SiteMapRepository siteMapRepository, List <WebSession> dbSessions, CollectorRecord collectorRecord)
        {
            // working sessions list
            var sessions = new List <WebSession>();

            // set of WebSession references that have been modified or added
            var resultSessions = new List <WebSession>();
            var recordList     = collectorRecord.RecordList.OrderBy(r => r.Timestamp).ToList();

            // terminate all sessions that aren't "in progress"
            var firstRecord = recordList.First();
            var timestamp   = Convert.ToDateTime(firstRecord.Timestamp);

            if (dbSessions != null && dbSessions.Count() > 0)
            {
                foreach (var s in dbSessions)
                {
                    var sessionStart = Convert.ToDateTime(s.Start);
                    if (s.InProgress == true && timestamp > sessionStart + TimeSpan.FromSeconds(SessionThreshold))
                    {
                        // session is no longer in progress - mark it for update
                        s.InProgress = false;
                        resultSessions.Add(s);
                    }
                    else
                    {
                        // add it to the working session list
                        sessions.Add(s);
                    }
                }
            }

            foreach (var record in recordList)
            {
                // get the sitemap for this site and skip if the site is suppressed
                var siteMap = siteMapRepository.GetSiteMapping(record.WebsiteName);
                if (siteMap == null)
                {
                    continue;
                }

                // find an in-progress session
                var session = sessions.LastOrDefault(s =>
                                                     s.Device.DeviceId == collectorRecord.DeviceId &&
                                                     s.Site == siteMap.Site &&
                                                     s.InProgress == true);
                if (session == null)
                {
                    var newSession = new WebSession()
                    {
                        UserId   = collectorRecord.UserId,
                        DeviceId = collectorRecord.DeviceId,
                        Device   = new Device()
                        {
                            DeviceId = collectorRecord.DeviceId, Hostname = collectorRecord.DeviceName, UserId = collectorRecord.UserId
                        },
                        Site       = siteMap.Site,
                        Category   = siteMap.Category,
                        Start      = record.Timestamp,
                        Duration   = record.Duration,
                        InProgress = true
                    };
                    sessions.Add(newSession);
                    resultSessions.Add(newSession);
                }
                else
                {
                    var recordTimestamp = Convert.ToDateTime(record.Timestamp);
                    var sessionStart    = Convert.ToDateTime(session.Start);
                    var sessionCurrent  = sessionStart + TimeSpan.FromSeconds(session.Duration);

                    // is this a new session?
                    if (recordTimestamp > sessionCurrent + TimeSpan.FromSeconds(SessionThreshold))
                    {
                        // terminate the current session and add it to the result session list
                        session.InProgress = false;
                        if (!resultSessions.Contains(session))
                        {
                            resultSessions.Add(session);
                        }

                        // create a new session
                        var newSession = new WebSession()
                        {
                            UserId   = collectorRecord.UserId,
                            DeviceId = collectorRecord.DeviceId,
                            Device   = new Device()
                            {
                                DeviceId = collectorRecord.DeviceId, Hostname = collectorRecord.DeviceName, UserId = collectorRecord.UserId
                            },
                            Site       = siteMap.Site,
                            Category   = siteMap.Category,
                            Start      = record.Timestamp,
                            Duration   = record.Duration,
                            InProgress = true
                        };
                        sessions.Add(newSession);
                        resultSessions.Add(newSession);
                    }
                    else
                    {
                        // extend the session
                        int duration = 0;
                        if (recordTimestamp < sessionStart)
                        {
                            // handle the case where the current record somehow predates the existing session
                            session.Start = record.Timestamp;
                            sessionStart  = recordTimestamp;
                            duration      = session.Duration > record.Duration ? session.Duration : record.Duration;
                        }
                        else
                        {
                            // normal processing - just calculate the delta between the new record timestamp and the session start, and add the duration
                            // also ensure that the resulting duration isn't smaller than the existing session duration
                            var delta = (int)(recordTimestamp - sessionStart).TotalSeconds + record.Duration;
                            duration = delta > session.Duration ? delta : session.Duration;
                        }
                        session.Duration = duration;

                        // add it to the result session list if not there already
                        if (!resultSessions.Contains(session))
                        {
                            resultSessions.Add(session);
                        }
                    }
                }
            }

            return(resultSessions);
        }
        // POST colapi/collector
        public ServiceResponse Post(HttpRequestMessage req, JToken value)
        {
            //BUGBUG - need to do something about CSRF

            try
            {
                var controlMessage = ControlMessage.Normal;

                var obj    = value as JObject;
                var record = new CollectorRecord()
                {
                    DeviceId   = (string)obj[CollectorFields.DeviceId],
                    DeviceName = (string)obj[CollectorFields.DeviceName],
                    UserId     = CollectorRepository.UserId,
                    State      = RecordState.New,
                    RecordList = new List <SiteLookupRecord>()
                };

                // reject messages from a null device ID or UserID
                if (string.IsNullOrEmpty(record.DeviceId) || string.IsNullOrEmpty(record.UserId))
                {
                    TraceLog.TraceError(string.Format("Rejecting invalid record: {0}", obj.ToString()));
                    return(new ServiceResponse()
                    {
                        ControlMessage = controlMessage, RecordsProcessed = -1
                    });
                }

                // store device software version and timestamp (if this isn't a new device)
                var device = UserDataRepository.Devices.FirstOrDefault(d => d.DeviceId == record.DeviceId);
                if (device != null)
                {
                    // this device is marked for deletion
                    if (device.Enabled == null)
                    {
                        TraceLog.TraceInfo(string.Format("Deleting suspended device {0} for user {1}", device.Name, device.UserId));
                        UserDataRepository.DeleteDevice(device);
                        return(new ServiceResponse()
                        {
                            ControlMessage = ControlMessage.DisableDevice, RecordsProcessed = 0
                        });
                    }

                    // tell the client to suspend collection if the device was disabled by the user
                    if (!device.Enabled.Value)
                    {
                        controlMessage = ControlMessage.SuspendCollection;
                    }

                    if (obj[CollectorFields.SoftwareVersion] != null)
                    {
                        device.SoftwareVersion = (string)obj[CollectorFields.SoftwareVersion];
                    }
                    device.Timestamp = DateTime.UtcNow;
                    UserDataRepository.SaveChanges();
                }

                var array = obj[CollectorFields.Records] as JArray;
                if (array != null && array.Count > 0)
                {
                    // extract each object out of the array and create a SiteLookupRecord for each
                    foreach (JObject r in array)
                    {
                        int duration = r["Duration"] != null ? (int)r["Duration"] : 0;
                        record.RecordList.Add(new SiteLookupRecord()
                        {
                            WebsiteName = (string)r["WebsiteName"],
                            Timestamp   = ((DateTime)r["Timestamp"]).ToString("s"),
                            Duration    = duration,
                        });
                    }

                    // add all records at once
                    CollectorRepository.AddRecord(record);

                    TraceLog.TraceInfo(string.Format("Added {0} records for user {1}", record.RecordList.Count, CollectorRepository.UserId));
                }

                var response = new ServiceResponse()
                {
                    RecordsProcessed = array != null ? array.Count : 0,
                    ControlMessage   = controlMessage
                };

                return(response);
            }
            catch (Exception ex)
            {
                TraceLog.TraceException("Collector Post failed", ex);
                throw;
            }
        }