This repository has been archived by the owner on Sep 4, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathTimeSeriesQuickstartEndPoint.cs
242 lines (213 loc) · 10.4 KB
/
TimeSeriesQuickstartEndPoint.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
using HistoricalDataFetcher.Classes.Endpoints;
using HistoricalDataFetcher.Classes.Models.Collection;
using HistoricalDataFetcher.Classes.Models.Collection.TimeSeries;
using HistoricalDataFetcher.Classes.Services;
using HistoricalDataFetcher.Classes.Utilities;
using HistoricalDataFetcher.DataStorage.Interfaces;
using HistoricalDataFetcher.DataStorage.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace HistoricalDataFetcher.QuickExtract
{
class TimeSeriesQuickstartEndPoint : TimeSeriesEndPoint
{
public TimeSeriesQuickstartEndPoint(IDataStore<SamplesDataStoreModel> dataStore) : base(dataStore)
{
}
/// <summary>
/// Async call to run the selected URL as a task
/// </summary>
/// <param name="taskUrl">Complete URL for the Network Devices</param>
/// <returns>bool: True = complete</returns>
public new async Task<bool> RunAsync(string taskUrl)
{
_sampleData = new List<SamplesDataStoreModel>();
_url = taskUrl;
var pointCollection = new List<PointBatchCollectionItem>();
var availableSampleList = new List<AvailableSampleCollectionItem>();
var rawSampleList = new List<SampleCollectionItem>();
var networkDeviceCollection = new List<NetworkDeviceCollectionItem>();
try
{
networkDeviceCollection.AddRange(await BuildNetworkDeviceCollectionAsync(taskUrl));
pointCollection.AddRange(await BuildPointCollectionAsync(networkDeviceCollection));
availableSampleList.AddRange(await BuildAvailableSamplesListAsync(pointCollection));
rawSampleList.AddRange(await BuildRawSamplesListAsync(availableSampleList));
_sampleData.AddRange(BuildSampleDataCollection(rawSampleList));
}
catch (Exception)
{
return false;
}
await SaveDataAsync(_sampleData, pointCollection);
return true;
}
/// <summary>
/// Save data by combining Samples and Points into a single set
/// </summary>
/// <param name="samples">List of samples</param>
/// <param name="points">List of points</param>
/// <returns></returns>
public async Task SaveDataAsync(List<SamplesDataStoreModel> samples, List<PointBatchCollectionItem> points)
{
var result = (
from sample in samples
join point in points on sample.PointGuid.ToString() equals point.Id
select new SamplesDataStoreModel
{
IsReliable = sample.IsReliable,
TimeStamp = sample.TimeStamp,
Units = sample.Units,
Value = sample.Value,
PointGuid = sample.PointGuid,
PointName = point.Name,
ItemReference = point.ItemReference,
PointType = EnumSetService.Instance.GetEnumMemberDescription(point.Type)
}
).ToList();
await _dataStore.SetDataAsync(result);
}
/// <summary>
/// Build a list of available network devices
/// </summary>
/// <param name="url">Complete URL for the network device location</param>
/// <returns>IEnumberable of NetworkDeviceCollectionItem </returns>
private async Task<IEnumerable<NetworkDeviceCollectionItem>> BuildNetworkDeviceCollectionAsync(string url)
{
IEnumerable<NetworkDeviceCollectionItem> networkDevices;
_stopWatch.Start();
try
{
networkDevices = await GetSinglePageAsync<NetworkDeviceCollectionItem>(url);
LoggerService.LogApiRequest(url, networkDevices.Count(), TimeSpan.FromMilliseconds(_stopWatch.Elapsed.TotalMilliseconds).ToString());
}
catch (Exception ex)
{
LoggerService.LogException(url, TimeSpan.FromMilliseconds(_stopWatch.Elapsed.TotalMilliseconds).ToString(), ex);
networkDevices = new List<NetworkDeviceCollectionItem>();
}
_stopWatch.Stop();
_stopWatch.Reset();
return networkDevices;
}
/// <summary>
/// Build a list of child objects based on the list of Network Devices passed in
/// </summary>
/// <param name="networkDeviceCollection">List of Network devices</param>
/// <returns>IEnumberable of PointBatchCollectionItem</returns>
private async Task<IEnumerable<PointBatchCollectionItem>> BuildPointCollectionAsync(IEnumerable<NetworkDeviceCollectionItem> networkDeviceCollection)
{
var pointCollection = new List<PointBatchCollectionItem>();
foreach (var device in networkDeviceCollection)
{
string url = $"{ApiRequest.UrlBase}{device.Objects}?pageSize=200";
_stopWatch.Start();
try
{
var points = await GetSinglePageAsync<PointBatchCollectionItem>(url);
pointCollection.AddRange(points);
LoggerService.LogApiRequest(url, points.Count, TimeSpan.FromMilliseconds(_stopWatch.Elapsed.TotalMilliseconds).ToString());
}
catch (Exception ex)
{
LoggerService.LogException(url, TimeSpan.FromMilliseconds(_stopWatch.Elapsed.TotalMilliseconds).ToString(), ex);
}
_stopWatch.Stop();
_stopWatch.Reset();
}
return pointCollection;
}
/// <summary>
/// Build a list of available samples based on the attributes being used
/// </summary>
/// <param name="pointCollection">List of points to grab an available sample list from</param>
/// <returns>IEnumerable of AvailableSampleCollectionItem</returns>
private async Task<IEnumerable<AvailableSampleCollectionItem>> BuildAvailableSamplesListAsync(IEnumerable<PointBatchCollectionItem> pointCollection)
{
var availablePointSamples = new List<AvailableSampleCollectionItem>();
var url = string.Empty;
foreach (var pointItem in pointCollection)
{
_stopWatch.Start();
try
{
url = $"{ApiRequest.UrlBase}{pointItem.Attributes}?pageSize=200";
var availableSamples = (await GetSinglePageAsync<AvailableSampleCollectionItem>(url)).ToList();
LoggerService.LogApiRequest(url, availableSamples.Count, TimeSpan.FromMilliseconds(_stopWatch.Elapsed.TotalMilliseconds).ToString());
availableSamples.ForEach(x => x.Point = pointItem);
availablePointSamples.AddRange(availableSamples);
}
catch (Exception ex)
{
LoggerService.LogException(url, TimeSpan.FromMilliseconds(_stopWatch.Elapsed.TotalMilliseconds).ToString(), ex);
}
_stopWatch.Stop();
_stopWatch.Reset();
}
return availablePointSamples;
}
/// <summary>
/// Build a complete list of all samples within the attributes selected
/// </summary>
/// <param name="availablePointSamples">List of available point samples</param>
/// <returns>IEnumberable of SampleCollectionItem</returns>
private async Task<IEnumerable<SampleCollectionItem>> BuildRawSamplesListAsync(IEnumerable<AvailableSampleCollectionItem> availablePointSamples)
{
var pointSamples = new List<SampleCollectionItem>();
foreach (var availableSample in availablePointSamples)
{
_stopWatch.Start();
var samplesUrl = availableSample.Samples.Split("?")[0];
samplesUrl = $"{ApiRequest.UrlBase}{samplesUrl}?startTime={DateTime.Now.AddDays(-1)}&endTime={DateTime.Now}&page=1&pageSize=1000&sort=timestamp";
try
{
var samples = (await GetSinglePageAsync<SampleCollectionItem>(samplesUrl)).ToList();
LoggerService.LogApiRequest(samplesUrl, samples.Count, TimeSpan.FromMilliseconds(_stopWatch.Elapsed.TotalMilliseconds).ToString());
samples.ForEach(x => x.Point = availableSample.Point);
pointSamples.AddRange(samples);
}
catch (Exception ex)
{
LoggerService.LogException(samplesUrl, TimeSpan.FromMilliseconds(_stopWatch.Elapsed.TotalMilliseconds).ToString(), ex);
}
_stopWatch.Stop();
_stopWatch.Reset();
}
return pointSamples;
}
/// <summary>
/// Format the raw samples into a format ready to save
/// </summary>
/// <param name="pointSamplesList">The raw sample list</param>
/// <returns>IEnumberable of SamplesDataStoreModel</returns>
private IEnumerable<SamplesDataStoreModel> BuildSampleDataCollection(IEnumerable<SampleCollectionItem> pointSamplesList)
{
return pointSamplesList.Select(sample => new SamplesDataStoreModel
{
PointName = sample.Point.Name,
PointGuid = new Guid(sample.Point.Id),
ItemReference = sample.Point.ItemReference,
IsReliable = sample.IsReliable,
TimeStamp = sample.Timestamp,
Units = GetEnumSetInformation(sample.Value.Units),
Value = sample.Value.Value
}).ToList();
}
/// <summary>
/// Makes a single API call and does not loop through all the available pages
/// </summary>
/// <typeparam name="T">Expected item returned from the API call</typeparam>
/// <param name="startUrl">The URL to call</param>
/// <returns>ICollection of "T"</returns>
private async Task<ICollection<T>> GetSinglePageAsync<T>(string startUrl)
{
var collection = new List<T>();
string nextUrl = startUrl;
var points = await GetCollectionAsync<T>(nextUrl);
collection.AddRange(points.Items);
return collection;
}
}
}