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); } }
// 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 }
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); }
// 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))); }
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 }
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"); }
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"); }