public async Task <JsonResult> SearchDevicesHistoryByPage(string deviceId = null, int batchIndex = 1, int batchSize = 200, string startTimestamp = null) { // Manage session and Context HttpServiceUriBuilder contextUri = new HttpServiceUriBuilder().SetServiceName(this.context.ServiceName); DeviceEventRowList deviceMessages = new DeviceEventRowList(batchIndex, batchSize); ServiceUriBuilder uriBuilder = new ServiceUriBuilder(Names.InsightDataServiceName); Uri serviceUri = uriBuilder.Build(); // service may be partitioned. // this will aggregate the queue lengths from each partition ServicePartitionList partitions = await this.fabricClient.QueryManager.GetPartitionListAsync(serviceUri); foreach (Partition partition in partitions) { string pathAndQuery = $"/api/devices/history/batchIndex/{batchIndex}/batchSize/{batchSize}"; if (startTimestamp != null) { pathAndQuery = $"/api/devices/history/batchIndex/{batchIndex}/batchSize/{batchSize}/startingAt/{startTimestamp}"; deviceMessages.SearchStartTimestamp = DateTimeOffset.Parse(startTimestamp).ToUniversalTime(); } Uri getUrl = new HttpServiceUriBuilder() .SetServiceName(serviceUri) .SetPartitionKey(((Int64RangePartitionInformation)partition.PartitionInformation).LowKey) .SetServicePathAndQuery(pathAndQuery) .Build(); HttpResponseMessage response = await httpClient.GetAsync(getUrl, appLifetime.ApplicationStopping); if (response.StatusCode == System.Net.HttpStatusCode.OK) { JsonSerializer serializer = new JsonSerializer(); using (StreamReader streamReader = new StreamReader(await response.Content.ReadAsStreamAsync())) { using (JsonTextReader jsonReader = new JsonTextReader(streamReader)) { DeviceEventRowList resultDeviceEventRowList = serializer.Deserialize <DeviceEventRowList>(jsonReader); foreach (DeviceEventRow row in resultDeviceEventRowList.Rows) { deviceMessages.AddRow(row); } deviceMessages.TotalCount += resultDeviceEventRowList.TotalCount; if (deviceMessages.SearchStartTimestamp.ToUnixTimeMilliseconds() < 1000) { deviceMessages.SearchStartTimestamp = resultDeviceEventRowList.SearchStartTimestamp; } } } } } return(this.Json(deviceMessages)); }
public async Task <JsonResult> SearchDevicesHistoryByPage(string deviceId = null, int batchIndex = 1, int batchSize = 200, string startTimestamp = null) { DeviceEventRowList deviceMessages = new DeviceEventRowList(batchIndex, batchSize); IReliableDictionary <DateTimeOffset, DeviceEventSeries> storeCompletedMessages = storeCompletedMessages = await this.stateManager.GetOrAddAsync <IReliableDictionary <DateTimeOffset, DeviceEventSeries> >(TargetSolution.Names.EventHistoryDictionaryName); DateTimeOffset searchStartTimestamp = DateTimeOffset.Parse("1970-01-01T00:00:00.000Z"); bool searchStartTimestampUpdateFlag = true; if (storeCompletedMessages != null) { long totalCount = await GetQueueLengthAsyncInternal(); using (ITransaction tx = this.stateManager.CreateTransaction()) { if (totalCount > 0) { bool useIndexForTotalCount = false; IAsyncEnumerable <KeyValuePair <DateTimeOffset, DeviceEventSeries> > enumerable = null; IAsyncEnumerator <KeyValuePair <DateTimeOffset, DeviceEventSeries> > enumerator = null; if (startTimestamp == null) { enumerable = await storeCompletedMessages.CreateEnumerableAsync(tx, EnumerationMode.Ordered); } else { searchStartTimestamp = DateTimeOffset.Parse(startTimestamp).ToUniversalTime(); enumerable = await storeCompletedMessages.CreateEnumerableAsync(tx, EnumerationMode.Ordered); enumerator = enumerable.GetAsyncEnumerator(); await enumerator.MoveNextAsync(appLifetime.ApplicationStopping); if (enumerator.Current.Key.CompareTo(searchStartTimestamp) < 0) { useIndexForTotalCount = true; enumerable = await storeCompletedMessages.CreateEnumerableAsync(tx, key => key.CompareTo(searchStartTimestamp) >= 0, EnumerationMode.Ordered); } else { enumerable = await storeCompletedMessages.CreateEnumerableAsync(tx, EnumerationMode.Ordered); } } enumerator = enumerable.GetAsyncEnumerator(); int indexStart = batchIndex; if (indexStart < 0) { indexStart = 0; } else if (indexStart > 0) { indexStart--; } indexStart = indexStart * batchSize; int indexEnd = indexStart + batchSize; if (!useIndexForTotalCount) { totalCount -= indexStart; } int index = 1; while (await enumerator.MoveNextAsync(appLifetime.ApplicationStopping)) { if (searchStartTimestampUpdateFlag) { searchStartTimestamp = enumerator.Current.Key; searchStartTimestampUpdateFlag = false; } if (deviceId == null || deviceId == enumerator.Current.Value.DeviceId) { if (index > indexStart && index <= indexEnd) { foreach (DeviceEvent evnt in enumerator.Current.Value.Events) { deviceMessages.AddRow(new DeviceEventRow(enumerator.Current.Key, evnt.Timestamp, enumerator.Current.Value.DeviceId, evnt.MeasurementType, evnt.SensorIndex, evnt.TempExternal, evnt.TempInternal, evnt.BatteryLevel, evnt.DataPointsCount)); break; } } if (index == indexEnd & !useIndexForTotalCount) { break; } index++; } } if (useIndexForTotalCount) { totalCount = (long)index; } } await tx.CommitAsync(); deviceMessages.TotalCount = totalCount; deviceMessages.SearchStartTimestamp = searchStartTimestamp; ServiceEventSource.Current.ServiceMessage(this.context, $"DataService - SearchDevicesHistoryByPage - Count of[{deviceMessages.TotalCount}] for data range from [{startTimestamp}] - device [{deviceId ?? "All"}]"); } } return(this.Json(deviceMessages)); }