コード例 #1
0
        static void Main(string[] args)
        {
            PublicationConfig    publicationConfig    = new PublicationConfig();
            PublicationGenerator publicationGenerator = new PublicationGenerator();

            publicationGenerator.GeneratePublications();
            SubscriptionGenerator subscriptionGenerator = new SubscriptionGenerator();

            subscriptionGenerator.GenerateSubscriptions();
        }
コード例 #2
0
        public async Task ConnectionsAndSubscriptionsAreBeingTracked()
        {
            // Generating the necessary edgeHub components and the test clients
            var(connectionManager, connectionHandler, subscriptionChangeHandler, telemetryHandler) = await SetupEdgeHub("something");

            var clients = GenerateClients(100, 0.5, 0.5);

            var rnd = new Random(548196703);
            var subscriptionTypes = new[] { SubscriptionOrMessage.C2D, SubscriptionOrMessage.DesiredPropertyUpdates, SubscriptionOrMessage.DirectMethod, SubscriptionOrMessage.TwinResponse };

            // Start playing the playbook. At every iteration it executes the operations (e.g. subscribe to twin results) that the playbook of a
            // given client dictates.
            for (var phase = 0; phase < PlaybookLength; phase++)
            {
                // get a randomized order of clients so the messages are more stochastic
                clients.Shuffle(rnd);

                // Direct clients can send their subscriptions immediately, however for nested clients we collect them and send a single
                // update, as in this case edgeHub sends a single event describing all the nested clients.
                var edgeHubSubscriptions = new List <string>();

                foreach (var client in clients)
                {
                    // This is just to avoid sending the subscriptions always the same order, e.g. always twin first, then c2d
                    subscriptionTypes.Shuffle(rnd);

                    if (client.IsDirect)
                    {
                        var hasChanged           = false;
                        var currentSubscriptions = new List <string>();
                        foreach (var sub in subscriptionTypes)
                        {
                            // we are interested only in changes. Note, that the playbook handles the call with -1 (phase=0), so no error at the next line
                            if (client.Playbook.IsActive(sub, phase) ^ client.Playbook.IsActive(sub, phase - 1))
                            {
                                hasChanged = true;
                            }

                            if (client.Playbook.IsActive(sub, phase))
                            {
                                currentSubscriptions.Add(SubscriptionGenerator[sub](true, client.Identity));
                            }
                        }

                        if (hasChanged)
                        {
                            client.SetNoticed();
                            var subscriptionEvent = $"[{currentSubscriptions.Select(s => $"\"{s}\"").Join(", ")}]";
                            await subscriptionChangeHandler.HandleAsync(new MqttPublishInfo($"$edgehub/{client.Identity.Id}/subscriptions", Encoding.UTF8.GetBytes(subscriptionEvent)));
                        }

                        if (client.Playbook.IsActive(SubscriptionOrMessage.Message, phase))
                        {
                            client.SetNoticed();
                            await telemetryHandler.HandleAsync(new MqttPublishInfo($"$edgehub/{client.Identity.Id}/messages/events", Encoding.UTF8.GetBytes("hello")));
                        }
                    }
                    else
                    {
                        foreach (var sub in subscriptionTypes)
                        {
                            // just store all the subscribed topics. Note, that this code does not care if the result is the same as previously,
                            // however resending an event twice should not cause problems for edgeHub
                            if (client.Playbook.IsActive(sub, phase))
                            {
                                client.SetNoticed();
                                edgeHubSubscriptions.Add(SubscriptionGenerator[sub](false, client.Identity));
                            }
                        }

                        if (client.Playbook.IsActive(SubscriptionOrMessage.Message, phase))
                        {
                            client.SetNoticed();
                            await telemetryHandler.HandleAsync(new MqttPublishInfo($"$iothub/{client.Identity.Id}/messages/events", Encoding.UTF8.GetBytes("hello")));
                        }
                    }
                }

                var edgeHubsubscriptionEvent = $"[{edgeHubSubscriptions.Select(s => $"\"{s}\"").Join(", ")}]";
                await subscriptionChangeHandler.HandleAsync(new MqttPublishInfo("$edgehub/nested_dev/$edgeHub/subscriptions", Encoding.UTF8.GetBytes(edgeHubsubscriptionEvent)));

                // we do a phase check at around %20 of the steps
                if (rnd.NextDouble() < 0.2 || phase + 1 == PlaybookLength)
                {
                    var clientsShouldBeKnown = new HashSet <IIdentity>(clients.Where(c => c.IsNoticed).Select(c => c.Identity));

                    var started           = DateTime.Now;
                    var knownClientsAreOk = false;

                    // Calculating the actual state in a loop, that is because it may take time till the subscription events are get processed
                    do
                    {
                        var clientsKnown = new HashSet <IIdentity>((connectionHandler.AsPrivateAccessible().knownConnections as ConcurrentDictionary <IIdentity, IDeviceListener>).Keys);
                        knownClientsAreOk = clientsKnown.SetEquals(clientsShouldBeKnown);

                        if (!knownClientsAreOk)
                        {
                            await Task.Delay(500);
                        }
                    }while (!knownClientsAreOk && DateTime.Now - started < TimeSpan.FromSeconds(5));

                    Assert.True(knownClientsAreOk);

                    started = DateTime.Now;
                    var subscriptionsAreOk = false;
                    foreach (var client in clients.Where(c => c.IsNoticed))
                    {
                        var expectedSubscriptions = default(HashSet <DeviceSubscription>);
                        var actualSubscriptions   = default(HashSet <DeviceSubscription>);
                        do
                        {
                            expectedSubscriptions = new HashSet <DeviceSubscription>();
                            foreach (var sub in subscriptionTypes)
                            {
                                if (client.Playbook.IsActive(sub, phase))
                                {
                                    expectedSubscriptions.Add(
                                        sub switch
                                    {
                                        SubscriptionOrMessage.C2D => DeviceSubscription.C2D,
                                        SubscriptionOrMessage.DesiredPropertyUpdates => DeviceSubscription.DesiredPropertyUpdates,
                                        SubscriptionOrMessage.DirectMethod => DeviceSubscription.Methods,
                                        SubscriptionOrMessage.TwinResponse => DeviceSubscription.TwinResponse,
                                        _ => DeviceSubscription.Unknown,
                                    });
                                }
                            }

                            actualSubscriptions = new HashSet <DeviceSubscription>(
                                connectionManager.GetSubscriptions(client.Identity.Id).Expect(() => new Exception("client should be known"))
                                .Where(s => s.Value == true)
                                .Select(s => s.Key));

                            subscriptionsAreOk = expectedSubscriptions.SetEquals(actualSubscriptions);

                            if (!subscriptionsAreOk)
                            {
                                await Task.Delay(500);
                            }
                        }while (!subscriptionsAreOk && DateTime.Now - started < TimeSpan.FromSeconds(5));

                        Assert.True(subscriptionsAreOk);
                    }