Пример #1
0
        static void Main(string[] args)
        {
            Console.WriteLine("Creating a .NET Qi Client...");

            string server  = Constants.QiServerUrl;
            QiType evtType = null;
            QiHttpClientFactory <IQiServer> clientFactory = new QiHttpClientFactory <IQiServer>();

            clientFactory.ProxyTimeout = new TimeSpan(0, 1, 0);
            IQiServer      qiclient = clientFactory.CreateChannel(new Uri(server));
            IQiClientProxy proxy    = (IQiClientProxy)qiclient;

            proxy.OnBeforeInvoke((handler) => {
                string token = AcquireAuthToken();
                if (proxy.Client.DefaultHeaders.Contains("Authorization"))
                {
                    proxy.Client.DefaultHeaders.Remove("Authorization");
                }

                proxy.Client.DefaultHeaders.Add("Authorization", new AuthenticationHeaderValue("Bearer", token).ToString());
            });

            try
            {
                // Create a Qi Type to reflect the event data being stored in Qi.
                // The Qi Client Libraries provide QiTypeBuilder which constructs a QiType object
                // based upon a class you define in your code.
                Console.WriteLine("Creating a Qi type for WaveData instances");
                QiTypeBuilder typeBuilder = new QiTypeBuilder();
                evtType    = typeBuilder.Create <WaveData>();
                evtType.Id = "WaveType";
                QiType tp = qiclient.GetOrCreateType(evtType);

                // now let's create the stream to contain the events
                // specify the type id of the QiType created above in the TypeId property of the QiStream object
                // All events submitted to this stream must be of this type
                Console.WriteLine("Creating a stream for simple event measurements");
                QiStream sampleStream = new QiStream();
                sampleStream.Name        = "evtStream";
                sampleStream.Id          = "evtStream";
                sampleStream.TypeId      = tp.Id;
                sampleStream.Description = "This is a sample stream for storing WaveData type measurements";
                QiStream strm = qiclient.GetOrCreateStream(sampleStream);

                #region CRUD Operations

                #region Create Events (Insert)

                Console.WriteLine("Artificially generating 100 events and inserting them into the Qi Service");

                // Insert a single event into a stream
                TimeSpan span = new TimeSpan(0, 1, 0);
                WaveData evt  = WaveData.Next(span, 2.0, 0);

                qiclient.InsertValue("evtStream", evt);

                // Inserting a collection of events into a stream
                List <WaveData> events = new List <WaveData>();
                for (int i = 2; i < 200; i += 2)
                {
                    WaveData newEvt = WaveData.Next(span, 2.0, i);
                    events.Add(newEvt);
                    Thread.Sleep(400);
                }

                qiclient.InsertValues("evtStream", events);
                Thread.Sleep(2000);

                #endregion

                #region Retrieve events for a time range

                // use the round trip formatting for time
                Console.WriteLine("Retrieving the inserted events");
                Console.WriteLine("==============================");
                IEnumerable <WaveData> foundEvts = qiclient.GetWindowValues <WaveData>("evtStream", "0", "198");
                DumpEvents(foundEvts);
                #endregion

                #region Update an event

                Console.WriteLine();
                Console.WriteLine("Updating values");

                // take the first value inserted and update the value using a multiplier of 4, while retaining the order
                evt = foundEvts.First();
                evt = WaveData.Next(span, 4.0, evt.Order);
                qiclient.UpdateValue("evtStream", evt);

                // update the collection of events (same span, multiplier of 4, retain order)
                List <WaveData> newEvents = new List <WaveData>();
                foreach (WaveData evnt in events)
                {
                    WaveData newEvt = WaveData.Next(span, 4.0, evnt.Order);
                    newEvents.Add(newEvt);
                    Thread.Sleep(500);
                }

                qiclient.UpdateValues("evtStream", newEvents);
                Thread.Sleep(2000);

                Console.WriteLine("Retrieving the updated values");
                Console.WriteLine("=============================");
                foundEvts = qiclient.GetWindowValues <WaveData>("evtStream", "0", "198");
                DumpEvents(foundEvts);

                // illustrate how stream behaviors modify retrieval
                // First, pull three items back with GetRangeValues for range values between events.
                // The default behavior is continuous, so ExactOrCalculated should bring back interpolated values
                Console.WriteLine();
                Console.WriteLine(@"Retrieving three events without a stream behavior");
                foundEvts = qiclient.GetRangeValues <WaveData>("evtStream", "1", 0, 3, false, QiBoundaryType.ExactOrCalculated);
                DumpEvents(foundEvts);

                // now, create a stream behavior with Discrete and attach it to the existing stream
                QiStreamBehavior behavior = new QiStreamBehavior();
                behavior.Id   = "evtStreamStepLeading";
                behavior.Mode = QiStreamMode.StepwiseContinuousLeading;
                behavior      = qiclient.GetOrCreateBehavior(behavior);

                // update the stream to include this behavior
                sampleStream.BehaviorId = behavior.Id;
                qiclient.UpdateStream("evtStream", sampleStream);

                // repeat the retrieval
                Console.WriteLine();
                Console.WriteLine("Retrieving three events with a stepwise stream behavior in effect -- compare to last retrieval");
                foundEvts = qiclient.GetRangeValues <WaveData>("evtStream", "1", 0, 3, false, QiBoundaryType.ExactOrCalculated);
                DumpEvents(foundEvts);

                #endregion

                #region Delete events

                Console.WriteLine();
                Console.WriteLine("Deleting events");
                qiclient.RemoveValue("evtStream", 0);
                qiclient.RemoveWindowValues("evtStream", 2, 198);
                Thread.Sleep(2000);
                Console.WriteLine("Checking for events");
                Console.WriteLine("===================");
                foundEvts = qiclient.GetWindowValues <WaveData>("evtStream", "0", "198");
                DumpEvents(foundEvts);
                Console.WriteLine("Test ran successfully");
                Console.WriteLine("====================");
                Console.WriteLine("Press any button to shutdown");
                Console.ReadLine();
                #endregion
                #endregion
            }
            catch (QiHttpClientException qiex)
            {
                Console.WriteLine("Error in Qi Service Client: " + qiex.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Other error: " + ex.Message);
            }
            finally
            {
                // clean up all created entities so you can run this again
                // all entities are reference counted, so you must delete the stream, then the type it uses
                try
                {
                    qiclient.DeleteStream("evtStream");
                    qiclient.DeleteBehavior("evtStreamStepLeading");
                    qiclient.DeleteType(evtType.Id);
                }
                catch (Exception)
                {
                }
            }
        }
Пример #2
0
        static void Main(string[] args)
        {
            Console.WriteLine("Creating a .NET Qi Client...");

            string server = ConfigurationManager.AppSettings["QiServerUrl"];

            // set up a client to the Qi Service -- it is essential that you set the QiTenant header

            QiHttpClientFactory<IQiServer> clientFactory = new QiHttpClientFactory<IQiServer>();
            clientFactory.ProxyTimeout = new TimeSpan(0, 1, 0);
            clientFactory.OnCreated((p) => p.DefaultHeaders.Add("QiTenant", "sampletenant"));
            IQiServer qiclient = clientFactory.CreateChannel(new Uri(server));

            try
            {
                // TODO -- remove tenant creation when provisioning is accomplished

                Console.WriteLine("Creating a tenant named sampletenant");
                QiTenant tenant = new QiTenant("sampletenant");

                // submit to PI Cloud Historian to create the tenant in storage

                qiclient.GetOrCreateTenant(tenant);

                // Create a Qi Type -- the Qi Libraries let you do this via reflection
                // First, create a type builder, then pass it the name of the class you are using for events.
                // This greatly simplifies type creation

                QiTypeBuilder typeBuilder = new QiTypeBuilder();
                QiType evtType = typeBuilder.Create<SimpleEvent>();
                evtType.Name = "SimpleEvent";
                evtType.Id = "SimpleEvent";

                QiType tp = qiclient.GetOrCreateType(evtType);

                Console.WriteLine("Creating a stream in this tenant for simple event measurements");

                QiStream sampleStream = new QiStream();
                sampleStream.Name = "evtStream";
                sampleStream.Id = "evtStream";

                // set the TypeId property to the value of the Id property of the type you submitted
                // All events submitted to this stream must be of this type
                // Note there are Async versions of the client methods, too, using .NET TPL
                sampleStream.TypeId = "SimpleEvent";
                sampleStream.Description = "This is a sample stream for storing SimpleEvent type measurements";
                QiStream strm = qiclient.GetOrCreateStream(sampleStream);

                #region CRUD Operations

                #region Create Events (Insert)

                Console.WriteLine("Artificially generating 100 events at one second intervals and inserting them into the Qi Service");
                Random rnd = new Random();

                // How to insert a single event
                SimpleEvent evt = new SimpleEvent(rnd.NextDouble() * 100, "deg C");

                // for our contrived purposes, let's manually set the timestamp to 100 seconds in the past
                DateTime start = DateTime.UtcNow.AddSeconds(-100.0);
                evt.Timestamp = start;
                qiclient.InsertValue("evtStream", evt);

                List<SimpleEvent> events = new List<SimpleEvent>();
                // how to insert an a collection of events
                for (int i = 1; i < 100; i++)
                {
                    evt = new SimpleEvent(rnd.NextDouble() * 100, "deg C");
                    evt.Timestamp = start.AddSeconds((double)i);
                    events.Add(evt);
                }

                qiclient.InsertValues<SimpleEvent>("evtStream", events);
                Thread.Sleep(2000);

                #endregion

                #region Retrieve events for a time range

                // use the round trip formatting for time
                Console.WriteLine("Retrieving the inserted events");
                Console.WriteLine("==============================");
                IEnumerable<SimpleEvent> foundEvts = qiclient.GetWindowValues<SimpleEvent>("evtStream", start.ToString("o"), DateTime.UtcNow.ToString("o"));
                DumpEvents(foundEvts);
                #endregion

                #region Update an event

                Console.WriteLine();
                Console.WriteLine("Updating values");

                // take the first value inserted and update the value and UOM
                evt = foundEvts.First<SimpleEvent>();
                evt.Units = "deg F";
                evt.Value = 212.0;
                qiclient.UpdateValue<SimpleEvent>("evtStream", evt);

                // update the collection of events (convert to deg F)
                foreach (SimpleEvent evnt in events)
                {
                    evnt.Units = "deg F";
                    evnt.Value = evnt.Value * 9 / 5 + 32.0;
                }

                qiclient.UpdateValues<SimpleEvent>("evtStream", events);
                Thread.Sleep(2000);

                Console.WriteLine("Retrieving the updated values");
                Console.WriteLine("=============================");
                foundEvts = qiclient.GetWindowValues<SimpleEvent>("evtStream", start.ToString("o"), DateTime.UtcNow.ToString("o"));
                DumpEvents(foundEvts);

                #endregion

                #region Delete events

                Console.WriteLine();
                Console.WriteLine("Deleting events");
                qiclient.RemoveValue<DateTime>("evtStream", evt.Timestamp);
                qiclient.RemoveWindowValues("evtStream", foundEvts.First<SimpleEvent>().Timestamp.ToString("o"), foundEvts.Last<SimpleEvent>().Timestamp.ToString("o"));
                Thread.Sleep(2000);
                Console.WriteLine("Checking for events");
                Console.WriteLine("===================");
                foundEvts = qiclient.GetWindowValues<SimpleEvent>("evtStream", start.ToString("o"), DateTime.UtcNow.ToString("o"));
                DumpEvents(foundEvts);
                #endregion
                #endregion

            }
            catch (QiHttpClientException qiex)
            {
                Console.WriteLine("Error in Qi Service Client: " + qiex.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Other error: " + ex.Message);
            }
            finally
            {
                // clean up all created entities so you can run this again
                // all entities are reference counted, so you must delete the stream, then the type it uses
                try
                {

                    qiclient.DeleteStream("evtStream");
                }
                catch (Exception exStrm)
                {
                    Console.WriteLine("Error deleting stream, type is left: " + exStrm.Message);
                }
                try
                {

                    qiclient.DeleteType("SimpleEvent");
                }
                catch (Exception exTyp)
                {
                    Console.WriteLine("Error deleting stream: " + exTyp.Message);
                }
                try
                {
                    qiclient.DeleteTenant("sampletenant");
                }
                catch (Exception exTnt)
                {
                    Console.WriteLine("Error deleting tenant: " + exTnt.Message);
                }
                Console.WriteLine("Press ENTER to finish");
                Console.ReadLine();

            }
        }
Пример #3
0
        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 behaviorId      = "SampleBehavior";
            string targetTypeId    = "SampleType_Target";
            string targetIntTypeId = "SampleType_TargetInt";
            string autoViewId      = "SampleAutoView";
            string manualViewId    = "SampleManualView";

            // Get Qi Services to communicate with server
            QiSecurityHandler securityHandler = new QiSecurityHandler(resource, tenantId, clientId, clientKey);

            QiService qiService       = new QiService(new Uri(address), securityHandler);
            var       metadataService = qiService.GetMetadataService(tenantId, namespaceId);
            var       dataService     = qiService.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($"Qi endpoint at {address}");
            Console.WriteLine();

            try
            {
                // create a QiType
                Console.WriteLine("Creating a QiType");
                QiType type = QiTypeBuilder.CreateQiType <WaveData>();
                type.Id = typeId;
                type    = await metadataService.GetOrCreateTypeAsync(type);

                // create a QiStream
                Console.WriteLine("Creating a QiStream");
                var stream = new QiStream
                {
                    Id          = streamId,
                    Name        = "Wave Data Sample",
                    TypeId      = type.Id,
                    Description = "This is a sample QiStream 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();

                // Stream behaviors
                Console.WriteLine("QiStreamBehaviors determine whether Qi interpolates or extrapolates data at the requested index location");
                Console.WriteLine();

                // Stream behaviors modify retrieval.  We will retrieve three events using the default behavior, Continuous
                var retrieved = await dataService
                                .GetRangeValuesAsync <WaveData>(stream.Id, "1", 3, QiBoundaryType.ExactOrCalculated);

                Console.WriteLine("Default (Continuous) stream behavior, requesting data starting at index location '1', Qi will interpolate this value:");
                foreach (var value in retrieved)
                {
                    Console.WriteLine($"Order: {value.Order}, Radians: {value.Radians}");
                }
                Console.WriteLine();

                // create a Discrete stream behavior
                var behavior = new QiStreamBehavior
                {
                    Id   = behaviorId,
                    Mode = QiStreamMode.Discrete
                };
                behavior = await metadataService.GetOrCreateBehaviorAsync(behavior);

                // update the stream
                stream.BehaviorId = behavior.Id;
                await metadataService.CreateOrUpdateStreamAsync(stream);

                retrieved = await dataService
                            .GetRangeValuesAsync <WaveData>(stream.Id, "1", 3, QiBoundaryType.ExactOrCalculated);

                Console.WriteLine("Discrete stream behavior, Qi does not interpolate and returns the data starting at the next index location containing data:");
                foreach (var value in retrieved)
                {
                    Console.WriteLine($"Order: {value.Order}, Radians: {value.Radians}");
                }
                Console.WriteLine();

                // Stream views
                Console.WriteLine("QiViews");

                // create target types
                var targetType = QiTypeBuilder.CreateQiType <WaveDataTarget>();
                targetType.Id = targetTypeId;

                var targetIntType = QiTypeBuilder.CreateQiType <WaveDataInteger>();
                targetIntType.Id = targetIntTypeId;

                await metadataService.CreateOrUpdateTypeAsync(targetType);

                await metadataService.CreateOrUpdateTypeAsync(targetIntType);

                // create views
                var autoView = new QiView()
                {
                    Id           = autoViewId,
                    SourceTypeId = typeId,
                    TargetTypeId = targetTypeId
                };

                // create explicit mappings
                var vp1 = new QiViewProperty()
                {
                    SourceId = "Order", TargetId = "OrderTarget"
                };
                var vp2 = new QiViewProperty()
                {
                    SourceId = "Sin", TargetId = "SinInt"
                };
                var vp3 = new QiViewProperty()
                {
                    SourceId = "Cos", TargetId = "CosInt"
                };
                var vp4 = new QiViewProperty()
                {
                    SourceId = "Tan", TargetId = "TanInt"
                };

                var manualView = new QiView()
                {
                    Id           = manualViewId,
                    SourceTypeId = typeId,
                    TargetTypeId = targetIntTypeId,
                    Properties   = new List <QiViewProperty>()
                    {
                        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, QiBoundaryType.ExactOrCalculated, autoViewId);

                Console.WriteLine("Specifying a view with a QiType of the same shape returns values that are automatically mapped to the target QiType'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("QiViews 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, QiBoundaryType.ExactOrCalculated, manualViewId);

                foreach (var value in manualViewData)
                {
                    Console.WriteLine($"SinInt: {value.SinInt} CosInt: {value.CosInt} TanInt: {value.TanInt}");
                }
                Console.WriteLine();

                // get QiViewMap
                Console.WriteLine("We can query Qi to return the QiViewMap for our QiView, here is the one generated automatically:");
                var autoViewMap = await metadataService.GetViewMapAsync(autoViewId);

                PrintViewMapProperties(autoViewMap);

                Console.WriteLine("Here is our explicit mapping, note QiViewMap will return all properties of the Source Type, even those without a corresponding Target property:");
                var manualViewMap = await metadataService.GetViewMapAsync(manualViewId);

                PrintViewMapProperties(manualViewMap);

                // delete values
                Console.WriteLine("Deleting values from the QiStream");

                // 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, views and behavior
                Console.WriteLine("Deleteing stream");
                await metadataService.DeleteStreamAsync(streamId);

                Console.WriteLine("Deleteing types");
                await metadataService.DeleteTypeAsync(typeId);

                await metadataService.DeleteTypeAsync(targetTypeId);

                await metadataService.DeleteTypeAsync(targetIntTypeId);

                Console.WriteLine("Deleteing views");
                await metadataService.DeleteViewAsync(autoViewId);

                await metadataService.DeleteViewAsync(manualViewId);

                Console.WriteLine("Deleteing behavior");
                await metadataService.DeleteBehaviorAsync(behaviorId);

                Console.WriteLine("done");
                Console.ReadKey();
            }
        }
Пример #4
0
        static void Main(string[] args)
        {
            Console.WriteLine("Creating a .NET Qi Client...");

            string server = ConfigurationManager.AppSettings["QiServerUrl"];

            // set up a client to the Qi Service -- it is essential that you set the QiTenant header

            QiHttpClientFactory <IQiServer> clientFactory = new QiHttpClientFactory <IQiServer>();

            clientFactory.ProxyTimeout = new TimeSpan(0, 1, 0);
            clientFactory.OnCreated((p) => p.DefaultHeaders.Add("QiTenant", "sampletenant"));
            IQiServer qiclient = clientFactory.CreateChannel(new Uri(server));

            try
            {
                // TODO -- remove tenant creation when provisioning is accomplished

                Console.WriteLine("Creating a tenant named sampletenant");
                QiTenant tenant = new QiTenant("sampletenant");

                // submit to PI Cloud Historian to create the tenant in storage

                qiclient.GetOrCreateTenant(tenant);

                // Create a Qi Type -- the Qi Libraries let you do this via reflection
                // First, create a type builder, then pass it the name of the class you are using for events.
                // This greatly simplifies type creation

                QiTypeBuilder typeBuilder = new QiTypeBuilder();
                QiType        evtType     = typeBuilder.Create <SimpleEvent>();
                evtType.Name = "SimpleEvent";
                evtType.Id   = "SimpleEvent";

                QiType tp = qiclient.GetOrCreateType(evtType);

                Console.WriteLine("Creating a stream in this tenant for simple event measurements");

                QiStream sampleStream = new QiStream();
                sampleStream.Name = "evtStream";
                sampleStream.Id   = "evtStream";

                // set the TypeId property to the value of the Id property of the type you submitted
                // All events submitted to this stream must be of this type
                // Note there are Async versions of the client methods, too, using .NET TPL
                sampleStream.TypeId      = "SimpleEvent";
                sampleStream.Description = "This is a sample stream for storing SimpleEvent type measurements";
                QiStream strm = qiclient.GetOrCreateStream(sampleStream);

                #region CRUD Operations

                #region Create Events (Insert)

                Console.WriteLine("Artificially generating 100 events at one second intervals and inserting them into the Qi Service");
                Random rnd = new Random();

                // How to insert a single event
                SimpleEvent evt = new SimpleEvent(rnd.NextDouble() * 100, "deg C");

                // for our contrived purposes, let's manually set the timestamp to 100 seconds in the past
                DateTime start = DateTime.UtcNow.AddSeconds(-100.0);
                evt.Timestamp = start;
                qiclient.InsertValue("evtStream", evt);

                List <SimpleEvent> events = new List <SimpleEvent>();
                // how to insert an a collection of events
                for (int i = 1; i < 100; i++)
                {
                    evt           = new SimpleEvent(rnd.NextDouble() * 100, "deg C");
                    evt.Timestamp = start.AddSeconds((double)i);
                    events.Add(evt);
                }

                qiclient.InsertValues <SimpleEvent>("evtStream", events);
                Thread.Sleep(2000);

                #endregion


                #region Retrieve events for a time range

                // use the round trip formatting for time
                Console.WriteLine("Retrieving the inserted events");
                Console.WriteLine("==============================");
                IEnumerable <SimpleEvent> foundEvts = qiclient.GetWindowValues <SimpleEvent>("evtStream", start.ToString("o"), DateTime.UtcNow.ToString("o"));
                DumpEvents(foundEvts);
                #endregion

                #region Update an event

                Console.WriteLine();
                Console.WriteLine("Updating values");

                // take the first value inserted and update the value and UOM
                evt       = foundEvts.First <SimpleEvent>();
                evt.Units = "deg F";
                evt.Value = 212.0;
                qiclient.UpdateValue <SimpleEvent>("evtStream", evt);

                // update the collection of events (convert to deg F)
                foreach (SimpleEvent evnt in events)
                {
                    evnt.Units = "deg F";
                    evnt.Value = evnt.Value * 9 / 5 + 32.0;
                }

                qiclient.UpdateValues <SimpleEvent>("evtStream", events);
                Thread.Sleep(2000);

                Console.WriteLine("Retrieving the updated values");
                Console.WriteLine("=============================");
                foundEvts = qiclient.GetWindowValues <SimpleEvent>("evtStream", start.ToString("o"), DateTime.UtcNow.ToString("o"));
                DumpEvents(foundEvts);

                #endregion

                #region Delete events

                Console.WriteLine();
                Console.WriteLine("Deleting events");
                qiclient.RemoveValue <DateTime>("evtStream", evt.Timestamp);
                qiclient.RemoveWindowValues("evtStream", foundEvts.First <SimpleEvent>().Timestamp.ToString("o"), foundEvts.Last <SimpleEvent>().Timestamp.ToString("o"));
                Thread.Sleep(2000);
                Console.WriteLine("Checking for events");
                Console.WriteLine("===================");
                foundEvts = qiclient.GetWindowValues <SimpleEvent>("evtStream", start.ToString("o"), DateTime.UtcNow.ToString("o"));
                DumpEvents(foundEvts);
                #endregion
                #endregion
            }
            catch (QiHttpClientException qiex)
            {
                Console.WriteLine("Error in Qi Service Client: " + qiex.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Other error: " + ex.Message);
            }
            finally
            {
                // clean up all created entities so you can run this again
                // all entities are reference counted, so you must delete the stream, then the type it uses
                try
                {
                    qiclient.DeleteStream("evtStream");
                }
                catch (Exception exStrm)
                {
                    Console.WriteLine("Error deleting stream, type is left: " + exStrm.Message);
                }
                try
                {
                    qiclient.DeleteType("SimpleEvent");
                }
                catch (Exception exTyp)
                {
                    Console.WriteLine("Error deleting stream: " + exTyp.Message);
                }
                try
                {
                    qiclient.DeleteTenant("sampletenant");
                }
                catch (Exception exTnt)
                {
                    Console.WriteLine("Error deleting tenant: " + exTnt.Message);
                }
                Console.WriteLine("Press ENTER to finish");
                Console.ReadLine();
            }
        }
Пример #5
0
        private static void Main(string[] args)
        {
            // ==== Client constants ====
            var tenant   = ConfigurationManager.AppSettings["Tenant"];
            var address  = ConfigurationManager.AppSettings["Address"];
            var resource = ConfigurationManager.AppSettings["Resource"];
            var appId    = ConfigurationManager.AppSettings["AppId"];
            var appKey   = ConfigurationManager.AppSettings["AppKey"];

            var namespaceId = ConfigurationManager.AppSettings["Namespace"];

            // ==== Setup the namespace.  The namespace provides isolation within a Tenant. ====
            var admin = QiService.GetAdministrationService(new Uri(address), tenant, new QiSecurityHandler(resource, tenant, appId, appKey));

            var sampleNamespace = new QiNamespace(namespaceId);

            sampleNamespace = admin.GetOrCreateNamespaceAsync(sampleNamespace).GetAwaiter().GetResult();

            // ==== Setup the type and stream ====
            var config = QiService.GetMetadataService(new Uri(address), tenant, namespaceId, new QiSecurityHandler(resource, tenant, appId, appKey));

            QiType type = QiTypeBuilder.CreateQiType <WaveData>();

            type = config.GetOrCreateTypeAsync(type).GetAwaiter().GetResult();

            var stream = new QiStream
            {
                Id          = Guid.NewGuid().ToString(),
                Name        = "Wave Data Sample",
                TypeId      = type.Id,
                Description = "This is a sample QiStream for storing WaveData type measurements"
            };

            stream = config.GetOrCreateStreamAsync(stream).GetAwaiter().GetResult();

            // ==== Perform a number of CRUD opreations ====
            var client = QiService.GetDataService(new Uri(address), tenant, namespaceId, new QiSecurityHandler(resource, tenant, appId, appKey));

            // Insert a single event into a stream
            var wave = GetWave(0, 200, 2);

            client.InsertValueAsync(stream.Id, wave).GetAwaiter().GetResult();

            // Update will add the event as well
            wave.Order += 1;
            client.UpdateValueAsync(stream.Id, wave).GetAwaiter().GetResult();

            // Inserting a collection of events into a stream (more efficient)
            var waves = new List <WaveData>();

            for (var i = 2; i <= 200; ++i)
            {
                waves.Add(GetWave(i, 200, 2));
            }

            client.InsertValuesAsync(stream.Id, waves).GetAwaiter().GetResult();

            // Retrieve events for a the range.  Indexes are expected in string format.  Order property is is the Key
            IEnumerable <WaveData> retrieved = client.GetWindowValuesAsync <WaveData>(stream.Id, "0", "200").GetAwaiter().GetResult();

            Console.WriteLine("Retrieved {0} events", retrieved.Count());
            Console.WriteLine("\tfrom {0} {1}", retrieved.First().Order, retrieved.First().Sin);
            Console.WriteLine("\tto {0} {1}", retrieved.Last().Order, retrieved.Last().Sin);

            // Update some events
            UpdateWave(retrieved.First(), 4);
            client.UpdateValueAsync(stream.Id, retrieved.First()).GetAwaiter().GetResult();

            foreach (var value in waves)
            {
                UpdateWave(value, 4);
            }

            client.UpdateValuesAsync(stream.Id, waves.ToList()).GetAwaiter().GetResult();

            retrieved = client.GetWindowValuesAsync <WaveData>(stream.Id, "0", "200").GetAwaiter().GetResult();
            Console.WriteLine("Updated {0} events", retrieved.Count());
            Console.WriteLine("\tfrom {0} {1}", retrieved.First().Order, retrieved.First().Sin);
            Console.WriteLine("\tto {0} {1}", retrieved.Last().Order, retrieved.Last().Sin);

            // Stream behaviors modify retrieval
            // Retrieve a range of three values using the default behavior.  The default behavior is Continuous,
            // so ExactOrCalculated should bring back interpolated values
            retrieved = client.GetRangeValuesAsync <WaveData>(stream.Id, "1", 0, 3, false, QiBoundaryType.ExactOrCalculated).GetAwaiter().GetResult();
            Console.WriteLine("Default behavior {0} events", retrieved.Count());
            foreach (var value in retrieved)
            {
                Console.WriteLine("\t{0} {1}", value.Order, value.Sin);
            }

            // Modify the stream behavior to StepwiseContinuousLeading
            var stepwiseContinuousLeading = new QiStreamBehavior
            {
                Id   = Guid.NewGuid().ToString(),
                Mode = QiStreamMode.StepwiseContinuousLeading
            };

            stepwiseContinuousLeading = config.GetOrCreateBehaviorAsync(stepwiseContinuousLeading).GetAwaiter().GetResult();

            stream.BehaviorId = stepwiseContinuousLeading.Id;
            config.UpdateStreamAsync(stream.Id, stream).GetAwaiter().GetResult();

            retrieved = client.GetRangeValuesAsync <WaveData>(stream.Id, "1", 0, 3, false, QiBoundaryType.ExactOrCalculated).GetAwaiter().GetResult();
            Console.WriteLine("StepwiseContinuousLeading behavior {0} events", retrieved.Count());
            foreach (var value in retrieved)
            {
                Console.WriteLine("\t{0} {1}", value.Order, value.Sin);
            }

            // Delete the first event in the stream, the event at index zero
            client.RemoveValueAsync(stream.Id, 0).GetAwaiter().GetResult();

            // Delete the rest of the Events
            client.RemoveWindowValuesAsync(stream.Id, 1, 200).GetAwaiter().GetResult();

            retrieved = client.GetWindowValuesAsync <WaveData>(stream.Id, "0", "200").GetAwaiter().GetResult();
            Console.WriteLine("After delete {0} events remain", retrieved.Count());

            // Delete the stream and behavior
            config.DeleteStreamAsync(stream.Id).GetAwaiter().GetResult();
            config.DeleteBehaviorAsync(stepwiseContinuousLeading.Id).GetAwaiter().GetResult();

            // It is less common to remove the type and namespace
            config.DeleteTypeAsync(type.Id).GetAwaiter().GetResult();
            // admin.DeleteNamespaceAsync(sampleNamespace.Id).GetAwaiter().GetResult();
        }
Пример #6
0
        static void Main(string[] args)
        {
            Console.WriteLine("Creating a .NET Qi Client...");

            string server = ConfigurationManager.AppSettings["QiServerUrl"];
            QiType evtType = null;

            ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
            QiHttpClientFactory<IQiServer> clientFactory = new QiHttpClientFactory<IQiServer>();
            clientFactory.ProxyTimeout = new TimeSpan(0, 1, 0);

            IQiServer qiclient = clientFactory.CreateChannel(new Uri(server));
            IQiClientProxy proxy = (IQiClientProxy)qiclient;
            proxy.OnBeforeInvoke((handler)=>{
                string token = AcquireAuthToken();
                if (proxy.Client.DefaultHeaders.Contains("Authorization"))
                {
                    proxy.Client.DefaultHeaders.Remove("Authorization");
                }

                proxy.Client.DefaultHeaders.Add("Authorization", new AuthenticationHeaderValue("Bearer", token).ToString());

            });

            try
            {
                // Create a Qi Type -- the Qi Libraries let you do this via reflection
                // First, create a type builder, then pass it the name of the class you are using for events.
                // This greatly simplifies type creation

                Console.WriteLine("Creating a Qi type for WaveData instances");
                QiTypeBuilder typeBuilder = new QiTypeBuilder();
                evtType = typeBuilder.Create<WaveData>();
                evtType.Id = "WaveType";
                QiType tp = qiclient.GetOrCreateType(evtType);

                Console.WriteLine("Creating a stream in this tenant for simple event measurements");

                QiStream sampleStream = new QiStream();
                sampleStream.Name = "evtStream";
                sampleStream.Id = "evtStream";

                // set the TypeId property to the value of the Id property of the type you submitted
                // All events submitted to this stream must be of this type
                // Note there are Async versions of the client methods, too, using .NET TPL
                sampleStream.TypeId = tp.Id;
                sampleStream.Description = "This is a sample stream for storing WaveData type measurements";
                QiStream strm = qiclient.GetOrCreateStream(sampleStream);

                #region CRUD Operations

                #region Create Events (Insert)

                Console.WriteLine("Artificially generating 100 events and inserting them into the Qi Service");

                // How to insert a single event
                TimeSpan span = new TimeSpan(0, 1, 0);
                WaveData evt = WaveData.Next(span, 2.0, 0);

                qiclient.InsertValue("evtStream", evt);

                List<WaveData> events = new List<WaveData>();
                // how to insert an a collection of events
                for (int i = 2; i < 200; i+=2)
                {
                    WaveData newEvt = WaveData.Next(span, 2.0, i);
                    events.Add(newEvt);
                    Thread.Sleep(400);
                }

                qiclient.InsertValues<WaveData>("evtStream", events);
                Thread.Sleep(2000);

                #endregion

                #region Retrieve events for a time range

                // use the round trip formatting for time
                Console.WriteLine("Retrieving the inserted events");
                Console.WriteLine("==============================");
                IEnumerable<WaveData> foundEvts = qiclient.GetWindowValues<WaveData>("evtStream", "0", "198");
                DumpEvents(foundEvts);
                #endregion

                #region Update an event

                Console.WriteLine();
                Console.WriteLine("Updating values");

                // take the first value inserted and update the value using a multiplier of 4, while retaining the order
                evt = foundEvts.First<WaveData>();
                evt = WaveData.Next(span, 4.0, evt.Order);

                qiclient.UpdateValue<WaveData>("evtStream", evt);

                // update the collection of events (same span, multiplier of 4, retain order)
                List<WaveData> newEvents = new List<WaveData>();
                foreach (WaveData evnt in events)
                {
                    WaveData newEvt = WaveData.Next(span, 4.0, evnt.Order);
                    newEvents.Add(newEvt);
                    Thread.Sleep(500);
                }

                qiclient.UpdateValues<WaveData>("evtStream", newEvents);
                Thread.Sleep(2000);

                Console.WriteLine("Retrieving the updated values");
                Console.WriteLine("=============================");
                foundEvts = qiclient.GetWindowValues<WaveData>("evtStream", "0", "198");
                DumpEvents(foundEvts);

                // illustrate how stream behaviors modify retrieval
                // First, pull three items back with GetRangeValues for range values between events.
                // The default behavior is continuous, so ExactOrCalculated should bring back interpolated values
                Console.WriteLine();
                Console.WriteLine(@"Retrieving three events without a stream behavior");
                foundEvts = qiclient.GetRangeValues<WaveData>("evtStream", "1", 0, 3, false, QiBoundaryType.ExactOrCalculated);
                DumpEvents(foundEvts);

                // now, create a stream behavior with Discrete and attach it to the existing stream
                QiStreamBehavior behavior = new QiStreamBehavior();
                behavior.Id = "evtStreamStepLeading";
                behavior.Mode = QiStreamMode.StepwiseContinuousLeading;
                behavior = qiclient.GetOrCreateBehavior(behavior);

                // update the stream to include this behavior
                sampleStream.BehaviorId = behavior.Id;
                qiclient.UpdateStream("evtStream", sampleStream);

                // repeat the retrieval
                Console.WriteLine();
                Console.WriteLine("Retrieving three events with a stepwise stream behavior in effect -- compare to last retrieval");
                foundEvts = qiclient.GetRangeValues<WaveData>("evtStream", "1", 0, 3, false, QiBoundaryType.ExactOrCalculated);
                DumpEvents(foundEvts);

                #endregion

                #region Delete events

                Console.WriteLine();
                Console.WriteLine("Deleting events");
                qiclient.RemoveValue<int>("evtStream", 0);
                qiclient.RemoveWindowValues<int>("evtStream", 2, 198);
                Thread.Sleep(2000);
                Console.WriteLine("Checking for events");
                Console.WriteLine("===================");
                foundEvts = qiclient.GetWindowValues<WaveData>("evtStream", "0", "198");
                DumpEvents(foundEvts);
                #endregion
                #endregion

            }
            catch (QiHttpClientException qiex)
            {
                Console.WriteLine("Error in Qi Service Client: " + qiex.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Other error: " + ex.Message);
            }
            finally
            {
                // clean up all created entities so you can run this again
                // all entities are reference counted, so you must delete the stream, then the type it uses
                try
                {

                    qiclient.DeleteStream("evtStream");
                    qiclient.DeleteBehavior("evtStreamStepLeading");
                    qiclient.DeleteType(evtType.Id);
                }
                catch (Exception)
                {

                }
            }
        }
Пример #7
0
        public static void Main(string[] args)
        {
            string sampleNamespaceId = "WaveData_SampleNamespace";
            string sampleTypeId = "WaveData_SampleType";
            string sampleStreamId = "WaveData_SampleStream";
            string sampleBehaviorId = "WaveData_SampleBehavior";

            Console.WriteLine("Creating a .NET Qi Administration Service...");
            IQiAdministrationService qiAdministrationService = GetQiAdministrationService();

            Console.WriteLine("Creating a .NET Qi Metadata Service...");
            IQiMetadataService qiMetadataService = GetQiMetadataService(sampleNamespaceId);

            Console.WriteLine("Creating a .NET Qi Data Service...");
            IQiDataService qiDataService = GetQiDataService(sampleNamespaceId);

            try
            {
                // Create a QiNamespace to hold the streams, types, and behaviors
                Console.WriteLine("Creating a QiNamespace to hold the streams, types, and behaviors");
                QiNamespace sampleNamespace = new QiNamespace(sampleNamespaceId);
                sampleNamespace = qiAdministrationService.GetOrCreateNamespaceAsync(sampleNamespace).GetAwaiter().GetResult();
                
                DelayForQiConsistency();

                // Create a Qi Type to reflect the event data being stored in Qi.
                // The Qi Client Libraries provide QiTypeBuilder which constructs a QiType object 
                // based upon a class you define in your code.  
                Console.WriteLine("Creating a Qi type for WaveData instances");
                QiTypeBuilder typeBuilder = new QiTypeBuilder();
                QiType sampleType = typeBuilder.Create<WaveData>();
                sampleType.Id = sampleTypeId;
                sampleType = qiMetadataService.GetOrCreateTypeAsync(sampleType).GetAwaiter().GetResult();

                DelayForQiConsistency();

                // now let's create the stream to contain the events
                // specify the type id of the QiType created above in the TypeId property of the QiStream object
                // All events submitted to this stream must be of this type
                Console.WriteLine("Creating a stream for simple event measurements");
                QiStream sampleStream = new QiStream()
                {
                    Name = "Wave Data Sample Stream",
                    Id = sampleStreamId,
                    TypeId = sampleTypeId,
                    Description = "This is a sample QiStream for storing WaveData type measurements"
                };

                sampleStream = qiMetadataService.GetOrCreateStreamAsync(sampleStream).GetAwaiter().GetResult();

                DelayForQiConsistency();

                #region CRUD Operations

                #region Create Events (Insert)

                Console.WriteLine("Artificially generating 100 events and inserting them into the Qi Service");

                // Insert a single event into a stream
                TimeSpan span = new TimeSpan(0, 1, 0);
                WaveData waveDataEvent = WaveData.Next(span, 2.0, 0);

                Console.WriteLine("Inserting the first event");
                qiDataService.InsertValueAsync(sampleStreamId, waveDataEvent).GetAwaiter().GetResult();

                // Inserting a collection of events into a stream
                List<WaveData> waveDataEvents = new List<WaveData>();
                for (int i = 2; i < 200; i += 2)
                {
                    waveDataEvent = WaveData.Next(span, 2.0, i);
                    waveDataEvents.Add(waveDataEvent);
                }

                Console.WriteLine("Inserting the rest of the events");
                qiDataService.InsertValuesAsync(sampleStreamId, waveDataEvents).GetAwaiter().GetResult();

                DelayForQiConsistency();

                #endregion

                #region Retrieve events for a time range

                // use the round trip formatting for time
                Console.WriteLine("Retrieving the inserted events");
                Console.WriteLine("==============================");
                IEnumerable<WaveData> foundEvents = qiDataService.GetWindowValuesAsync<WaveData>(sampleStreamId, "0", "198").GetAwaiter().GetResult();
                DumpEvents(foundEvents);
                #endregion

                #region Update an event

                Console.WriteLine();
                Console.WriteLine("Updating the first event");

                // take the first value inserted and update the value using a multiplier of 4, while retaining the order
                waveDataEvent = foundEvents.First();
                waveDataEvent = WaveData.Next(span, 4.0, waveDataEvent.Order);
                qiDataService.UpdateValueAsync(sampleStreamId, waveDataEvent).GetAwaiter().GetResult();

                // update the collection of events (same span, multiplier of 4, retain order)
                waveDataEvents = new List<WaveData>();
                foreach (WaveData evnt in waveDataEvents)
                {
                    waveDataEvent = WaveData.Next(span, 4.0, evnt.Order);
                    waveDataEvents.Add(waveDataEvent);
                }

                Console.WriteLine("Updating the rest of the events");
                qiDataService.UpdateValuesAsync(sampleStreamId, waveDataEvents).GetAwaiter().GetResult();

                DelayForQiConsistency();

                Console.WriteLine("Retrieving the updated values");
                Console.WriteLine("=============================");
                foundEvents = qiDataService.GetWindowValuesAsync<WaveData>(sampleStreamId, "0", "198").GetAwaiter().GetResult();
                DumpEvents(foundEvents);

                // illustrate how stream behaviors modify retrieval
                // First, pull three items back with GetRangeValues for range values between events.
                // The default behavior is continuous, so ExactOrCalculated should bring back interpolated values
                Console.WriteLine();
                Console.WriteLine(@"Retrieving three events without a stream behavior");
                foundEvents = qiDataService.GetRangeValuesAsync<WaveData>(sampleStreamId, "1", 0, 3, false, QiBoundaryType.ExactOrCalculated).GetAwaiter().GetResult();
                DumpEvents(foundEvents);

                // now, create a stream behavior with Discrete and attach it to the existing stream
                Console.WriteLine("Creating a QiStreamBehavior");
                QiStreamBehavior sampleBehavior = new QiStreamBehavior()
                {
                    Id = sampleBehaviorId,
                    Mode = QiStreamMode.StepwiseContinuousLeading
                };
                sampleBehavior = qiMetadataService.GetOrCreateBehaviorAsync(sampleBehavior).GetAwaiter().GetResult();

                DelayForQiConsistency();

                // update the stream to include this behavior
                Console.WriteLine("Updating the QiStream with the new QiStreamBehaivor");
                sampleStream.BehaviorId = sampleBehaviorId;
                qiMetadataService.UpdateStreamAsync(sampleStreamId, sampleStream).GetAwaiter().GetResult();

                DelayForQiConsistency();

                // repeat the retrieval
                Console.WriteLine();
                Console.WriteLine("Retrieving three events with a stepwise stream behavior in effect -- compare to last retrieval");
                foundEvents = qiDataService.GetRangeValuesAsync<WaveData>(sampleStreamId, "1", 0, 3, false, QiBoundaryType.ExactOrCalculated).GetAwaiter().GetResult();
                DumpEvents(foundEvents);

                #endregion

                #region Delete events

                Console.WriteLine();
                Console.WriteLine("Deleting first event");
                qiDataService.RemoveValueAsync(sampleStreamId, 0).GetAwaiter().GetResult();
                Console.WriteLine("Deleting the rest of the events");
                qiDataService.RemoveWindowValuesAsync(sampleStreamId, 2, 198).GetAwaiter().GetResult();

                DelayForQiConsistency();

                Console.WriteLine("Checking for events");
                Console.WriteLine("===================");
                foundEvents = qiDataService.GetWindowValuesAsync<WaveData>(sampleStreamId, "0", "198").GetAwaiter().GetResult();
                DumpEvents(foundEvents);
                Console.WriteLine("Test ran successfully");
                Console.WriteLine("====================");
                Console.WriteLine("Press any button to shutdown");
                Console.ReadLine();

                #endregion
                
                #endregion
            }
            catch (QiHttpClientException qerr)
            {
                PrintError("Error in Qi Service", qerr);
            }
            catch (Exception ex)
            {
                PrintError("Unknown Error", ex);
            }
            finally
            {
                // clean up all created entities so you can run this again
                // all entities are reference counted, so you must delete the stream, then the type it uses
                Console.WriteLine("Deleting the stream...");
                HandleQiCallAsync(async () => await qiMetadataService.DeleteStreamAsync(sampleStreamId)).GetAwaiter().GetResult();

                Console.WriteLine("Deleting the behavior...");
                HandleQiCallAsync(async () => await qiMetadataService.DeleteBehaviorAsync(sampleBehaviorId)).GetAwaiter().GetResult();

                Console.WriteLine("Deleting the type...");
                HandleQiCallAsync(async () => await qiMetadataService.DeleteTypeAsync(sampleTypeId)).GetAwaiter().GetResult();
            }
        }
Пример #8
0
        static void Main(string[] args)
        {
            Console.WriteLine("Creating a .NET Qi Client...");

            string server  = ConfigurationManager.AppSettings["QiServerUrl"];
            QiType evtType = null;

            // acquire an authentication token from Azure AD

            string token = AcquireAuthToken();

            // set up a client to the Qi Service -- it is essential that you set the QiTenant header

            QiHttpClientFactory <IQiServer> clientFactory = new QiHttpClientFactory <IQiServer>();

            clientFactory.ProxyTimeout = new TimeSpan(0, 1, 0);
            clientFactory.OnCreated((p) => p.DefaultHeaders.Add("Authorization", new AuthenticationHeaderValue("Bearer", token).ToString()));

            IQiServer qiclient = clientFactory.CreateChannel(new Uri(server));

            try
            {
                // Create a Qi Type -- the Qi Libraries let you do this via reflection
                // First, create a type builder, then pass it the name of the class you are using for events.
                // This greatly simplifies type creation

                Console.WriteLine("Creating a Qi type for WaveData instances");
                QiTypeBuilder typeBuilder = new QiTypeBuilder();
                evtType    = typeBuilder.Create <WaveData>();
                evtType.Id = "WaveType";
                QiType tp = qiclient.GetOrCreateType(evtType);

                Console.WriteLine("Creating a stream in this tenant for simple event measurements");

                QiStream sampleStream = new QiStream();
                sampleStream.Name = "evtStream";
                sampleStream.Id   = "evtStream";

                // set the TypeId property to the value of the Id property of the type you submitted
                // All events submitted to this stream must be of this type
                // Note there are Async versions of the client methods, too, using .NET TPL
                sampleStream.TypeId      = tp.Id;
                sampleStream.Description = "This is a sample stream for storing WaveData type measurements";
                QiStream strm = qiclient.GetOrCreateStream(sampleStream);

                #region CRUD Operations

                #region Create Events (Insert)

                Console.WriteLine("Artificially generating 100 events and inserting them into the Qi Service");

                // How to insert a single event
                TimeSpan span = new TimeSpan(0, 1, 0);
                WaveData evt  = WaveData.Next(span, 2.0, 0);

                qiclient.InsertValue("evtStream", evt);

                List <WaveData> events = new List <WaveData>();
                // how to insert an a collection of events
                for (int i = 2; i < 200; i += 2)
                {
                    WaveData newEvt = WaveData.Next(span, 2.0, i);
                    events.Add(newEvt);
                    Thread.Sleep(400);
                }

                qiclient.InsertValues <WaveData>("evtStream", events);
                Thread.Sleep(2000);

                #endregion


                #region Retrieve events for a time range

                // use the round trip formatting for time
                Console.WriteLine("Retrieving the inserted events");
                Console.WriteLine("==============================");
                IEnumerable <WaveData> foundEvts = qiclient.GetWindowValues <WaveData>("evtStream", "0", "198");
                DumpEvents(foundEvts);
                #endregion

                #region Update an event

                Console.WriteLine();
                Console.WriteLine("Updating values");

                // take the first value inserted and update the value using a multiplier of 4, while retaining the order
                evt = foundEvts.First <WaveData>();
                evt = WaveData.Next(span, 4.0, evt.Order);

                qiclient.UpdateValue <WaveData>("evtStream", evt);

                // update the collection of events (same span, multiplier of 4, retain order)
                List <WaveData> newEvents = new List <WaveData>();
                foreach (WaveData evnt in events)
                {
                    WaveData newEvt = WaveData.Next(span, 4.0, evnt.Order);
                    newEvents.Add(newEvt);
                    Thread.Sleep(500);
                }

                qiclient.UpdateValues <WaveData>("evtStream", newEvents);
                Thread.Sleep(2000);

                Console.WriteLine("Retrieving the updated values");
                Console.WriteLine("=============================");
                foundEvts = qiclient.GetWindowValues <WaveData>("evtStream", "0", "198");
                DumpEvents(foundEvts);

                // illustrate how stream behaviors modify retrieval
                // First, pull three items back with GetRangeValues for range values between events.
                // The default behavior is continuous, so ExactOrCalculated should bring back interpolated values
                Console.WriteLine();
                Console.WriteLine(@"Retrieving three events without a stream behavior");
                foundEvts = qiclient.GetRangeValues <WaveData>("evtStream", "1", 0, 3, false, QiBoundaryType.ExactOrCalculated);
                DumpEvents(foundEvts);

                // now, create a stream behavior with Discrete and attach it to the existing stream
                QiStreamBehavior behavior = new QiStreamBehavior();
                behavior.Id   = "evtStreamStepLeading";
                behavior.Mode = QiStreamMode.StepwiseContinuousLeading;
                behavior      = qiclient.GetOrCreateBehavior(behavior);

                // update the stream to include this behavior
                sampleStream.BehaviorId = behavior.Id;
                qiclient.UpdateStream("evtStream", sampleStream);

                // repeat the retrieval
                Console.WriteLine();
                Console.WriteLine("Retrieving three events with a stepwise stream behavior in effect -- compare to last retrieval");
                foundEvts = qiclient.GetRangeValues <WaveData>("evtStream", "1", 0, 3, false, QiBoundaryType.ExactOrCalculated);
                DumpEvents(foundEvts);

                #endregion

                #region Delete events

                Console.WriteLine();
                Console.WriteLine("Deleting events");
                qiclient.RemoveValue <int>("evtStream", 0);
                qiclient.RemoveWindowValues <int>("evtStream", 2, 198);
                Thread.Sleep(2000);
                Console.WriteLine("Checking for events");
                Console.WriteLine("===================");
                foundEvts = qiclient.GetWindowValues <WaveData>("evtStream", "0", "198");
                DumpEvents(foundEvts);
                #endregion
                #endregion
            }
            catch (QiHttpClientException qiex)
            {
                Console.WriteLine("Error in Qi Service Client: " + qiex.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Other error: " + ex.Message);
            }
            finally
            {
                // clean up all created entities so you can run this again
                // all entities are reference counted, so you must delete the stream, then the type it uses
                try
                {
                    qiclient.DeleteStream("evtStream");
                    qiclient.DeleteBehavior("evtStreamStepLeading");
                    qiclient.DeleteType(evtType.Id);
                }
                catch (Exception)
                {
                }
            }
        }
Пример #9
0
        private static void Main(string[] args)
        {
            // ==== Create the client ====
            var tenant    = ConfigurationManager.AppSettings["Tenant"];
            var address   = ConfigurationManager.AppSettings["Address"];
            var aadFormat = ConfigurationManager.AppSettings["AADInstanceFormat"];
            var resource  = ConfigurationManager.AppSettings["Resource"];
            var appId     = ConfigurationManager.AppSettings["AppId"];
            var appKey    = ConfigurationManager.AppSettings["AppKey"];

            // A formal client should be wrapped in a retry handler.
            HttpClient client = HttpClientFactory.Create(new WebRequestHandler(),
                                                         new AuthenticationHandler(resource, tenant, aadFormat, appId, appKey));

            client.BaseAddress = new Uri(address);

            // ==== Get or create the namespace, type and stream(s) ====
            var space = new QiNamespace()
            {
                Id = ConfigurationManager.AppSettings["Namespace"]
            };
            HttpResponseMessage response = client.GetAsync($"Qi/{tenant}/Namespaces/{space.Id}").GetAwaiter().GetResult();

            if (response.StatusCode == HttpStatusCode.NotFound)
            {
                response = client.PostAsJsonAsync($"Qi/{tenant}/Namespaces", space).GetAwaiter().GetResult();
            }
            if (!response.IsSuccessStatusCode)
            {
                throw new HttpResponseException(response);
            }

            var type = QiTypeBuilder.CreateQiType <WaveData>();

            response = client.GetAsync($"Qi/{tenant}/{space.Id}/Types/{type.Id}").GetAwaiter().GetResult();
            if (response.StatusCode == HttpStatusCode.NotFound)
            {
                response = client.PostAsJsonAsync($"Qi/{tenant}/{space.Id}/Types", type).GetAwaiter().GetResult();
            }
            if (!response.IsSuccessStatusCode)
            {
                throw new HttpResponseException(response);
            }

            var stream = new QiStream()
            {
                Id          = Guid.NewGuid().ToString(),
                Name        = typeof(WaveData).Name,
                Description = "Sample",
                TypeId      = type.Id
            };

            response = client.GetAsync($"Qi/{tenant}/{space.Id}/Streams/{stream.Id}").GetAwaiter().GetResult();
            if (response.StatusCode == HttpStatusCode.NotFound)
            {
                response = client.PostAsJsonAsync($"Qi/{tenant}/{space.Id}/Streams", stream).GetAwaiter().GetResult();
            }
            if (!response.IsSuccessStatusCode)
            {
                throw new HttpResponseException(response);
            }

            // ==== Perform basic CRUD optations ====

            // insert a single event
            var wave = GetWave(0, 200, 2);

            response =
                client.PutAsJsonAsync($"Qi/{tenant}/{space.Id}/Streams/{stream.Id}/Data/UpdateValue", wave)
                .GetAwaiter()
                .GetResult();
            if (!response.IsSuccessStatusCode)
            {
                throw new HttpResponseException(response);
            }

            // Insert another single event using a Post instead of a Put
            wave.Order += 1;
            response    =
                client.PostAsJsonAsync($"Qi/{tenant}/{space.Id}/Streams/{stream.Id}/Data/InsertValue", wave)
                .GetAwaiter()
                .GetResult();
            if (!response.IsSuccessStatusCode)
            {
                throw new HttpResponseException(response);
            }

            // Insert a collection of events
            var events = new List <WaveData>();

            for (var i = 2; i <= 200; i += 2)
            {
                events.Add(GetWave(i, 200, 2));
            }

            response =
                client.PostAsJsonAsync($"Qi/{tenant}/{space.Id}/Streams/{stream.Id}/Data/InsertValues", events)
                .GetAwaiter()
                .GetResult();
            if (!response.IsSuccessStatusCode)
            {
                throw new HttpResponseException(response);
            }

            // retrieve the newly inserted events
            response =
                client.GetAsync(
                    $"Qi/{tenant}/{space.Id}/Streams/{stream.Id}/Data/GetValues?startIndex={0}&endIndex={200}&count={100}")
                .GetAwaiter()
                .GetResult();
            if (!response.IsSuccessStatusCode)
            {
                throw new HttpResponseException(response);
            }
            var retrievedEvents = response.Content.ReadAsAsync <WaveData[]>().GetAwaiter().GetResult();

            // Update the events
            Array.ForEach(retrievedEvents, w => GetWave(w.Order, 200, 3));
            response =
                client.PutAsJsonAsync($"Qi/{tenant}/{space.Id}/Streams/{stream.Id}/Data/UpdateValues", events)
                .GetAwaiter()
                .GetResult();
            if (!response.IsSuccessStatusCode)
            {
                throw new HttpResponseException(response);
            }

            // ==== Clean up ====

            // It's not necessary to delete the values if you're deleting the stream
            response =
                client.DeleteAsync(
                    $"Qi/{tenant}/{space.Id}/Streams/{stream.Id}/Data/RemoveWindowValues?startIndex={0}&endIndex={200}")
                .GetAwaiter()
                .GetResult();
            if (!response.IsSuccessStatusCode)
            {
                throw new HttpResponseException(response);
            }

            response = client.DeleteAsync($"Qi/{tenant}/{space.Id}/Streams/{stream.Id}").GetAwaiter().GetResult();
            if (!response.IsSuccessStatusCode)
            {
                throw new HttpResponseException(response);
            }
            response = client.DeleteAsync($"Qi/{tenant}/{space.Id}/Types/{type.Id}").GetAwaiter().GetResult();
            if (!response.IsSuccessStatusCode)
            {
                throw new HttpResponseException(response);
            }
        }