public void BartIngressTest() { Program.LoadConfiguration(); // Verify timestamp is within last minute var verifyTimestamp = DateTime.UtcNow.AddMinutes(-1); // Test requires that specific stations are chosen for BartApiOrig and BartApiDest, "all" is not allowed var streamId = $"BART_{Program.Settings.BartApiOrig}_{Program.Settings.BartApiDest}"; try { Program.RunIngress(); // Wait for data to be processed by OCS Thread.Sleep(5000); // Edge Data Store and PI Web API process OMF before sending a response, and will return an error code if there is a problem // In this test, the call to RunIngress above will result in an exception if there is a failure on either of those endpoints // OCS does not validate OMF before sending a success response, so the test must check that the messages were successful using var ocsAuthenticationHandler = new AuthenticationHandler(Program.Settings.OcsUri, Program.Settings.OcsClientId, Program.Settings.OcsClientSecret); var ocsSdsService = new SdsService(Program.Settings.OcsUri, null, HttpCompressionMethod.GZip, ocsAuthenticationHandler); var ocsDataService = ocsSdsService.GetDataService(Program.Settings.OcsTenantId, Program.Settings.OcsNamespaceId); var ocsValue = ocsDataService.GetLastValueAsync <BartStationEtd>(streamId).Result; Assert.True(ocsValue.TimeStamp > verifyTimestamp); } finally { // Delete type and containers Program.Cleanup(); } }
public SDSWumpusData() { var uriResource = new Uri(resource); // Get Sds Services to communicate with server authenticationHandler = new AuthenticationHandler(uriResource, clientId, clientKey); sdsService = new SdsService(new Uri(resource), null, HttpCompressionMethod.GZip, authenticationHandler); metadataService = sdsService.GetMetadataService(tenantId, namespaceId); dataService = sdsService.GetDataService(tenantId, namespaceId); // var tableService = sdsService.GetTableService(tenantId, namespaceId); Console.WriteLine($"SDS endpoint at {resource}"); Console.WriteLine(); }
public void OpenWeatherTest() { // Verify timestamp is within last minute var verifyTimestamp = DateTime.UtcNow.AddMinutes(-10); Program.Run(null, new TestLogger()); // Stream ID below must match single city defined in OpenWeatherQueries var streamId = $"OpenWeather_Current_San Leandro"; // OCS does not validate OMF before sending a success response, so the test must check that the messages were successful using var ocsAuthenticationHandler = new AuthenticationHandler(Program.Settings.OcsUri, Program.Settings.OcsClientId, Program.Settings.OcsClientSecret); var ocsSdsService = new SdsService(Program.Settings.OcsUri, null, HttpCompressionMethod.GZip, ocsAuthenticationHandler); var ocsDataService = ocsSdsService.GetDataService(Program.Settings.OcsTenantId, Program.Settings.OcsNamespaceId); var ocsValue = ocsDataService.GetLastValueAsync <CurrentWeather>(streamId).Result; Assert.True(ocsValue.Timestamp > verifyTimestamp); }
public static async Task <bool> MainAsync(bool test = false) { ISdsMetadataService metadataService = null; #region settings var typeValueTimeName = "Value_Time"; var typePressureTemperatureTimeName = "Pressure_Temp_Time"; var streamPressureName = "Pressure_Tank1"; var streamTempName = "Temperature_Tank1"; var streamTank0 = "Vessel"; var streamTank1 = "Tank1"; var streamTank2 = "Tank2"; #endregion try { #region configurationSettings _configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .AddJsonFile("appsettings.test.json", optional: true) .Build(); var tenantId = _configuration["TenantId"]; var namespaceId = _configuration["NamespaceId"]; var resource = _configuration["Resource"]; var clientId = _configuration["ClientId"]; var clientKey = _configuration["ClientKey"]; #endregion (_configuration as ConfigurationRoot).Dispose(); var uriResource = new Uri(resource); // Step 1 // Get Sds Services to communicate with server #region step1 AuthenticationHandler authenticationHandler = new AuthenticationHandler(uriResource, clientId, clientKey); SdsService sdsService = new SdsService(new Uri(resource), authenticationHandler); metadataService = sdsService.GetMetadataService(tenantId, namespaceId); var dataService = sdsService.GetDataService(tenantId, namespaceId); var tableService = sdsService.GetTableService(tenantId, namespaceId); #endregion // Step 2 #region step2b SdsType type = SdsTypeBuilder.CreateSdsType <TimeData>(); type.Id = typeValueTimeName; type = await metadataService.GetOrCreateTypeAsync(type).ConfigureAwait(false); #endregion // Step 3 // create an SdsStream #region step3 var pressure_stream = new SdsStream { Id = streamPressureName, TypeId = type.Id, Description = "A stream for pressure data of tank1", }; pressure_stream = await metadataService.GetOrCreateStreamAsync(pressure_stream).ConfigureAwait(false); var temperature_stream = new SdsStream { Id = streamTempName, TypeId = type.Id, Description = "A stream for temperature data of tank1", }; temperature_stream = await metadataService.GetOrCreateStreamAsync(temperature_stream).ConfigureAwait(false); #endregion // Step 4 // insert simple data #region step4c await dataService.InsertValuesAsync(pressure_stream.Id, GetPressureData()).ConfigureAwait(false); await dataService.InsertValuesAsync(streamTempName, GetTemperatureData()).ConfigureAwait(false); #endregion // Step 5 // create complex type #region step5b SdsType tankType = SdsTypeBuilder.CreateSdsType <PressureTemperatureData>(); tankType.Id = typePressureTemperatureTimeName; tankType = await metadataService.GetOrCreateTypeAsync(tankType).ConfigureAwait(false); #endregion // Step 6 // create complex type stream #region step6 var tankStream = new SdsStream { Id = streamTank1, TypeId = tankType.Id, Description = "A stream for data of tank1", }; tankStream = await metadataService.GetOrCreateStreamAsync(tankStream).ConfigureAwait(false); #endregion // Step 7 // insert complex data #region step7 var data = GetData(); await dataService.InsertValuesAsync(streamTank1, data).ConfigureAwait(false); #endregion // Step 8 and Step 9 // view data // note: step 9 is not done in this example as the JSON conversion by the library takes care of it automatically for you #region step8 var sortedData = data.OrderBy(entry => entry.Time).ToList(); var firstTime = sortedData.First(); var lastTime = sortedData.Last(); var resultsPressure = (await dataService.GetWindowValuesAsync <TimeData>( streamPressureName, firstTime.Time.ToUniversalTime().ToString("o", CultureInfo.InvariantCulture), lastTime.Time.ToUniversalTime().ToString("o", CultureInfo.InvariantCulture)) .ConfigureAwait(false)) .ToList(); Console.WriteLine("Values from Pressure of Tank1:"); foreach (var evnt in resultsPressure) { Console.WriteLine(JsonConvert.SerializeObject(evnt)); } var resultsTank = (await dataService.GetWindowValuesAsync <PressureTemperatureData>( streamTank1, firstTime.Time.ToUniversalTime().ToString("o", CultureInfo.InvariantCulture), lastTime.Time.ToUniversalTime().ToString("o", CultureInfo.InvariantCulture)) .ConfigureAwait(false)) .ToList(); Console.WriteLine("Values from Tank1:"); foreach (var evnt in resultsTank) { Console.WriteLine(JsonConvert.SerializeObject(evnt)); } #endregion if (test) { // Testing to make sure we get back expected stuff if (string.Compare(JsonConvert.SerializeObject(resultsPressure.First()), "{\"Time\":\"2017-01-11T22:21:23.43Z\",\"Value\":346.0}", StringComparison.OrdinalIgnoreCase) != 0) { throw new Exception("Value retrieved isn't expected value for pressure of Tank1"); } if (string.Compare(JsonConvert.SerializeObject(resultsTank.First()), "{\"Time\":\"2017-01-11T22:21:23.43Z\",\"Pressure\":346.0,\"Temperature\":91.0}", StringComparison.OrdinalIgnoreCase) != 0) { throw new Exception("Value retrieved isn't expected value for Temeprature from Tank1"); } } // Step 10 // view summary data #region step10 var resultsTankSummary = (await dataService.GetIntervalsAsync <PressureTemperatureData>( streamTank1, firstTime.Time.ToUniversalTime().ToString("o", CultureInfo.InvariantCulture), lastTime.Time.ToUniversalTime().ToString("o", CultureInfo.InvariantCulture), 1) .ConfigureAwait(false)) .ToList(); Console.WriteLine("Summaries from Tank1:"); foreach (var evnt in resultsTankSummary) { Console.WriteLine(JsonConvert.SerializeObject(evnt.Summaries)); } #endregion // Step 11 // Bulk calls #region step11a var tankStream0 = new SdsStream { Id = streamTank0, TypeId = tankType.Id, }; tankStream = await metadataService.GetOrCreateStreamAsync(tankStream0).ConfigureAwait(false); var tankStream2 = new SdsStream { Id = streamTank2, TypeId = tankType.Id, Description = "A stream for data of tank2", }; tankStream2 = await metadataService.GetOrCreateStreamAsync(tankStream2).ConfigureAwait(false); var data2 = GetData2(); var sortedData2 = data2.OrderBy(entry => entry.Time).ToList(); var firstTime2 = sortedData2.First(); var lastTime2 = sortedData2.Last(); await dataService.InsertValuesAsync(tankStream2.Id, data2).ConfigureAwait(false); await dataService.InsertValuesAsync(tankStream0.Id, GetData()).ConfigureAwait(false); #endregion Thread.Sleep(200); // slight rest here for consistency #region step11b var results2Tanks = await dataService.GetJoinValuesAsync <PressureTemperatureData>( new string[] { tankStream0.Id, tankStream2.Id }, SdsJoinType.Outer, firstTime2.Time.ToUniversalTime().ToString("o", CultureInfo.InvariantCulture), lastTime2.Time.ToUniversalTime().ToString("o", CultureInfo.InvariantCulture)) .ConfigureAwait(false); Console.WriteLine(); Console.WriteLine(); Console.WriteLine($"Bulk Values: {tankStream0.Id} then {tankStream2.Id}: "); Console.WriteLine(); foreach (var tankResult in results2Tanks) { foreach (var dataEntry in tankResult) { Console.WriteLine(JsonConvert.SerializeObject(dataEntry)); } Console.WriteLine(); } #endregion } catch (Exception ex) { Console.WriteLine(ex); _toThrow = ex; throw; } finally { if (metadataService != null) { // Step 12 // delete everything #region step12 await RunInTryCatch(metadataService.DeleteStreamAsync, streamPressureName).ConfigureAwait(false); await RunInTryCatch(metadataService.DeleteStreamAsync, streamTempName).ConfigureAwait(false); await RunInTryCatch(metadataService.DeleteStreamAsync, streamTank0).ConfigureAwait(false); await RunInTryCatch(metadataService.DeleteStreamAsync, streamTank1).ConfigureAwait(false); await RunInTryCatch(metadataService.DeleteStreamAsync, streamTank2).ConfigureAwait(false); await RunInTryCatch(metadataService.DeleteTypeAsync, typeValueTimeName).ConfigureAwait(false); await RunInTryCatch(metadataService.DeleteTypeAsync, typePressureTemperatureTimeName).ConfigureAwait(false); #endregion Thread.Sleep(10); // slight rest here for consistency // Check deletes await RunInTryCatchExpectException(metadataService.GetStreamAsync, streamPressureName).ConfigureAwait(false); await RunInTryCatchExpectException(metadataService.GetStreamAsync, streamTempName).ConfigureAwait(false); await RunInTryCatchExpectException(metadataService.GetStreamAsync, streamTank0).ConfigureAwait(false); await RunInTryCatchExpectException(metadataService.GetStreamAsync, streamTank1).ConfigureAwait(false); await RunInTryCatchExpectException(metadataService.GetStreamAsync, streamTank2).ConfigureAwait(false); await RunInTryCatchExpectException(metadataService.GetTypeAsync, typeValueTimeName).ConfigureAwait(false); await RunInTryCatchExpectException(metadataService.GetTypeAsync, typePressureTemperatureTimeName).ConfigureAwait(false); } } if (test && _toThrow != null) { throw _toThrow; } return(_toThrow == null); }
public static async Task <bool> MainAsync(bool testIn = false, string fileLocation = "datafile.csv") { test = testIn; try { // Import data in. Use csv reader and custom class to make it simple using (var reader = new StreamReader(fileLocation)) using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture)) { dataList = csv.GetRecords <TemperatureReadingsWithIds>().ToList(); } // Use Linq to get the distinct StreamIds we need. streamsIdsToSendTo = dataList.Select(dataeEntry => dataeEntry.StreamId).Distinct(); //Get Configuration information about where this is sending to configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .AddJsonFile("appsettings.test.json", optional: true) .Build(); var tenantId = configuration["TenantId"]; var namespaceId = configuration["NamespaceId"]; var resource = configuration["Resource"]; var clientId = configuration["ClientID"]; if (!test) { SystemBrowser.OpenBrowser = new OpenSystemBrowser(); } else { SystemBrowser.Password = configuration["Password"]; SystemBrowser.UserName = configuration["UserName"]; } (configuration as ConfigurationRoot).Dispose(); // Setup access to OCS AuthenticationHandler_PKCE authenticationHandler = new AuthenticationHandler_PKCE(tenantId, clientId, resource); SdsService sdsService = new SdsService(new Uri(resource), authenticationHandler); dataService = sdsService.GetDataService(tenantId, namespaceId); metaService = sdsService.GetMetadataService(tenantId, namespaceId); if (createStreams) { SdsType typeToCreate = SdsTypeBuilder.CreateSdsType <TemperatureReadings>(); typeToCreate.Id = typeID; Console.WriteLine("Creating Type"); await metaService.GetOrCreateTypeAsync(typeToCreate); var stream1 = new SdsStream { Id = stream1ID, TypeId = typeToCreate.Id }; var stream2 = new SdsStream { Id = stream2ID, TypeId = typeToCreate.Id }; Console.WriteLine("Creating Stream"); stream1 = await metaService.GetOrCreateStreamAsync(stream1); stream2 = await metaService.GetOrCreateStreamAsync(stream2); } Console.WriteLine("Sending Data"); // Loop over each stream to send to and send the data as one call. foreach (string streamId in streamsIdsToSendTo) { // Get all of the data for this stream in a list var valueToSend = dataList.Where(dataEntry => dataEntry.StreamId == streamId) //gets only appropriate data for stream .Select(dataEntry => new TemperatureReadings(dataEntry)) // transforms it to the right data .ToList(); // needed in IList format for insertValues await dataService.InsertValuesAsync(streamId, valueToSend); } if (test) { //checks to make sure values are written await CheckValuesWrittenASync(); } } catch (Exception ex) { Console.WriteLine(ex.Message); toThrow = ex; } finally { if (test) { if (!createStreams) { // if we just created the data lets just remove that // Do Delete Console.WriteLine("Deleting Data"); await DeleteValuesAsync(); // Do Delete check await CheckDeletesValuesAsync(); } else { Console.WriteLine("Deleting Streams"); // if we created the types and streams, lets remove those too await RunInTryCatch(metaService.DeleteStreamAsync, stream1ID); await RunInTryCatch(metaService.DeleteStreamAsync, stream2ID); Console.WriteLine("Deleting Types"); await RunInTryCatch(metaService.DeleteTypeAsync, typeID); // Check deletes await RunInTryCatchExpectException(metaService.GetStreamAsync, stream1ID); await RunInTryCatchExpectException(metaService.GetStreamAsync, stream2ID); await RunInTryCatchExpectException(metaService.GetTypeAsync, typeID); } } } if (toThrow != null) { throw toThrow; } return(toThrow == null); }
public async Task OmfIngressClientLibrariesTest() { // Setting things up Program.Setup(); // Initializing Sds Service ISdsMetadataService sdsMetadataService = SdsService.GetMetadataService(new Uri(Program.Address), Program.TenantId, Program.NamespaceId, new AuthenticationHandler(new Uri(Program.Address), Program.ClientId, Program.ClientSecret)); ISdsDataService sdsDataService = SdsService.GetDataService(new Uri(Program.Address), Program.TenantId, Program.NamespaceId, new AuthenticationHandler(new Uri(Program.Address), Program.ClientId, Program.ClientSecret)); OmfConnection omfConnection = null; try { // Create the Connection, send OMF omfConnection = await Program.CreateOmfConnectionAsync().ConfigureAwait(false); await Program.SendTypeContainerAndDataAsync().ConfigureAwait(false); // Check if Data was successfully stored in Sds DataPointType firstValueForStream = null; await PollUntilTrueAsync(async() => { try { firstValueForStream = await sdsDataService.GetFirstValueAsync <DataPointType>(Program.StreamId).ConfigureAwait(false); return(firstValueForStream != null); } catch { return(false); } }, TimeSpan.FromSeconds(180), TimeSpan.FromSeconds(1)).ConfigureAwait(false); Assert.NotNull(firstValueForStream); } finally { // Delete the Type and Stream await Program.DeleteTypeAndContainerAsync().ConfigureAwait(false); // Verify the Type was successfully deleted in Sds bool deleted = await PollUntilTrueAsync(async() => { try { SdsType sdsType = await sdsMetadataService.GetTypeAsync("DataPointType").ConfigureAwait(false); return(false); } catch (Exception ex) when(ex is SdsHttpClientException sdsHttpClientException && sdsHttpClientException.StatusCode == HttpStatusCode.NotFound) { return(true); } catch { return(false); } }, TimeSpan.FromSeconds(180), TimeSpan.FromSeconds(1)).ConfigureAwait(false); Assert.True(deleted); await Program.DeleteOmfConnectionAsync(omfConnection).ConfigureAwait(false); } }
public static async Task MainAsync() { string tenantId = ConfigurationManager.AppSettings["Tenant"]; string namespaceId = ConfigurationManager.AppSettings["Namespace"]; string address = ConfigurationManager.AppSettings["Address"]; string resource = ConfigurationManager.AppSettings["Resource"]; string clientId = ConfigurationManager.AppSettings["ClientId"]; string clientSecret = ConfigurationManager.AppSettings["ClientSecret"]; SdsSecurityHandler securityHandler = new SdsSecurityHandler(resource, tenantId, clientId, clientSecret); SdsService service = new SdsService(new Uri(address), securityHandler); ISdsMetadataService MetadataService = service.GetMetadataService(tenantId, namespaceId); ISdsDataService DataService = service.GetDataService(tenantId, namespaceId); /* * The following code provides an implementation for getting all the SdsUom ID's for each quantity. * If you are not aware with which SdsUom ID to use, you can uncomment the below code and find out the * uom id. * * e.g. I am using degree_fahrenheit and degree_celsius UOMS for temperature SdsQuantity. * * * IEnumerable<SdsUomQuantity> sdsUomQuantities = await MetadataService.GetQuantitiesAsync(); * IEnumerable<SdsUom> sdsUoms = null; * * foreach (SdsUomQuantity sdsUomQuantity in sdsUomQuantities) * { * sdsUoms = await MetadataService.GetQuantityUomsAsync(sdsUomQuantity.Id); * * foreach (SdsUom sdsUom in sdsUoms) * { * Console.WriteLine(sdsUom.Id); * } * } */ #region stream and type creation // Creating a Sdstype SdsType sdsType = SdsTypeBuilder.CreateSdsType <Widget>(); sdsType.Id = TypeId; sdsType = await MetadataService.GetOrCreateTypeAsync(sdsType); //Creating a Stream overriding the distance property. SdsStream sdsStreamOne = new SdsStream() { Id = StreamWithPropertyOverriden, TypeId = TypeId, Name = "UomStreamSourceWithPropertyOverridden", PropertyOverrides = new List <SdsStreamPropertyOverride>() }; //Overriding the UOM of the distance property to be kilometer instead of mile. sdsStreamOne.PropertyOverrides.Add(new SdsStreamPropertyOverride() { Uom = "kilometer", SdsTypePropertyId = "Distance" }); sdsStreamOne = await MetadataService.GetOrCreateStreamAsync(sdsStreamOne); //Creating a Stream without overriding properties. SdsStream sdsStreamTwo = new SdsStream() { Id = StreamWithoutPropertyOverriden, TypeId = TypeId, Name = "UomStreamSourceWithNoPropertyOverridden", }; sdsStreamTwo = await MetadataService.GetOrCreateStreamAsync(sdsStreamTwo); // Generating data IList <Widget> data = new List <Widget>(); for (int i = 0; i < 10; i++) { Widget widget = new Widget(); widget.Time = DateTime.UtcNow.AddSeconds(i); widget.Temperature = Random.Next(1, 100); widget.Distance = Random.Next(1, 100); data.Add(widget); } /* In stream one, the temperature value will be inserted as Fahrenheit since we have defined the * default uom as Fahrenheit for Temperature in the Widget class. The distance value will be * inserted as kilometer, as we have overridden the Distance property in stream one, * regardless of the default uom for Distance in the Widget class. */ await DataService.InsertValuesAsync <Widget>(sdsStreamOne.Id, data); /* In stream two, the temperature value will be inserted as Fahrenheit and the distance will be inserted as mile. * */ await DataService.InsertValuesAsync <Widget>(sdsStreamTwo.Id, data); /* * The last value stored in stream one. */ Widget widgetFromStreamOne = await DataService.GetLastValueAsync <Widget>(sdsStreamOne.Id); Console.WriteLine($"In stream one, the distance is {widgetFromStreamOne.Distance} kilometers and the temperature is {widgetFromStreamOne.Temperature} degrees fahrenheit"); Console.WriteLine(); /* * The last value stored in stream two. */ Widget widgetFromStreamTwo = await DataService.GetLastValueAsync <Widget>(sdsStreamTwo.Id); Console.WriteLine($"In stream two, the distance is {widgetFromStreamTwo.Distance} miles and the temperature is {widgetFromStreamTwo.Temperature} degrees fahrenheit"); Console.WriteLine(); /* * If you want your data to be in specified uom, you can override your properties while making a call. * In the following, I want the temperature to be in Celsius, and the distance to be in feet. * * Then you can pass IList<SdsStreamPropertyOverride> to DataService while getting values. * */ IList <SdsStreamPropertyOverride> requestOverrides = new List <SdsStreamPropertyOverride>(); requestOverrides.Add(new SdsStreamPropertyOverride() { Uom = "degree_celsius", SdsTypePropertyId = "Temperature" }); requestOverrides.Add(new SdsStreamPropertyOverride() { Uom = "foot", SdsTypePropertyId = "Distance" }); /* * In the following call, data will be converted from Fahrenheit to Celsius for the temperature property, * and from kilometer to foot for the distance property. * * Uoms in Stream one (Temperature : Fahrenheit, Distance : Kilometer) * */ widgetFromStreamOne = await DataService.GetLastValueAsync <Widget>(sdsStreamOne.Id, requestOverrides); Console.WriteLine($"In stream one, the distance is {widgetFromStreamOne.Distance} foot and the temperature is {widgetFromStreamOne.Temperature} degrees celsius"); Console.WriteLine(); /* * In the following call, data will be converted from Fahrenheit to Celsius for the temperature property, * and from mile to foot for the distance property. * * Uoms in Stream two (Temperature : Fahrenheit, Distance : Mile) * */ widgetFromStreamTwo = await DataService.GetLastValueAsync <Widget>(sdsStreamTwo.Id, requestOverrides); Console.WriteLine($"In stream two, the distance is {widgetFromStreamTwo.Distance} foot and the temperature is {widgetFromStreamTwo.Temperature} degrees celsius"); Console.WriteLine(); #endregion stream and type creation #region Deletion of Streams and type await MetadataService.DeleteStreamAsync(sdsStreamOne.Id); await MetadataService.DeleteStreamAsync(sdsStreamTwo.Id); await MetadataService.DeleteTypeAsync(TypeId); #endregion Deletion of Streams and type }
private static async Task MainAsync() { IConfigurationBuilder builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json"); IConfiguration configuration = builder.Build(); // ==== Client constants ==== var tenantId = configuration["TenantId"]; var namespaceId = configuration["NamespaceId"]; var address = configuration["Address"]; var resource = configuration["Resource"]; var clientId = configuration["ClientId"]; var clientKey = configuration["ClientKey"]; // ==== Metadata IDs ==== string streamId = "SampleStream"; string typeId = "SampleType"; string targetTypeId = "SampleType_Target"; string targetIntTypeId = "SampleType_TargetInt"; string autoViewId = "SampleAutoView"; string manualViewId = "SampleManualView"; // Get Sds Services to communicate with server SdsSecurityHandler securityHandler = new SdsSecurityHandler(resource, tenantId, clientId, clientKey); SdsService sdsService = new SdsService(new Uri(address), securityHandler); var metadataService = sdsService.GetMetadataService(tenantId, namespaceId); var dataService = sdsService.GetDataService(tenantId, namespaceId); LoggerCallbackHandler.UseDefaultLogging = false; Console.WriteLine(@"-------------------------------------------------------------"); Console.WriteLine(@" _________ .___ _______ ______________________"); Console.WriteLine(@" / _____/ __| _/______ \ \ \_ _____/\__ ___/"); Console.WriteLine(@" \_____ \ / __ |/ ___/ / | \ | __)_ | | "); Console.WriteLine(@" / \/ /_/ |\___ \ / | \| \ | | "); Console.WriteLine(@"/_______ /\____ /____ > /\ \____|__ /_______ / |____| "); Console.WriteLine(@" \/ \/ \/ \/ \/ \/ "); Console.WriteLine(@"-------------------------------------------------------------"); Console.WriteLine(); Console.WriteLine($"Sds endpoint at {address}"); Console.WriteLine(); try { // create an SdsType Console.WriteLine("Creating an SdsType"); SdsType type = SdsTypeBuilder.CreateSdsType <WaveData>(); type.Id = typeId; type = await metadataService.GetOrCreateTypeAsync(type); // create an SdsStream Console.WriteLine("Creating an SdsStream"); var stream = new SdsStream { Id = streamId, Name = "Wave Data Sample", TypeId = type.Id, Description = "This is a sample SdsStream for storing WaveData type measurements" }; stream = await metadataService.GetOrCreateStreamAsync(stream); // insert data Console.WriteLine("Inserting data"); // insert a single event var wave = GetWave(0, 200, 2); await dataService.InsertValueAsync(stream.Id, wave); // insert a list of events var waves = new List <WaveData>(); for (var i = 2; i <= 18; i += 2) { waves.Add(GetWave(i, 200, 2)); } await dataService.InsertValuesAsync(stream.Id, waves); // get last event Console.WriteLine("Getting latest event"); var latest = await dataService.GetLastValueAsync <WaveData>(streamId); Console.WriteLine(latest.ToString()); Console.WriteLine(); // get all events Console.WriteLine("Getting all events"); var allEvents = (List <WaveData>) await dataService.GetWindowValuesAsync <WaveData>(streamId, "0", "180"); Console.WriteLine($"Total events found: {allEvents.Count}"); foreach (var evnt in allEvents) { Console.WriteLine(evnt.ToString()); } Console.WriteLine(); // update events Console.WriteLine("Updating events"); // update one event var updatedWave = UpdateWave(allEvents.First(), 4); await dataService.UpdateValueAsync(stream.Id, updatedWave); // update all events, adding ten more var updatedCollection = new List <WaveData>(); for (int i = 2; i < 40; i = i + 2) { updatedCollection.Add(GetWave(i, 400, 4)); } await dataService.UpdateValuesAsync(stream.Id, updatedCollection); allEvents = (List <WaveData>) await dataService.GetWindowValuesAsync <WaveData>(stream.Id, "0", "180"); Console.WriteLine("Getting updated events"); Console.WriteLine($"Total events found: {allEvents.Count}"); foreach (var evnt in allEvents) { Console.WriteLine(evnt.ToString()); } Console.WriteLine(); // replacing events Console.WriteLine("Replacing events"); // replace one event var replaceEvent = allEvents.First(); replaceEvent.Sin = 0.717; replaceEvent.Cos = 0.717; replaceEvent.Tan = Math.Sqrt(2 * (0.717 * 0.717)); await dataService.ReplaceValueAsync <WaveData>(streamId, replaceEvent); // replace all events foreach (var evnt in allEvents) { evnt.Sin = 5.0 / 2; evnt.Cos = 5 * Math.Sqrt(3) / 2; evnt.Tan = 5 / Math.Sqrt(3); } await dataService.ReplaceValuesAsync <WaveData>(streamId, allEvents); Console.WriteLine("Getting replaced events"); var replacedEvents = (List <WaveData>) await dataService.GetWindowValuesAsync <WaveData>(streamId, "0", "180"); Console.WriteLine($"Total events found: {replacedEvents.Count}"); foreach (var evnt in replacedEvents) { Console.WriteLine(evnt.ToString()); } Console.WriteLine(); // Property Overrides Console.WriteLine("Sds can interpolate or extrapolate data at an index location where data does not explicitly exist:"); Console.WriteLine(); // We will retrieve three events using the default behavior, Continuous var retrieved = await dataService .GetRangeValuesAsync <WaveData>(stream.Id, "1", 3, SdsBoundaryType.ExactOrCalculated); Console.WriteLine("Default (Continuous) requesting data starting at index location '1', where we have not entered data, Sds will interpolate a value for each property:"); foreach (var value in retrieved) { Console.WriteLine($"Order: {value.Order}, Radians: {value.Radians}, Cos: {value.Cos}"); } Console.WriteLine(); // create a Discrete stream PropertyOverride indicating that we do not want Sds to calculate a value for Radians and update our stream var propertyOverride = new SdsStreamPropertyOverride() { SdsTypePropertyId = "Radians", InterpolationMode = SdsInterpolationMode.Discrete }; var propertyOverrides = new List <SdsStreamPropertyOverride>() { propertyOverride }; // update the stream stream.PropertyOverrides = propertyOverrides; await metadataService.CreateOrUpdateStreamAsync(stream); retrieved = await dataService .GetRangeValuesAsync <WaveData>(stream.Id, "1", 3, SdsBoundaryType.ExactOrCalculated); Console.WriteLine("We can override this behavior on a property by property basis, here we override the Radians property instructing Sds not to interpolate."); Console.WriteLine("Sds will now return the default value for the data type:"); foreach (var value in retrieved) { Console.WriteLine($"Order: {value.Order}, Radians: {value.Radians}, Cos: {value.Cos}"); } Console.WriteLine(); // Stream views Console.WriteLine("SdsViews"); // create target types var targetType = SdsTypeBuilder.CreateSdsType <WaveDataTarget>(); targetType.Id = targetTypeId; var targetIntType = SdsTypeBuilder.CreateSdsType <WaveDataInteger>(); targetIntType.Id = targetIntTypeId; await metadataService.CreateOrUpdateTypeAsync(targetType); await metadataService.CreateOrUpdateTypeAsync(targetIntType); // create views var autoView = new SdsView() { Id = autoViewId, SourceTypeId = typeId, TargetTypeId = targetTypeId }; // create explicit mappings var vp1 = new SdsViewProperty() { SourceId = "Order", TargetId = "OrderTarget" }; var vp2 = new SdsViewProperty() { SourceId = "Sin", TargetId = "SinInt" }; var vp3 = new SdsViewProperty() { SourceId = "Cos", TargetId = "CosInt" }; var vp4 = new SdsViewProperty() { SourceId = "Tan", TargetId = "TanInt" }; var manualView = new SdsView() { Id = manualViewId, SourceTypeId = typeId, TargetTypeId = targetIntTypeId, Properties = new List <SdsViewProperty>() { vp1, vp2, vp3, vp4 } }; await metadataService.CreateOrUpdateViewAsync(autoView); await metadataService.CreateOrUpdateViewAsync(manualView); Console.WriteLine("Here is some of our data as it is stored on the server:"); foreach (var evnt in retrieved) { Console.WriteLine($"Sin: {evnt.Sin}, Cos: {evnt.Cos}, Tan {evnt.Tan}"); } Console.WriteLine(); // get autoview data var autoViewData = await dataService.GetRangeValuesAsync <WaveDataTarget>(stream.Id, "1", 3, SdsBoundaryType.ExactOrCalculated, autoViewId); Console.WriteLine("Specifying a view with an SdsType of the same shape returns values that are automatically mapped to the target SdsType's properties:"); foreach (var value in autoViewData) { Console.WriteLine($"SinTarget: {value.SinTarget} CosTarget: {value.CosTarget} TanTarget: {value.TanTarget}"); } Console.WriteLine(); // get manaulview data Console.WriteLine("SdsViews can also convert certain types of data, here we return integers where the original values were doubles:"); var manualViewData = await dataService.GetRangeValuesAsync <WaveDataInteger>(stream.Id, "1", 3, SdsBoundaryType.ExactOrCalculated, manualViewId); foreach (var value in manualViewData) { Console.WriteLine($"SinInt: {value.SinInt} CosInt: {value.CosInt} TanInt: {value.TanInt}"); } Console.WriteLine(); // get SdsViewMap Console.WriteLine("We can query Sds to return the SdsViewMap for our SdsView, here is the one generated automatically:"); var autoViewMap = await metadataService.GetViewMapAsync(autoViewId); PrintViewMapProperties(autoViewMap); Console.WriteLine("Here is our explicit mapping, note SdsViewMap will return all properties of the Source Type, even those without a corresponding Target property:"); var manualViewMap = await metadataService.GetViewMapAsync(manualViewId); PrintViewMapProperties(manualViewMap); // tags, metadata and search Console.WriteLine("Let's add some Tags and Metadata to our stream:"); var tags = new List <string> { "waves", "periodic", "2018", "validated" }; var metadata = new Dictionary <string, string>() { { "Region", "North America" }, { "Country", "Canada" }, { "Province", "Quebec" } }; await metadataService.UpdateStreamTagsAsync(streamId, tags); await metadataService.UpdateStreamMetadataAsync(streamId, metadata); tags = (List <string>) await metadataService.GetStreamTagsAsync(streamId); Console.WriteLine(); Console.WriteLine($"Tags now associated with {streamId}:"); foreach (var tag in tags) { Console.WriteLine(tag); } Console.WriteLine(); Console.WriteLine($"Metadata now associated with {streamId}:"); Console.WriteLine("Metadata key Region: " + await metadataService.GetStreamMetadataValueAsync(streamId, "Region")); Console.WriteLine("Metadata key Country: " + await metadataService.GetStreamMetadataValueAsync(streamId, "Country")); Console.WriteLine("Metadata key Province: " + await metadataService.GetStreamMetadataValueAsync(streamId, "Province")); Console.WriteLine(); Console.WriteLine("Pausing to allow for search indexing..."); // allow time for search indexing await Task.Delay(15000); Console.WriteLine("We can also use our tags to search for streams, let's search for streams tagged with 'periodic':"); var streams = await metadataService.GetStreamsAsync("periodic"); foreach (var strm in streams) { Console.WriteLine(strm.Id); } Console.WriteLine(); // delete values Console.WriteLine("Deleting values from the SdsStream"); // delete one event await dataService.RemoveValueAsync(stream.Id, 0); // delete all events await dataService.RemoveWindowValuesAsync(stream.Id, 1, 200); retrieved = await dataService.GetWindowValuesAsync <WaveData>(stream.Id, "0", "200"); if (retrieved.ToList <WaveData>().Count == 0) { Console.WriteLine("All values deleted successfully!"); } Console.WriteLine(); } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { Console.WriteLine("Cleaning up"); // Delete the stream, types and views Console.WriteLine("Deleteing stream"); await metadataService.DeleteStreamAsync(streamId); Console.WriteLine("Deleteing views"); await metadataService.DeleteViewAsync(autoViewId); await metadataService.DeleteViewAsync(manualViewId); Console.WriteLine("Deleteing types"); await metadataService.DeleteTypeAsync(typeId); await metadataService.DeleteTypeAsync(targetTypeId); await metadataService.DeleteTypeAsync(targetIntTypeId); Console.WriteLine("done"); Console.ReadKey(); } }
public static async Task <bool> MainAsync(bool test = false) { IConfigurationBuilder builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .AddJsonFile("appsettings.test.json", optional: true); _configuration = builder.Build(); // ==== Client constants ==== var tenantId = _configuration["TenantId"]; var namespaceId = _configuration["NamespaceId"]; var resource = _configuration["Resource"]; var clientId = _configuration["ClientId"]; var clientKey = _configuration["ClientKey"]; // ==== Metadata IDs ==== string streamId = "SampleStream"; string streamIdSecondary = "SampleStream_Secondary"; string streamIdCompound = "SampleStream_Compound"; string typeId = "SampleType"; string targetTypeId = "SampleType_Target"; string targetIntTypeId = "SampleType_TargetInt"; string autoStreamViewId = "SampleAutoStreamView"; string manualStreamViewId = "SampleManualStreamView"; string compoundTypeId = "SampleType_Compound"; var uriResource = new Uri(resource); // Step 1 // Get Sds Services to communicate with server AuthenticationHandler authenticationHandler = new AuthenticationHandler(uriResource, clientId, clientKey); SdsService sdsService = new SdsService(new Uri(resource), null, HttpCompressionMethod.GZip, authenticationHandler); var metadataService = sdsService.GetMetadataService(tenantId, namespaceId); var dataService = sdsService.GetDataService(tenantId, namespaceId); var tableService = sdsService.GetTableService(tenantId, namespaceId); Console.WriteLine(@"-------------------------------------------------------------"); Console.WriteLine(@" _________ .___ _______ ______________________"); Console.WriteLine(@" / _____/ __| _/______ \ \ \_ _____/\__ ___/"); Console.WriteLine(@" \_____ \ / __ |/ ___/ / | \ | __)_ | | "); Console.WriteLine(@" / \/ /_/ |\___ \ / | \| \ | | "); Console.WriteLine(@"/_______ /\____ /____ > /\ \____|__ /_______ / |____| "); Console.WriteLine(@" \/ \/ \/ \/ \/ \/ "); Console.WriteLine(@"-------------------------------------------------------------"); Console.WriteLine(); Console.WriteLine($"SDS endpoint at {resource}"); Console.WriteLine(); try { // Step 2 // create an SdsType Console.WriteLine("Creating an SdsType"); SdsType type = SdsTypeBuilder.CreateSdsType <WaveData>(); type.Id = typeId; type = await metadataService.GetOrCreateTypeAsync(type).ConfigureAwait(false); // Step 3 // create an SdsStream Console.WriteLine("Creating an SdsStream"); var stream = new SdsStream { Id = streamId, Name = "Wave Data Sample", TypeId = type.Id, Description = "This is a sample SdsStream for storing WaveData type measurements", }; stream = await metadataService.GetOrCreateStreamAsync(stream).ConfigureAwait(false); // Step 4 // insert data Console.WriteLine("Inserting data"); // insert a single event var wave = GetWave(0, 2); await dataService.InsertValueAsync(stream.Id, wave).ConfigureAwait(false); // insert a list of events var waves = new List <WaveData>(); for (var i = 2; i <= 18; i += 2) { waves.Add(GetWave(i, 2)); } await dataService.InsertValuesAsync(stream.Id, waves).ConfigureAwait(false); // Step 5 // get last event Console.WriteLine("Getting latest event"); var latest = await dataService.GetLastValueAsync <WaveData>(streamId).ConfigureAwait(false); Console.WriteLine(latest.ToString()); Console.WriteLine(); // get all events Console.WriteLine("Getting all events"); var allEvents = (List <WaveData>) await dataService.GetWindowValuesAsync <WaveData>(streamId, "0", "180").ConfigureAwait(false); Console.WriteLine($"Total events found: {allEvents.Count}"); foreach (var evnt in allEvents) { Console.WriteLine(evnt.ToString()); } Console.WriteLine(); // Step 6 // getting all events in table format with headers var tableEvents = await tableService.GetWindowValuesAsync(stream.Id, "0", "180").ConfigureAwait(false); Console.WriteLine("Getting table events"); foreach (var evnt in tableEvents.Rows) { Console.WriteLine(string.Join(",", evnt.ToArray())); } Console.WriteLine(); // Step 7 // update events Console.WriteLine("Updating events"); // update one event var updatedWave = UpdateWave(allEvents.First(), 4); await dataService.UpdateValueAsync(stream.Id, updatedWave).ConfigureAwait(false); // update all events, adding ten more var updatedCollection = new List <WaveData>(); for (int i = 2; i < 40; i += 2) { updatedCollection.Add(GetWave(i, 4)); } await dataService.UpdateValuesAsync(stream.Id, updatedCollection).ConfigureAwait(false); allEvents = (List <WaveData>) await dataService.GetWindowValuesAsync <WaveData>(stream.Id, "0", "180").ConfigureAwait(false); Console.WriteLine("Getting updated events"); Console.WriteLine($"Total events found: {allEvents.Count}"); foreach (var evnt in allEvents) { Console.WriteLine(evnt.ToString()); } Console.WriteLine(); // Step 8 // replacing events Console.WriteLine("Replacing events"); // replace one event var replaceEvent = UpdateWave(allEvents.First(), multiplier: 5); await dataService.ReplaceValueAsync <WaveData>(streamId, replaceEvent).ConfigureAwait(false); // replace all events for (int i = 1; i < allEvents.Count; i++) { allEvents[i] = UpdateWave(allEvents[i], multiplier: 5); } await dataService.ReplaceValuesAsync <WaveData>(streamId, allEvents).ConfigureAwait(false); Console.WriteLine("Getting replaced events"); var replacedEvents = (List <WaveData>) await dataService.GetWindowValuesAsync <WaveData>(streamId, "0", "180").ConfigureAwait(false); Console.WriteLine($"Total events found: {replacedEvents.Count}"); foreach (var evnt in replacedEvents) { Console.WriteLine(evnt.ToString()); } Console.WriteLine(); // Step 9 // Property Overrides Console.WriteLine("SDS can interpolate or extrapolate data at an index location where data does not explicitly exist:"); Console.WriteLine(); // We will retrieve three events using the default behavior, Continuous var retrieved = await dataService .GetRangeValuesAsync <WaveData>(stream.Id, "1", 3, SdsBoundaryType.ExactOrCalculated).ConfigureAwait(false); Console.WriteLine("Default (Continuous) requesting data starting at index location '1', where we have not entered data, SDS will interpolate a value for this property and then return entered values:"); foreach (var value in retrieved) { Console.WriteLine(value.ToString()); } Console.WriteLine(); var retrievedInterpolated = await dataService .GetValuesAsync <WaveData>(stream.Id, "5", "32", 4).ConfigureAwait(false); Console.WriteLine("SDS will interpolate a value for each index asked for (5,14,23,32):"); foreach (var value in retrievedInterpolated) { Console.WriteLine(value.ToString()); } Console.WriteLine(); // Step 10 // We will retrieve events filtered to only get the ones where the radians are less than 50. Note, this can be done on index properties too. var retrievedInterpolatedFiltered = await dataService.GetWindowFilteredValuesAsync <WaveData>(stream.Id, "0", "180", SdsBoundaryType.ExactOrCalculated, "Radians lt 50").ConfigureAwait(false); Console.WriteLine("SDS will only return the values where the radians are less than 50:"); foreach (var value in retrievedInterpolatedFiltered) { Console.WriteLine(value.ToString()); } Console.WriteLine(); // Step 11 // We will retrieve a sample of our data Console.WriteLine("SDS can return a sample of your data population to show trends."); Console.WriteLine("Getting Sampled Values:"); var sampledValues = await dataService.GetSampledValuesAsync <WaveData>(stream.Id, "0", "40", 4, new[] { nameof(WaveData.Sin) }).ConfigureAwait(false); foreach (var sample in sampledValues) { Console.WriteLine(sample); } Console.WriteLine(); // Step 12 // create a Discrete stream PropertyOverride indicating that we do not want Sds to calculate a value for Radians and update our stream var propertyOverride = new SdsStreamPropertyOverride() { SdsTypePropertyId = "Radians", InterpolationMode = SdsInterpolationMode.Discrete, }; var propertyOverrides = new List <SdsStreamPropertyOverride>() { propertyOverride }; // update the stream stream.PropertyOverrides = propertyOverrides; await metadataService.CreateOrUpdateStreamAsync(stream).ConfigureAwait(false); retrieved = await dataService .GetRangeValuesAsync <WaveData>(stream.Id, "1", 3, SdsBoundaryType.ExactOrCalculated).ConfigureAwait(false); Console.WriteLine("We can override this behavior on a property by property basis, here we override the Radians property instructing Sds not to interpolate."); Console.WriteLine("SDS will now return the default value for the data type:"); foreach (var value in retrieved) { Console.WriteLine(value.ToString()); } Console.WriteLine(); // Step 13 // StreamViews Console.WriteLine("SdsStreamViews"); // create target types var targetType = SdsTypeBuilder.CreateSdsType <WaveDataTarget>(); targetType.Id = targetTypeId; var targetIntType = SdsTypeBuilder.CreateSdsType <WaveDataInteger>(); targetIntType.Id = targetIntTypeId; await metadataService.GetOrCreateTypeAsync(targetType).ConfigureAwait(false); await metadataService.GetOrCreateTypeAsync(targetIntType).ConfigureAwait(false); // create StreamViews var autoStreamView = new SdsStreamView() { Id = autoStreamViewId, SourceTypeId = typeId, TargetTypeId = targetTypeId, }; // create explicit mappings var vp1 = new SdsStreamViewProperty() { SourceId = "Order", TargetId = "OrderTarget" }; var vp2 = new SdsStreamViewProperty() { SourceId = "Sin", TargetId = "SinInt" }; var vp3 = new SdsStreamViewProperty() { SourceId = "Cos", TargetId = "CosInt" }; var vp4 = new SdsStreamViewProperty() { SourceId = "Tan", TargetId = "TanInt" }; var manualStreamView = new SdsStreamView() { Id = manualStreamViewId, SourceTypeId = typeId, TargetTypeId = targetIntTypeId, Properties = new List <SdsStreamViewProperty>() { vp1, vp2, vp3, vp4 }, }; await metadataService.CreateOrUpdateStreamViewAsync(autoStreamView).ConfigureAwait(false); await metadataService.CreateOrUpdateStreamViewAsync(manualStreamView).ConfigureAwait(false); Console.WriteLine("Here is some of our data as it is stored on the server:"); foreach (var evnt in retrieved) { Console.WriteLine($"Sin: {evnt.Sin}, Cos: {evnt.Cos}, Tan {evnt.Tan}"); } Console.WriteLine(); // get autoStreamView data var autoStreamViewData = await dataService.GetRangeValuesAsync <WaveDataTarget>(stream.Id, "1", 3, SdsBoundaryType.ExactOrCalculated, autoStreamViewId).ConfigureAwait(false); Console.WriteLine("Specifying a StreamView with an SdsType of the same shape returns values that are automatically mapped to the target SdsType's properties:"); foreach (var value in autoStreamViewData) { Console.WriteLine($"SinTarget: {value.SinTarget} CosTarget: {value.CosTarget} TanTarget: {value.TanTarget}"); } Console.WriteLine(); // get manualStreamView data Console.WriteLine("SdsStreamViews can also convert certain types of data, here we return integers where the original values were doubles:"); var manualStreamViewData = await dataService.GetRangeValuesAsync <WaveDataInteger>(stream.Id, "1", 3, SdsBoundaryType.ExactOrCalculated, manualStreamViewId).ConfigureAwait(false); foreach (var value in manualStreamViewData) { Console.WriteLine($"SinInt: {value.SinInt} CosInt: {value.CosInt} TanInt: {value.TanInt}"); } Console.WriteLine(); // get SdsStreamViewMap Console.WriteLine("We can query SDS to return the SdsStreamViewMap for our SdsStreamView, here is the one generated automatically:"); var autoStreamViewMap = await metadataService.GetStreamViewMapAsync(autoStreamViewId).ConfigureAwait(false); PrintStreamViewMapProperties(autoStreamViewMap); Console.WriteLine("Here is our explicit mapping, note SdsStreamViewMap will return all properties of the Source Type, even those without a corresponding Target property:"); var manualStreamViewMap = await metadataService.GetStreamViewMapAsync(manualStreamViewId).ConfigureAwait(false); PrintStreamViewMapProperties(manualStreamViewMap); // Step 14 // Update Stream Type based on SdsStreamView Console.WriteLine("We will now update the stream type based on the stream view"); var firstVal = await dataService.GetFirstValueAsync <WaveData>(stream.Id).ConfigureAwait(false); await metadataService.UpdateStreamTypeAsync(stream.Id, autoStreamViewId).ConfigureAwait(false); var newStream = await metadataService.GetStreamAsync(stream.Id).ConfigureAwait(false); var firstValUpdated = await dataService.GetFirstValueAsync <WaveDataTarget>(stream.Id).ConfigureAwait(false); Console.WriteLine($"The new type id {newStream.TypeId} compared to the original one {stream.TypeId}."); Console.WriteLine($"The new type value {firstValUpdated} compared to the original one {firstVal}."); Console.WriteLine(); // Step 15 // Show filtering on Type, works the same as filtering on Streams var types = await metadataService.GetTypesAsync().ConfigureAwait(false); var typesFiltered = await metadataService.GetTypesAsync("Id:*Target*").ConfigureAwait(false); Console.WriteLine($"The number of types returned without filtering: {types.Count()}. With filtering {typesFiltered.Count()}."); Console.WriteLine(); // Step 16 // tags and metadata Console.WriteLine("Let's add some Tags and Metadata to our stream:"); var tags = new List <string> { "waves", "periodic", "2018", "validated" }; var metadata = new Dictionary <string, string>() { { "Region", "North America" }, { "Country", "Canada" }, { "Province", "Quebec" } }; await metadataService.UpdateStreamTagsAsync(streamId, tags).ConfigureAwait(false); await metadataService.UpdateStreamMetadataAsync(streamId, metadata).ConfigureAwait(false); tags = (List <string>) await metadataService.GetStreamTagsAsync(streamId).ConfigureAwait(false); Console.WriteLine(); Console.WriteLine($"Tags now associated with {streamId}:"); foreach (var tag in tags) { Console.WriteLine(tag); } Console.WriteLine(); Console.WriteLine($"Metadata now associated with {streamId}:"); Console.WriteLine("Metadata key Region: " + await metadataService.GetStreamMetadataValueAsync(streamId, "Region").ConfigureAwait(false)); Console.WriteLine("Metadata key Country: " + await metadataService.GetStreamMetadataValueAsync(streamId, "Country").ConfigureAwait(false)); Console.WriteLine("Metadata key Province: " + await metadataService.GetStreamMetadataValueAsync(streamId, "Province").ConfigureAwait(false)); Console.WriteLine(); // Step 17 // update metadata Console.WriteLine("Let's make some changes to the Metadata on our stream:"); var patch = new MetadataPatchDocument(); patch.Remove("Region"); patch.Replace("Province", "Ontario"); patch.Add("City", "Toronto"); await metadataService.PatchStreamMetadataAsync(streamId, patch).ConfigureAwait(false); Console.WriteLine(); Console.WriteLine($"Metadata now associated with {streamId}:"); Console.WriteLine("Metadata key Country: " + await metadataService.GetStreamMetadataValueAsync(streamId, "Country").ConfigureAwait(false)); Console.WriteLine("Metadata key Province: " + await metadataService.GetStreamMetadataValueAsync(streamId, "Province").ConfigureAwait(false)); Console.WriteLine("Metadata key City: " + await metadataService.GetStreamMetadataValueAsync(streamId, "City").ConfigureAwait(false)); Console.WriteLine(); // Step 18 // delete values Console.WriteLine("Deleting values from the SdsStream"); // delete one event await dataService.RemoveValueAsync(stream.Id, 0).ConfigureAwait(false); // delete all events await dataService.RemoveWindowValuesAsync(stream.Id, 1, 200).ConfigureAwait(false); retrieved = await dataService.GetWindowValuesAsync <WaveData>(stream.Id, "0", "200").ConfigureAwait(false); if (retrieved.ToList().Count == 0) { Console.WriteLine("All values deleted successfully!"); } Console.WriteLine(); // Step 19 // Adding a new stream with a secondary index. Console.WriteLine("Adding a stream with a secondary index."); SdsStreamIndex measurementIndex = new SdsStreamIndex() { SdsTypePropertyId = type.Properties.First(p => p.Id.Equals("Radians", StringComparison.OrdinalIgnoreCase)).Id, }; SdsStream secondary = new SdsStream() { Id = streamIdSecondary, TypeId = type.Id, Indexes = new List <SdsStreamIndex>() { measurementIndex, }, }; secondary = await metadataService.GetOrCreateStreamAsync(secondary).ConfigureAwait(false); Console.WriteLine($"Secondary indexes on streams. {stream.Id}:{stream.Indexes?.Count}. {secondary.Id}:{secondary.Indexes.Count}. "); Console.WriteLine(); // Modifying an existing stream with a secondary index. Console.WriteLine("Modifying a stream to have a secondary index."); stream = await metadataService.GetStreamAsync(stream.Id).ConfigureAwait(false); type = await metadataService.GetTypeAsync(stream.TypeId).ConfigureAwait(false); SdsStreamIndex measurementTargetIndex = new SdsStreamIndex() { SdsTypePropertyId = type.Properties.First(p => p.Id.Equals("RadiansTarget", StringComparison.OrdinalIgnoreCase)).Id, }; stream.Indexes = new List <SdsStreamIndex>() { measurementTargetIndex }; await metadataService.CreateOrUpdateStreamAsync(stream).ConfigureAwait(false); stream = await metadataService.GetStreamAsync(stream.Id).ConfigureAwait(false); // Modifying an existing stream to remove the secondary index Console.WriteLine("Removing a secondary index from a stream."); secondary.Indexes = null; await metadataService.CreateOrUpdateStreamAsync(secondary).ConfigureAwait(false); secondary = await metadataService.GetStreamAsync(secondary.Id).ConfigureAwait(false); Console.WriteLine($"Secondary indexes on streams. {stream.Id}:{stream.Indexes?.Count}. {secondary.Id}:{secondary.Indexes?.Count}. "); Console.WriteLine(); // Step 20 // Adding Compound Index Type Console.WriteLine("Creating an SdsType with a compound index"); SdsType typeCompound = SdsTypeBuilder.CreateSdsType <WaveDataCompound>(); typeCompound.Id = compoundTypeId; typeCompound = await metadataService.GetOrCreateTypeAsync(typeCompound).ConfigureAwait(false); // create an SdsStream Console.WriteLine("Creating an SdsStream off of type with compound index"); var streamCompound = new SdsStream { Id = streamIdCompound, Name = "Wave Data Sample", TypeId = typeCompound.Id, Description = "This is a sample SdsStream for storing WaveData type measurements", }; streamCompound = await metadataService.GetOrCreateStreamAsync(streamCompound).ConfigureAwait(false); // Step 21 // insert compound data Console.WriteLine("Inserting data"); await dataService.InsertValueAsync(streamCompound.Id, GetWaveMultiplier(1, 10)).ConfigureAwait(false); await dataService.InsertValueAsync(streamCompound.Id, GetWaveMultiplier(2, 2)).ConfigureAwait(false); await dataService.InsertValueAsync(streamCompound.Id, GetWaveMultiplier(3, 1)).ConfigureAwait(false); await dataService.InsertValueAsync(streamCompound.Id, GetWaveMultiplier(10, 3)).ConfigureAwait(false); await dataService.InsertValueAsync(streamCompound.Id, GetWaveMultiplier(10, 8)).ConfigureAwait(false); await dataService.InsertValueAsync(streamCompound.Id, GetWaveMultiplier(10, 10)).ConfigureAwait(false); var latestCompound = await dataService.GetLastValueAsync <WaveDataCompound>(streamCompound.Id).ConfigureAwait(false); var firstCompound = await dataService.GetFirstValueAsync <WaveDataCompound>(streamCompound.Id).ConfigureAwait(false); var data = await dataService.GetWindowValuesAsync <WaveDataCompound, int, int>(streamCompound.Id, Tuple.Create(2, 1), Tuple.Create(10, 8)).ConfigureAwait(false); Console.WriteLine($"First data: {firstCompound}. Latest data: {latestCompound}."); Console.WriteLine(); Console.WriteLine("Window Data:"); foreach (var evnt in data) { Console.WriteLine(evnt.ToString()); } } catch (Exception ex) { Console.WriteLine(ex.Message); _toThrow = ex; } finally { // Step 22 Console.WriteLine(); Console.WriteLine("Cleaning up"); // Delete the stream, types and streamViews making sure Console.WriteLine("Deleting stream"); await RunInTryCatch(metadataService.DeleteStreamAsync, streamId).ConfigureAwait(false); await RunInTryCatch(metadataService.DeleteStreamAsync, streamIdSecondary).ConfigureAwait(false); await RunInTryCatch(metadataService.DeleteStreamAsync, streamIdCompound).ConfigureAwait(false); Console.WriteLine("Deleting stream views"); await RunInTryCatch(metadataService.DeleteStreamViewAsync, autoStreamViewId).ConfigureAwait(false); await RunInTryCatch(metadataService.DeleteStreamViewAsync, manualStreamViewId).ConfigureAwait(false); Console.WriteLine("Deleting types"); await RunInTryCatch(metadataService.DeleteTypeAsync, typeId).ConfigureAwait(false); await RunInTryCatch(metadataService.DeleteTypeAsync, compoundTypeId).ConfigureAwait(false); await RunInTryCatch(metadataService.DeleteTypeAsync, targetTypeId).ConfigureAwait(false); await RunInTryCatch(metadataService.DeleteTypeAsync, targetIntTypeId).ConfigureAwait(false); Console.WriteLine("Complete!"); if (!test) { Console.ReadKey(); } } if (test && _toThrow != null) { throw _toThrow; } return(_toThrow == null); }
public static bool MainRunner(bool delete = false) { MetadataService = null; IConfiguration configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .AddJsonFile("appsettings.test.json", optional: true) .Build(); var tenantId = configuration["TenantId"]; var namespaceId = configuration["NamespaceId"]; var resource = configuration["Resource"]; var clientId = configuration["ClientId"]; var clientKey = configuration["ClientKey"]; DataViewPath = configuration["DataView"]; SdsStreamPath = configuration["Stream"]; SdsTypePath = configuration["Type"]; SdsStreamDataPath = configuration["Data"]; SdsStreamMetaPath = configuration["Metadata"]; SdsStreamTagPath = configuration["Tags"]; SdsDataOnlyPath = configuration["DataOnly"]; (configuration as ConfigurationRoot).Dispose(); var uriResource = new Uri(resource); AuthenticationHandler authenticationHandler = new AuthenticationHandler(uriResource, clientId, clientKey); SdsService sdsService = new SdsService(new Uri(resource), authenticationHandler); MetadataService = sdsService.GetMetadataService(tenantId, namespaceId); DataService = sdsService.GetDataService(tenantId, namespaceId); if (!string.IsNullOrEmpty(DataViewPath)) { AuthenticationHandler authenticationHandlerDataViews = new AuthenticationHandler(uriResource, clientId, clientKey); // currently this has to be a different auth handler or it throws errors var dv_service_factory = new DataViewServiceFactory(new Uri(resource), authenticationHandlerDataViews); DvService = dv_service_factory.GetDataViewService(tenantId, namespaceId); } if (delete) { Cleanup(); return(true); } if (!string.IsNullOrEmpty(SdsTypePath)) { SendTypes(); } if (!string.IsNullOrEmpty(SdsStreamPath)) { SendStreams(); } if (!string.IsNullOrEmpty(SdsDataOnlyPath)) { SendData(); } if (!string.IsNullOrEmpty(DataViewPath)) { SendDataView(); } if (ToThrow != null) { throw ToThrow; } Console.WriteLine("Success!!!"); return(true); }
public static async Task <bool> MainAsync(bool test = false) { IConfigurationBuilder builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .AddJsonFile("appsettings.test.json", optional: true); IConfiguration configuration = builder.Build(); string tenantId = configuration["TenantId"]; string namespaceId = configuration["NamespaceId"]; string resource = configuration["Resource"]; string clientId = configuration["ClientId"]; string clientKey = configuration["ClientKey"]; string apiVersion = configuration["ApiVersion"]; string ResourcePrefix = "UomSample"; string TypeId = $"{ResourcePrefix} Uom"; string StreamWithPropertyOverriden = $"{ResourcePrefix} UomPropertyOverridden"; string StreamWithoutPropertyOverriden = $"{ResourcePrefix} UomNoPropertyOverridden"; // Step 1 AuthenticationHandler authenticationHandler = new AuthenticationHandler(new Uri(resource), clientId, clientKey); SdsService service = new SdsService(new Uri(resource), authenticationHandler); ISdsMetadataService MetadataService = service.GetMetadataService(tenantId, namespaceId); ISdsDataService DataService = service.GetDataService(tenantId, namespaceId); try { /* * The following code provides an implementation for getting all the SdsUom ID's for each quantity. * If you are not aware with which SdsUom ID to use, you can uncomment the below code and find out the * uom id. * * e.g. I am using degree_fahrenheit and degree_celsius UOMS for temperature SdsQuantity. * * * IEnumerable<SdsUomQuantity> sdsUomQuantities = await MetadataService.GetQuantitiesAsync(); * IEnumerable<SdsUom> sdsUoms = null; * * foreach (SdsUomQuantity sdsUomQuantity in sdsUomQuantities) * { * sdsUoms = await MetadataService.GetQuantityUomsAsync(sdsUomQuantity.Id); * * foreach (SdsUom sdsUom in sdsUoms) * { * Console.WriteLine(sdsUom.Id); * } * } */ // Step 2 // Creating a Sdstype SdsType sdsType = SdsTypeBuilder.CreateSdsType <Widget>(); sdsType.Id = TypeId; sdsType = await MetadataService.GetOrCreateTypeAsync(sdsType); // Step 3 //Creating a Stream overriding the distance property. SdsStream sdsStreamOne = new SdsStream() { Id = StreamWithPropertyOverriden, TypeId = TypeId, Name = "UomStreamSourceWithPropertyOverridden", PropertyOverrides = new List <SdsStreamPropertyOverride>() }; //Overriding the UOM of the distance property to be kilometer instead of mile. sdsStreamOne.PropertyOverrides.Add(new SdsStreamPropertyOverride() { Uom = "kilometer", SdsTypePropertyId = "Distance" }); sdsStreamOne = await MetadataService.GetOrCreateStreamAsync(sdsStreamOne); // Step 4 //Creating a Stream without overriding properties. SdsStream sdsStreamTwo = new SdsStream() { Id = StreamWithoutPropertyOverriden, TypeId = TypeId, Name = "UomStreamSourceWithNoPropertyOverridden", }; sdsStreamTwo = await MetadataService.GetOrCreateStreamAsync(sdsStreamTwo); // Step 5 // Generating data IList <Widget> data = new List <Widget>(); for (int i = 0; i < 10; i++) { Widget widget = new Widget(); widget.Time = DateTime.UtcNow.AddSeconds(i); widget.Temperature = Random.Next(1, 100); widget.Distance = Random.Next(1, 100); data.Add(widget); } /* In stream one, the temperature value will be inserted as Fahrenheit since we have defined the * default uom as Fahrenheit for Temperature in the Widget class. The distance value will be * inserted as kilometer, as we have overridden the Distance property in stream one, * regardless of the default uom for Distance in the Widget class. */ await DataService.InsertValuesAsync <Widget>(sdsStreamOne.Id, data); /* In stream two, the temperature value will be inserted as Fahrenheit and the distance will be inserted as mile. * */ await DataService.InsertValuesAsync <Widget>(sdsStreamTwo.Id, data); // Step 6 /* * The last value stored in stream one. */ Widget widgetFromStreamOne = await DataService.GetLastValueAsync <Widget>(sdsStreamOne.Id); Console.WriteLine($"In stream one, the distance is {widgetFromStreamOne.Distance} kilometers and the temperature is {widgetFromStreamOne.Temperature} degrees fahrenheit"); Console.WriteLine(); /* * The last value stored in stream two. */ Widget widgetFromStreamTwo = await DataService.GetLastValueAsync <Widget>(sdsStreamTwo.Id); Console.WriteLine($"In stream two, the distance is {widgetFromStreamTwo.Distance} miles and the temperature is {widgetFromStreamTwo.Temperature} degrees fahrenheit"); Console.WriteLine(); // Step 7 /* * If you want your data to be in specified uom, you can override your properties while making a call. * In the following, I want the temperature to be in Celsius, and the distance to be in feet. * * Then you can pass IList<SdsStreamPropertyOverride> to DataService while getting values. * */ IList <SdsStreamPropertyOverride> requestOverrides = new List <SdsStreamPropertyOverride>(); requestOverrides.Add(new SdsStreamPropertyOverride() { Uom = "degree celsius", SdsTypePropertyId = "Temperature" }); requestOverrides.Add(new SdsStreamPropertyOverride() { Uom = "foot", SdsTypePropertyId = "Distance" }); /* * In the following call, data will be converted from Fahrenheit to Celsius for the temperature property, * and from kilometer to foot for the distance property. * * Uoms in Stream one (Temperature : Fahrenheit, Distance : Kilometer) * */ widgetFromStreamOne = await DataService.GetLastValueAsync <Widget>(sdsStreamOne.Id, requestOverrides); Console.WriteLine($"In stream one, the distance is {widgetFromStreamOne.Distance} foot and the temperature is {widgetFromStreamOne.Temperature} degrees celsius"); Console.WriteLine(); /* * In the following call, data will be converted from Fahrenheit to Celsius for the temperature property, * and from mile to foot for the distance property. * * Uoms in Stream two (Temperature : Fahrenheit, Distance : Mile) * */ widgetFromStreamTwo = await DataService.GetLastValueAsync <Widget>(sdsStreamTwo.Id, requestOverrides); Console.WriteLine($"In stream two, the distance is {widgetFromStreamTwo.Distance} foot and the temperature is {widgetFromStreamTwo.Temperature} degrees celsius"); Console.WriteLine(); } catch (Exception ex) { success = false; Console.WriteLine(ex.Message); toThrow = ex; } finally { // Step 8 Console.WriteLine("Deleting"); RunInTryCatch(MetadataService.DeleteStreamAsync, StreamWithPropertyOverriden); RunInTryCatch(MetadataService.DeleteStreamAsync, StreamWithoutPropertyOverriden); RunInTryCatch(MetadataService.DeleteTypeAsync, TypeId); if (!test) { Console.ReadLine(); } } if (test && !success) { throw toThrow; } return(success); }
private static async Task MainAsync() { string accountId = ConfigurationManager.AppSettings["accountId"]; string namespaceId = ConfigurationManager.AppSettings["namespaceId"]; string address = ConfigurationManager.AppSettings["address"]; string resource = ConfigurationManager.AppSettings["resource"]; string clientId = ConfigurationManager.AppSettings["clientId"]; string clientSecret = ConfigurationManager.AppSettings["clientSecret"]; string piServerName = ConfigurationManager.AppSettings["PIDataArchive"]; var sdsService = new SdsService(new Uri(address), new SdsSecurityHandler(resource, accountId, clientId, clientSecret)); var metadataService = sdsService.GetMetadataService(accountId, namespaceId); var dataService = sdsService.GetDataService(accountId, namespaceId); var piServer = new PIServers()[piServerName]; piServer.Connect(); PIPointQuery nameFilter = new PIPointQuery { AttributeName = PICommonPointAttributes.Tag, AttributeValue = _options.TagMask, Operator = OSIsoft.AF.Search.AFSearchOperator.Equal }; IEnumerable <string> attributesToRetrieve = new[] { PICommonPointAttributes.Descriptor, PICommonPointAttributes.EngineeringUnits, PICommonPointAttributes.PointSource }; var piPoints = (await PIPoint.FindPIPointsAsync(piServer, new[] { nameFilter }, attributesToRetrieve)).ToList(); if (!piPoints.Any()) { Console.WriteLine($"No points found matching the tagMask query!"); return; } Console.WriteLine($"Found {piPoints.Count} points matching mask: {_options.TagMask}"); //create types await PISdsTypes.CreateOrUpdateTypesInOcsAsync(metadataService); //delete existing streams if requested if (_options.Mode == CommandLineOptions.DataWriteModes.clearExistingData) { Parallel.ForEach(piPoints, piPoint => DeleteStreamBasedOnPIPointAsync(piPoint, metadataService).Wait()); } Parallel.ForEach(piPoints, piPoint => CreateStreamBasedOnPIPointAsync(piPoint, attributesToRetrieve, metadataService).Wait()); Console.WriteLine($"Created or updated {piPoints.Count()} streams."); //for each PIPoint, get the data of interest and write it to OCS Parallel.ForEach(piPoints, piPoint => { //Indices must be unique in OCS so we get rid of duplicate values for a given timestamp var timeRange = new AFTimeRange(_options.StartTime, _options.EndTime); var afValues = piPoint.RecordedValues(timeRange, AFBoundaryType.Inside, null, true) .GroupBy(value => value.Timestamp) .Select(valuesAtTimestamp => valuesAtTimestamp.Last()) //last event for particular timestamp .Where(val => val.IsGood) //System Digital States (e.g. Shutdown, IO Timeout, etc...) are ignored .ToList(); WriteDataToOcsAsync(piPoint, afValues, dataService).Wait(); }); }