private static async Task WriteDataToStream(AggregateData data, SdsStream stream) { using (HttpClient httpClient = new HttpClient()) { List <AggregateData> dataList = new List <AggregateData>(); dataList.Add(data); Console.WriteLine("Writing Data to " + stream.Id + " stream"); StringContent serializedData = new StringContent(JsonSerializer.Serialize(dataList)); HttpResponseMessage responseWriteDataToStream = await httpClient.PostAsync($"http://localhost:{port}/api/{apiVersion}/Tenants/{tenantId}/Namespaces/{namespaceId}/Streams/{stream.Id}/Data", serializedData); CheckIfResponseWasSuccessful(responseWriteDataToStream); } }
private static async Task AsyncWriteDataToStreamAsync(AggregateData data, SdsStream stream) { var dataList = new List <AggregateData> { data, }; Console.WriteLine("Writing Data to " + stream.Id + " stream"); using var serializedData = new StringContent(JsonSerializer.Serialize(dataList)); var requestUri = new Uri($"http://localhost:{_port}/api/v1/Tenants/{_tenantId}/Namespaces/{_namespaceId}/Streams/{stream.Id}/Data"); var responseWriteDataToStream = await _httpClient.PostAsync(requestUri, serializedData).ConfigureAwait(false); CheckIfResponseWasSuccessful(responseWriteDataToStream); }
public static async Task <bool> MainAsync(bool test = false) { Console.WriteLine("Getting configuration from appsettings.json"); IConfigurationBuilder builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .AddJsonFile("appsettings.test.json", optional: true); IConfiguration configuration = builder.Build(); // ==== Client constants ==== port = configuration["EDSPort"]; tenantId = configuration["TenantId"]; namespaceId = configuration["NamespaceId"]; apiVersion = configuration["apiVersion"]; using (HttpClient httpClient = new HttpClient()) { httpClient.DefaultRequestHeaders.Add("Accept-Encoding", "gzip"); try { Console.WriteLine(); Console.WriteLine("================= Data Filtering ================="); // Step 1 - create SineWave type // create Timestamp property SdsTypeProperty timestamp = new SdsTypeProperty { Id = "Timestamp", Name = "Timestamp", IsKey = true, SdsType = new SdsType { Name = "DateTime", SdsTypeCode = 16 } }; SdsType sineWaveType = new SdsType { Id = "SineWave", Name = "SineWave", SdsTypeCode = 1, Properties = new List <SdsTypeProperty>() { timestamp, CreateSdsTypePropertyOfTypeDouble("Value", false) } }; await CreateType(sineWaveType); // Step 2 - create SineWave stream SdsStream sineWaveStream = new SdsStream { TypeId = sineWaveType.Id, Id = "SineWave", Name = "SineWave" }; await CreateStream(sineWaveStream); // Step 3 - create events with a sine wave of data ranging from -1 to 1 Console.WriteLine("Initializing Sine Wave Data Events"); List <SineData> wave = new List <SineData>(); DateTime current = new DateTime(); current = DateTime.UtcNow; int count = 20; for (int i = 0; i < count; i++) { SineData newEvent = new SineData(i); newEvent.Timestamp = current.AddSeconds(i).ToString("o"); wave.Add(newEvent); } await WriteDataToStream(wave, sineWaveStream); // Step 4 - read in the sine wave data from the SineWave stream Console.WriteLine("Ingressing Sine Wave Data"); var responseSineDataIngress = await httpClient.GetAsync($"http://localhost:{port}/api/{apiVersion}/Tenants/{tenantId}/Namespaces/{namespaceId}/Streams/{sineWaveStream.Id}/Data?startIndex={wave[0].Timestamp}&count={count}"); CheckIfResponseWasSuccessful(responseSineDataIngress); var responseBodySineData = await responseSineDataIngress.Content.ReadAsStreamAsync(); var returnData = new List <SineData>(); // since the return values are in gzip, they must be decoded if (responseSineDataIngress.Content.Headers.ContentEncoding.Contains("gzip")) { var sineDataDestination = new MemoryStream(); using (var decompressor = (Stream) new GZipStream(responseBodySineData, CompressionMode.Decompress, true)) { decompressor.CopyToAsync(sineDataDestination).Wait(); } sineDataDestination.Seek(0, SeekOrigin.Begin); var sineDataRequestContent = sineDataDestination; using (var sr = new StreamReader(sineDataRequestContent)) { returnData = await JsonSerializer.DeserializeAsync <List <SineData> >(sineDataRequestContent); } } else { Console.Write("Count must be greater than one"); } // Step 5 // create FilteredSineWaveStream SdsStream filteredSineWaveStream = new SdsStream { TypeId = sineWaveType.Id, Id = "FilteredSineWave", Name = "FilteredSineWave" }; await CreateStream(filteredSineWaveStream); // Step 6 // populate FilteredSineWaveStream List <SineData> filteredWave = new List <SineData>(); int numberOfValidValues = 0; Console.WriteLine("Filtering Data"); for (int i = 0; i < count; i++) { // filters the data to only include values outside the range -0.9 to 0.9 // change this conditional to apply the type of filter you desire if (returnData[i].Value > .9 || returnData[i].Value < -.9) { filteredWave.Add(returnData[i]); numberOfValidValues++; } } await WriteDataToStream(filteredWave, filteredSineWaveStream); // ====================== Data Aggregation portion ====================== Console.WriteLine(); Console.WriteLine("================ Data Aggregation ================"); // Step 7 - create aggregatedDataType type SdsType aggregatedDataType = new SdsType { Id = "AggregatedData", Name = "AggregatedData", SdsTypeCode = 1, Properties = new List <SdsTypeProperty>() { timestamp, CreateSdsTypePropertyOfTypeDouble("Mean", false), CreateSdsTypePropertyOfTypeDouble("Minimum", false), CreateSdsTypePropertyOfTypeDouble("Maximum", false), CreateSdsTypePropertyOfTypeDouble("Range", false) } }; await CreateType(aggregatedDataType); // Step 8 - create CalculatedAggregatedData stream SdsStream calculatedAggregatedDataStream = new SdsStream { TypeId = aggregatedDataType.Id, Id = "CalculatedAggregatedData", Name = "CalculatedAggregatedData" }; await CreateStream(calculatedAggregatedDataStream); // Step 9 - calculate mean, min, max, and range using c# libraries and send to DataAggregation Stream Console.WriteLine("Calculating mean, min, max, and range"); double mean = returnData.Average(rd => rd.Value); Console.WriteLine("Mean = " + mean); var values = new List <double>(); for (int i = 0; i < count; i++) { values.Add(returnData[i].Value); numberOfValidValues++; } var min = values.Min(); Console.WriteLine("Min = " + min); var max = values.Max(); Console.WriteLine("Max = " + max); var range = max - min; Console.WriteLine("Range = " + range); AggregateData calculatedData = new AggregateData { Timestamp = current.ToString("o"), Mean = mean, Minimum = min, Maximum = max, Range = range }; await WriteDataToStream(calculatedData, calculatedAggregatedDataStream); // Step 10 - create EdsApiAggregatedData stream SdsStream edsApiAggregatedDataStream = new SdsStream { TypeId = aggregatedDataType.Id, Id = "EdsApiAggregatedData", Name = "EdsApiAggregatedData" }; await CreateStream(edsApiAggregatedDataStream); // Step 11 - Uses EDS’s standard data aggregate API calls to ingress aggregation data calculated by EDS var edsDataAggregationIngress = await httpClient.GetAsync($"http://localhost:{port}/api/{apiVersion}/Tenants/{tenantId}/Namespaces/{namespaceId}/Streams/{sineWaveStream.Id}" + $"/Data/Summaries?startIndex={calculatedData.Timestamp}&endIndex={current.AddMinutes(count).ToString("o")}&count=1"); CheckIfResponseWasSuccessful(edsDataAggregationIngress); var responseBodyDataAggregation = await edsDataAggregationIngress.Content.ReadAsStreamAsync(); // since response is gzipped, it must be decoded var destinationAggregatedData = new MemoryStream(); using (var decompressor = (Stream) new GZipStream(responseBodyDataAggregation, CompressionMode.Decompress, true)) { decompressor.CopyToAsync(destinationAggregatedData).Wait(); } destinationAggregatedData.Seek(0, SeekOrigin.Begin); var requestContentAggregatedData = destinationAggregatedData; using (var sr = new StreamReader(requestContentAggregatedData)) { var returnDataAggregation = await JsonSerializer.DeserializeAsync <object>(requestContentAggregatedData); string stringReturn = returnDataAggregation.ToString(); // create a new aggregateData object from the api call AggregateData edsApi = new AggregateData { Timestamp = current.ToString("o"), Mean = GetValue(stringReturn, "Mean"), Minimum = GetValue(stringReturn, "Minimum"), Maximum = GetValue(stringReturn, "Maximum"), Range = GetValue(stringReturn, "Range") }; await WriteDataToStream(edsApi, edsApiAggregatedDataStream); } Console.WriteLine(); Console.WriteLine("==================== Clean-Up ====================="); // Step 12 - Delete Streams and Types await DeleteStream(sineWaveStream); await DeleteStream(filteredSineWaveStream); await DeleteStream(calculatedAggregatedDataStream); await DeleteStream(edsApiAggregatedDataStream); await DeleteType(sineWaveType); await DeleteType(aggregatedDataType); } catch (Exception e) { Console.WriteLine(e.Message); throw e; } finally { Console.WriteLine(); Console.WriteLine("Demo Application Ran Successfully!"); } } return(true); }
public static async Task <bool> MainAsync() { // ==== Client constants ==== _port = Constants.DefaultPortNumber; // defaults to 5590 _tenantId = Constants.TenantId; _namespaceId = Constants.NamespaceId; _httpClientGzip.DefaultRequestHeaders.Add("Accept-Encoding", "gzip"); try { // ====================== Data Filtering portion ====================== Console.WriteLine(); Console.WriteLine("================= Data Filtering ================="); // Step 1 - Create SineWave type var sineWaveProperties = new List <SdsTypeProperty> { CreateSdsTypePropertyOfTypeDateTime(nameof(SineData.Timestamp), true), CreateSdsTypePropertyOfTypeDouble(nameof(SineData.Value), false), }; var sineWaveType = await AsyncCreateTypeAsync(Constants.SineWaveStream, Constants.SineWaveStream, sineWaveProperties).ConfigureAwait(false); // Step 2 - Create SineWave stream var sineWaveStream = await AsyncCreateStreamAsync(sineWaveType, Constants.SineWaveStream, Constants.SineWaveStream).ConfigureAwait(false); // Step 3 - Create a list of events of SineData objects. The value property of the SineData object is intitialized to a value between -1.0 and 1.0 Console.WriteLine("Initializing SineData Events"); var waveList = new List <SineData>(); var firstTimestamp = DateTime.UtcNow; // numberOfEvents must be an integer > 1 int numberOfEvents = 100; for (int i = 0; i < numberOfEvents; i++) { waveList.Add(new SineData(i) { Timestamp = firstTimestamp.AddSeconds(i), }); } await AsyncWriteDataToStreamAsync(waveList, sineWaveStream).ConfigureAwait(false); // Step 4 - Ingress the sine wave data from the SineWave stream var returnData = await AsyncQuerySineDataAsync(sineWaveStream, waveList[0].Timestamp, numberOfEvents).ConfigureAwait(false); // Step 5 - Create FilteredSineWaveStream var filteredSineWaveStream = await AsyncCreateStreamAsync(sineWaveType, Constants.FilteredSineWaveStream, Constants.FilteredSineWaveStream).ConfigureAwait(false); // Step 6 - Populate FilteredSineWaveStream with filtered data var filteredWave = new List <SineData>(); int numberOfValidValues = 0; Console.WriteLine("Filtering Data"); for (int i = 0; i < numberOfEvents; i++) { // filters the data to only include values outside the range -0.9 to 0.9 // change this conditional to apply the type of filter you desire if (returnData[i].Value > .9 || returnData[i].Value < -.9) { filteredWave.Add(returnData[i]); numberOfValidValues++; } } await AsyncWriteDataToStreamAsync(filteredWave, filteredSineWaveStream).ConfigureAwait(false); // ====================== Data Aggregation portion ====================== Console.WriteLine(); Console.WriteLine("================ Data Aggregation ================"); // Step 7 - Create aggregatedDataType type var aggregatedData = new List <SdsTypeProperty> { CreateSdsTypePropertyOfTypeDateTime(Constants.AggregatedDataTimestampProperty, true), CreateSdsTypePropertyOfTypeDouble(Constants.AggregatedDataMeanProperty, false), CreateSdsTypePropertyOfTypeDouble(Constants.AggregatedDataMinimumProperty, false), CreateSdsTypePropertyOfTypeDouble(Constants.AggregatedDataMaximumProperty, false), CreateSdsTypePropertyOfTypeDouble(Constants.AggregatedDataRangeProperty, false), }; var aggregatedDataType = await AsyncCreateTypeAsync(Constants.AggregatedDataStream, Constants.AggregatedDataStream, aggregatedData).ConfigureAwait(false); // Step 8 - Create CalculatedAggregatedData stream var calculatedAggregatedDataStream = await AsyncCreateStreamAsync(aggregatedDataType, Constants.CalculatedAggregatedDataStream, Constants.CalculatedAggregatedDataStream).ConfigureAwait(false); // Step 9 - Calculate mean, min, max, and range using c# libraries and send to the CalculatedAggregatedData Stream Console.WriteLine("Calculating mean, min, max, and range"); var sineDataValues = new List <double>(); for (int i = 0; i < numberOfEvents; i++) { sineDataValues.Add(returnData[i].Value); numberOfValidValues++; } var calculatedData = new AggregateData { Timestamp = firstTimestamp, Mean = returnData.Average(rd => rd.Value), Minimum = sineDataValues.Min(), Maximum = sineDataValues.Max(), Range = sineDataValues.Max() - sineDataValues.Min(), }; Console.WriteLine(" Mean = " + calculatedData.Mean); Console.WriteLine(" Minimum = " + calculatedData.Minimum); Console.WriteLine(" Maximum = " + calculatedData.Maximum); Console.WriteLine(" Range = " + calculatedData.Range); await AsyncWriteDataToStreamAsync(calculatedData, calculatedAggregatedDataStream).ConfigureAwait(false); // Step 10 - Create EdsApiAggregatedData stream var edsApiAggregatedDataStream = await AsyncCreateStreamAsync(aggregatedDataType, Constants.EdsApiAggregatedDataStream, Constants.EdsApiAggregatedDataStream).ConfigureAwait(false); // Step 11 - Use EDS’s standard data aggregate API calls to ingress aggregated data calculated by EDS and send to EdsApiAggregatedData stream var summaryData = await AsyncQuerySummaryDataAsync(sineWaveStream, calculatedData.Timestamp, firstTimestamp.AddSeconds(numberOfEvents)).ConfigureAwait(false); var edsApi = new AggregateData { Timestamp = firstTimestamp, Mean = GetValue(summaryData, Constants.AggregatedDataMeanProperty), Minimum = GetValue(summaryData, Constants.AggregatedDataMinimumProperty), Maximum = GetValue(summaryData, Constants.AggregatedDataMaximumProperty), Range = GetValue(summaryData, Constants.AggregatedDataRangeProperty), }; await AsyncWriteDataToStreamAsync(edsApi, edsApiAggregatedDataStream).ConfigureAwait(false); Console.WriteLine(); Console.WriteLine("==================== Clean-Up ====================="); // Step 12 - Delete Streams and Types await AsyncDeleteStreamAsync(sineWaveStream).ConfigureAwait(false); await AsyncDeleteStreamAsync(filteredSineWaveStream).ConfigureAwait(false); await AsyncDeleteStreamAsync(calculatedAggregatedDataStream).ConfigureAwait(false); await AsyncDeleteStreamAsync(edsApiAggregatedDataStream).ConfigureAwait(false); await AsyncDeleteTypeAsync(sineWaveType).ConfigureAwait(false); await AsyncDeleteTypeAsync(aggregatedDataType).ConfigureAwait(false); } catch { _httpClient?.Dispose(); _httpClientGzip?.Dispose(); throw; } finally { _httpClient?.Dispose(); _httpClientGzip?.Dispose(); } return(true); }