public void Run()
        {
            // 95% chance that ticket validation is successful is approved
            Random gen = new Random();
            bool   purchaseApproved = gen.Next(100) <= 95;

            // process each message
            ValidateTicketRequest ticketRequestMessage = JsonConvert.DeserializeObject <ValidateTicketRequest>(payloadMessage);

            try
            {
                string methodName    = ticketRequestMessage.MethodName;
                string deviceId      = ticketRequestMessage.DeviceId;
                string transactionId = ticketRequestMessage.TransactionId;

                var payload = new PurchaseTicketPayload()
                {
                    TransactionId = transactionId,
                    IsApproved    = purchaseApproved,
                    DeviceId      = ticketRequestMessage.DeviceId,
                    DeviceType    = ticketRequestMessage.DeviceType,
                    MessageType   = ticketRequestMessage.MessageType,
                };

                log.LogInformation($"Response Method: {methodName}");

                InvokeMethod(methodName, payload).GetAwaiter().GetResult();
            }
            catch (Exception ex)
            {
                log.LogError(ex.Message);
            }
        }
Esempio n. 2
0
        // Invoke the direct method on the device, passing the payload
        private static async Task InvokeMethod(string methodName, PurchaseTicketPayload purchaseTicketPayload)
        {
            TimeSpan responseTimeoutInSeconds = TimeSpan.FromSeconds(30);
            var      methodInvocation         = new CloudToDeviceMethod
                                                    (methodName)
            {
                ResponseTimeout = responseTimeoutInSeconds
            };
            var payload = JsonConvert.SerializeObject(purchaseTicketPayload);

            methodInvocation.SetPayloadJson(payload);

            try
            {
                // Invoke the direct method asynchronously and get the response from the simulated device.
                var response = await serviceClient.InvokeDeviceMethodAsync(purchaseTicketPayload.DeviceId, methodInvocation);

                Console.WriteLine("Response status: {0}, payload:", response.Status);
                Console.WriteLine(response.GetPayloadAsJson());
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw;
            }
        }
        public void TestKioskPurchaseTicket()
        {
            FakeDeviceClient   fakeDeviceClient = new FakeDeviceClient();
            FakeEventScheduler fakeScheduler    = new FakeEventScheduler();

            TestContext.WriteLine(string.Empty);
            TestContext.WriteLine(">> Testing the purchase ticket simulated event..");

            KioskDevice device = new KioskDevice(deviceconfig, fakeDeviceClient, fakeScheduler);

            // execute a purchase ticket event and check the result, it should always be false
            Assert.IsFalse(fakeScheduler.EventList[0].EventDelegate());
            // that delegate should have sent one message to the cloud
            Assert.AreEqual(fakeDeviceClient.sendMessageLog.Count, 1);

            // check the message sent to make sure its correct
            // create a sample request for comparison
            PurchaseTicketRequest expectedRequest = new PurchaseTicketRequest()
            {
                DeviceId      = deviceconfig.DeviceId,
                DeviceType    = deviceconfig.DeviceType,
                TransactionId = "fakeId",
                CreateTime    = System.DateTime.UtcNow,
                Price         = 1,
                MethodName    = "ReceivePurchaseTicketResponse"
            };
            // get request message into an object so we can compare it
            PurchaseTicketRequest actualRequest = JsonConvert.DeserializeObject <PurchaseTicketRequest>(fakeDeviceClient.sendMessageLog[0]);

            // compare properties to make sure they're valid.
            Assert.AreEqual(actualRequest.DeviceId, expectedRequest.DeviceId);
            Assert.AreEqual(actualRequest.DeviceType, expectedRequest.DeviceType);
            Assert.AreEqual(actualRequest.MessageType, expectedRequest.MessageType);
            // skipping the TransactionID and CreationTime
            Assert.IsTrue(actualRequest.Price > 2);
            Assert.IsTrue(actualRequest.Price < 100);
            Assert.AreEqual(actualRequest.MethodName, expectedRequest.MethodName);

            //
            /// test the CloudToEvent PurchaseResponse call we expect back
            //
            TestContext.WriteLine(string.Empty);
            TestContext.WriteLine(">> Testing the ticket approval direct method..");

            // test the direct method itself
            PurchaseTicketPayload approvePurchaseMethodkRequest = new PurchaseTicketPayload()
            {
                IsApproved  = true,
                DeviceId    = expectedRequest.DeviceId,
                DeviceType  = expectedRequest.DeviceType,
                MessageType = expectedRequest.MessageType,
            };
            string requestString = JsonConvert.SerializeObject(approvePurchaseMethodkRequest);
            // execute the method
            MethodRequest  methodRequest = new MethodRequest(expectedRequest.MethodName, Encoding.UTF8.GetBytes(requestString));
            MethodResponse methodresult  = fakeDeviceClient.directMethods[0](methodRequest, null).Result;

            // check results
            Assert.AreEqual(methodresult.Status, 200); // got back an ok
        }
Esempio n. 4
0
        public void Run()
        {
            // 95% chance that ticket purchase is approved
            Random gen = new Random();
            bool   purchaseApproved = gen.Next(100) <= (100 - failRate);

            // process each message
            PurchaseTicketRequest ticketRequestMessage = JsonConvert.DeserializeObject <PurchaseTicketRequest>(payloadMessage);

            try
            {
                string methodName = ticketRequestMessage.MethodName;
                //string iotHubName = Environment.GetEnvironmentVariable("IotHubName");
                string deviceId = ticketRequestMessage.DeviceId;
                //string responseUrl = $"https://{iotHubName}.azure-devices.net/twins/{deviceId}/methods?api-version=2018-06-30";
                string transactionId = ticketRequestMessage.TransactionId;
                var    payload       = new PurchaseTicketPayload()
                {
                    TransactionId = transactionId,
                    IsApproved    = purchaseApproved,
                    DeviceId      = ticketRequestMessage.DeviceId,
                    DeviceType    = ticketRequestMessage.DeviceType,
                    MessageType   = ticketRequestMessage.MessageType,
                };

                log.LogInformation($"Response Method: {methodName}");

                InvokeMethod(methodName, payload).GetAwaiter().GetResult();
            }
            catch (Exception ex)
            {
                log.LogError(ex.Message);
            }
        }
        public void TestPurchaseDenied()
        {
            FakeDeviceClient   fakeDeviceClient = new FakeDeviceClient();
            FakeEventScheduler fakeScheduler    = new FakeEventScheduler();

            TestContext.WriteLine(">> Testing the Kiosk Device's Low Stock notification..");

            PurchaseTicketPayload approvePurchaseMethodkRequest = new PurchaseTicketPayload()
            {
                DeviceId    = deviceconfig.DeviceId,
                DeviceType  = deviceconfig.DeviceType,
                MessageType = "Purchase",
                IsApproved  = false
            };

            // create our test device
            KioskDevice device = new KioskDevice(deviceconfig, fakeDeviceClient, fakeScheduler);

            TestContext.WriteLine(string.Empty);
            TestContext.WriteLine(">> Purchasing tickets, shouldn't throw event");
            string        requestString = JsonConvert.SerializeObject(approvePurchaseMethodkRequest);
            MethodRequest methodRequest = new MethodRequest("ReceivePurchaseTicketResponse", Encoding.UTF8.GetBytes(requestString));


            MethodResponse myresult = fakeDeviceClient.directMethods[0](methodRequest, null).Result;

            // no ticket was issued, count remained the same and no message sent to cloud
            Assert.AreEqual(device.CurrentStockLevel, deviceconfig.InitialStockCount);
            Assert.AreEqual(fakeDeviceClient.sendMessageLog.Count, 0);
        }
Esempio n. 6
0
        // Handle the direct method call back from Azure
        private Task <MethodResponse> ReceivePurchaseTicketResponse(MethodRequest methodRequest, object userContext)
        {
            var data = Encoding.UTF8.GetString(methodRequest.Data);
            PurchaseTicketPayload purchaseResponse = JsonConvert.DeserializeObject <PurchaseTicketPayload>(data);

            var json = JObject.Parse(data); //methodRequest.DataAsJson;

            Console.WriteLine("Executed direct method: " + methodRequest.Name);
            Console.WriteLine($"Transaction Id: {purchaseResponse.TransactionId}");
            Console.WriteLine($"IsApproved: {purchaseResponse.IsApproved}");
            Console.WriteLine();

            if (purchaseResponse.IsApproved)
            {
                SendTicketIssuedMessageToCloud(purchaseResponse);
            }

            // Acknowlege the direct method call with a 200 success message
            string result = "{\"result\":\"Executed direct method: " + methodRequest.Name + "\"}";

            // restart the purchase ticket event
            if (GetDeviceStatus() == DeviceStatus.enabled)
            {
                this._EventScheduler.Start(0);
            }

            return(Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(result), 200)));
        }
Esempio n. 7
0
        private bool SendTicketIssuedMessageToCloud(PurchaseTicketPayload requestpayload)
        {
            this.TicketStockCount--;

            IssueTicketRequest issueTicketRequest = new IssueTicketRequest()
            {
                DeviceId      = this.deviceId,
                DeviceType    = this.deviceType,
                TransactionId = requestpayload.TransactionId,
                CreateTime    = System.DateTime.UtcNow
            };

            var messageString = JsonConvert.SerializeObject(issueTicketRequest);

            SendMessageToCloud(messageString);

            Console.WriteLine("{0} > Sending message: {1}", DateTime.Now, messageString);
            Console.WriteLine();

            // if we've fallen below the threshold, send notification
            if (this.TicketStockCount < (int)this.deviceConfig.LowStockThreshold && !this.LowStockNotificationSent)
            {
                SendTLowStockMessageToCloud();
            }

            return(false); // don't restart timer
        }
Esempio n. 8
0
        public void PurchaseTicketTest()
        {
            // sample payload to test
            PurchaseTicketRequest sampleRequest = new PurchaseTicketRequest()
            {
                DeviceId      = "rjTest",
                DeviceType    = DeviceType.TicketKiosk,
                TransactionId = "c3d8b13c - 3e8f - 4e57 - a7d5 - ae8adaa8c2b2",
                CreateTime    = System.DateTime.UtcNow,
                Price         = 54,
                MethodName    = "ReceivePurchaseTicketResponse"
            };
            string sampleRequestString = JsonConvert.SerializeObject(sampleRequest);

            // expected response
            PurchaseTicketPayload expectedResponse = new PurchaseTicketPayload()
            {
                DeviceId      = sampleRequest.DeviceId,
                TransactionId = sampleRequest.TransactionId,
                DeviceType    = sampleRequest.DeviceType,
                MessageType   = MessageType.cmdPurchaseTicket,
                IsApproved    = true
            };
            string expectedResponseString = JsonConvert.SerializeObject(expectedResponse);


            FakeInvokeDeviceMethod serviceClient = new FakeInvokeDeviceMethod();
            PurchaseTicketAction   action        = new PurchaseTicketAction(serviceClient, 0, sampleRequestString, logger);

            action.Run();
            // Assert that serviceClient.invocations count is 1
            Assert.That(Equals(serviceClient.invocations.Count, 1));
            // Assert that the device id from the invocation is as expected
            Assert.That(string.Equals(serviceClient.invocations[0].device, "rjTest"));
            // Assert that the method name details from the invocation is as expected
            StringAssert.AreEqualIgnoringCase(sampleRequest.MethodName, serviceClient.invocations[0].method.MethodName);

            // get response to object
            PurchaseTicketPayload actualResponse = JsonConvert.DeserializeObject <PurchaseTicketPayload>(serviceClient.invocations[0].method.GetPayloadAsJson());

            // check the expected against the actuals
            Assert.AreEqual(expectedResponse.DeviceId, actualResponse.DeviceId, "Device IDs do not match");
            Assert.AreEqual(expectedResponse.DeviceType, actualResponse.DeviceType, "Device Types do not match");
            Assert.AreEqual(expectedResponse.TransactionId, actualResponse.TransactionId, "Transaction IDs do not match");
            Assert.AreEqual(expectedResponse.MessageType, actualResponse.MessageType, "Message Types do not match");
            Assert.IsTrue(actualResponse.IsApproved, "Expected Ticket to be approved, but it was rejected");
        }
Esempio n. 9
0
        public static void Run(
            [
                EventHubTrigger("purchaseticketeventhub",
                                Connection = "receiverConnectionString")
            ]
            EventData[] eventHubMessages, ILogger log)
        {
            // process messages
            foreach (EventData message in eventHubMessages)
            {
                string messagePayload = Encoding.UTF8.GetString(message.Body.Array);

                // process each message
                PurchaseTicketRequest ticketRequestMessage = JsonConvert.DeserializeObject <PurchaseTicketRequest>(messagePayload);

                try
                {
                    string methodName    = ticketRequestMessage.MethodName;
                    string deviceId      = ticketRequestMessage.DeviceId;
                    string transactionId = ticketRequestMessage.TransactionId;
                    var    payload       = new PurchaseTicketPayload()
                    {
                        TransactionId = transactionId,
                        IsApproved    = true,
                        DeviceId      = ticketRequestMessage.DeviceId,
                        DeviceType    = ticketRequestMessage.DeviceType,
                        MessageType   = ticketRequestMessage.MessageType,
                    };

                    log.LogInformation($"Response Method: {methodName}");

                    var connectionString = Environment.GetEnvironmentVariable("IotHubConnectionString");

                    serviceClient = ServiceClient.CreateFromConnectionString(connectionString);
                    InvokeMethod(methodName, payload).GetAwaiter().GetResult();
                }
                catch (Exception ex)
                {
                    log.LogError(ex.Message);
                }
            }
        }
        public void TestLowStock()
        {
            FakeDeviceClient   fakeDeviceClient = new FakeDeviceClient();
            FakeEventScheduler fakeScheduler    = new FakeEventScheduler();

            TestContext.WriteLine(">> Testing the Kiosk Device's Low Stock notification..");

            PurchaseTicketPayload approvePurchaseMethodkRequest = new PurchaseTicketPayload()
            {
                DeviceId    = deviceconfig.DeviceId,
                DeviceType  = deviceconfig.DeviceType,
                MessageType = MessageType.cmdPurchaseTicket,
                IsApproved  = true
            };

            // create our test device
            KioskDevice device = new KioskDevice(deviceconfig, fakeDeviceClient, fakeScheduler);

            device.InitializeAsync().Wait();

            TestContext.WriteLine(string.Empty);
            TestContext.WriteLine(">> Purchasing tickets, shouldn't throw event");
            string        requestString = JsonConvert.SerializeObject(approvePurchaseMethodkRequest);
            MethodRequest methodRequest = new MethodRequest("ReceivePurchaseTicketResponse", Encoding.UTF8.GetBytes(requestString));

            // fire events to bring the count down to right at threshold
            for (long count = this.deviceconfig.InitialStockCount; count > this.deviceconfig.LowStockThreshold; count--)
            {
                MethodResponse myresult = fakeDeviceClient.directMethods[0](methodRequest, null).Result;
                TestContext.WriteLine(">> Current stock level: " + device.CurrentStockLevel);
            }

            // now that we're at the threshold, lets clear all previous events
            fakeDeviceClient.sendMessageLog.Clear(); // clear out all messages to this point

            TestContext.WriteLine(string.Empty);
            TestContext.WriteLine(">> Purchasing 1 more ticket. Should send low stock notification");
            // purchase one more ticket.
            MethodResponse methodresult = fakeDeviceClient.directMethods[0](methodRequest, null).Result;

            // we expect 2 messages to have been sent
            Assert.AreEqual(fakeDeviceClient.sendMessageLog.Count, 2);
            // second message should make expected result
            LowStockRequest expectedRequest = new LowStockRequest()
            {
                DeviceId   = deviceconfig.DeviceId,
                DeviceType = deviceconfig.DeviceType,
                StockLevel = (deviceconfig.LowStockThreshold - 1),
            };
            // get actual message into an object so we can compare it
            LowStockRequest actualRequest = JsonConvert.DeserializeObject <LowStockRequest>(fakeDeviceClient.sendMessageLog[1]);

            TestContext.WriteLine(fakeDeviceClient.sendMessageLog[1]);
            // compare properties to make sure they're valid.
            Assert.AreEqual(actualRequest.DeviceId, expectedRequest.DeviceId);
            Assert.AreEqual(actualRequest.DeviceType, expectedRequest.DeviceType);
            Assert.AreEqual(actualRequest.MessageType, expectedRequest.MessageType);
            Assert.AreEqual(actualRequest.StockLevel, expectedRequest.StockLevel);

            TestContext.WriteLine(string.Empty);
            TestContext.WriteLine(">> Testing to make sure we don't have a second low stock warning ..");
            // make sure we don't throw the low stock warning again
            fakeDeviceClient.sendMessageLog.Clear(); // clear out all messages to this point
            // purchase one more ticket.
            methodresult = fakeDeviceClient.directMethods[0](methodRequest, null).Result;
            // we expect 2 messages to have been sent
            Assert.AreEqual(fakeDeviceClient.sendMessageLog.Count, 1);

            // reset the device to make sure ticket stock is reset using the desired property callback option
            device.SetDeviceStatusAsync(DeviceStatus.disabled).Wait(); // disable the device
            device.SetDeviceStatusAsync(DeviceStatus.enabled).Wait();  // enable the device
            // check the stock level
            Assert.AreEqual(deviceconfig.InitialStockCount, device.CurrentStockLevel, "Device stock levels were not reset back to initial after device rest");
        }