{"action":"created","comment":{"url":"https://api.github.com/repos/mspnp/iot-journey/pulls/comments/35144413","id":35144413,"diff_hunk":"@@ -1,74 +1,90 @@\n-# Journal Entry #1\n-_Capturing event data and saving it in its raw format to cold storage_\n+# Journal 1: Event Ingestion and Cold Storage\n \n-:pencil2: working draft\n+This journal entry covers the most basic end-to-end scenario in IoT: Getting events into the system and putting them into long-term storage. In terms of the logical architecture, it maps to the highlighted components shown here:\n \n-> The purpose of this phase is to determine an approach to ingesting data, performing the simplest of processing, and saving it for subsequent analysis. Because the customer requires all event data to be stored indefinitely, the volume of data held in cold storage could become very large. Cold storage must therefore be inexpensive.\n+![plan for this first milestone](media/01-cold-storage/logical-architecture-for-milestone01.png)\n \n-# Fabrikam's Perspective\n-Fabrikam's engineering team has very little experience with high-scale event-oriented systems. They want to make sure that they are [asking the right questions][orientation]. They also need to get a minimum viable product deployed.\n \n-For their [first milestone][milestone] they want to:\n-- Ingest a representative set of simulated events.\n-- Store the raw data for all events for later analysis. [:arrow_right:][cold-storage]\n-- Increase the scale until they match the targets for their customer [:arrow_right:][increase-scale]\n+- [Common requirements](#common-requirements)\n+- [Fabrikam requirements](#fabrikam-requirements)\n+- [Exploring solutions for ingestion and processing](#exploring-solutions-for-ingestion-and processing)\n+- [Exploring solutions for cold storage](#exploring-solutions-for-cold-storage)\n+- [Reference implementation](#reference-implementation)\n+- [Lessons learned](#lessons-learned)\n \n-They need a basic implementation that maps to the highlighted components of the logical architecture:\n+## Common requirements\n \n-![plan for this first milestone](media/01-cold-storage/logical-architecture-for-milestone01.png)\n+Here are some common requirements for ingestion and cold storage that any IoT solution will at least need to consider:\n+\n+- Achieving scale. That means both hitting the expected target data rate, but also designing the system to be scalable in the future.\n+- Authentication. Only authenticated devices can send data. (Provisioning devices is a separate scenario, although closely related.)\n+- Protecting the data stream.\n+- Storing the raw event data in long-term storage. Cold storage must hold a large volume of historical data indefinitely, at a reasonable cost. \n+\n+  \n+## Fabrikam requirements\n+\n+:memo: For more about our Fabrikam scenario, see [Introducing the Journey][00-intro]. \n \n+Here are some specific requirements for our scenario:\n \n-## Devices\n+- As an initial target, the system must handle up to 100,000 devices, each device sending 1 reading every minute. That's approximately 1,667 events per second. This is a minimum load &mdash; the system should be scalable beyond this target. \n+- Events might be time critical, so the Event Processing component must handle this volume of data without introducing any backlog into the system.\n+- The event data stream must be protected. This means not only securing the content of the events, but also masking the *absence* of events. For example, if the motion detectors in a house are not streaming any events, an attacker can conclude that nobody is home.\n \n-Initially, Fabrikam don't have access to the buildings, so they have elected to build a simple simulator that emits temperature events representing the readings for each device. These events are generated at a realistic rate, and the simulator can be configured to imitate a variable number of devices. The simulator has already been developed using the .NET Framework. A console application provides a simple user interface, but it is also possible to host the simulator as a web job to provide an environment for long-lived, unattended running.\n \n-> ![Markus](media/PersonaMarkus.png) \n-\"We invested a significant amount of time and effort in creating the simulator. It is important that we are able to simulate a realistic number of devices sending events at the expected rate.\"\n+## Exploring solutions for ingestion and processing\n \n-## Event Processing\n+**Ingestion** and **event processing** are somewhat related. How the system ingests the events may limit the options for processing. We investigated the following options.   \n \n-Per the customer requirements, the system needs to capture event information emanating from 100,000 devices, each device sending 1 reading every minute. This equates to approximately 1,667 events per second. The Event Processing component must be capable of capturing this volume of information without introducing any backlog into the system; events raised by devices could be time critical.\n+- HTTP service\n+- Service bus topics + message subscriber\n+- Event hub + custom event processor \n+- Event hub + Azure Stream Analytics\n+- Event hub + Apache Storm \n \n-The system must also be capable of provisioning and deprovisioning devices. This process is two-stage; the physical device must be installed, and then it must be registered with the Event Processing component. Events from unregistered devices should be ignored.\n \n-The event data stream must also be protected. This means not only securing the content of the events, but actually hiding or camouflaging the event stream itself. For example, if an observer can see that motion detectors in a house are not registering any events then there is probably nobody home.\n+### HTTP service\n \n-There are several ways you can implement the Event Processing component. The developers at Fabrikam considered the options described in the following sections:\n+In this approach, devices (or the field gateway) send HTTP requests. The cloud service runs a simple HTTP service that receives the requests and writes them to storage. The HTTP service could be implemented as a web role in an Azure cloud service.\n \n-### Build a cloud service that receives events posted as HTTP requests\n+Notice that in this design, the HTTP service handles both ingestion and processing.\n \n-The cloud service could be implemented as a web role that parses and saves the event information to cold storage. The cloud service effectively performs the ingestion and processing steps described in [Introducing the Journey][00-intro]\n+![cloud service solution based on web roles](media/01-cold-storage/physical-architecture-cloud-service.png)\n \n **Pros:**\n-- This approach is technically straightforward and quick to prototype\n+\n+- Technically straightforward and quick to prototype.\n \n **Concerns:**\n-- **Throughput.** All incoming requests are handled by the HTTP.sys driver (the entry point into the IIS services stack), and are queued for processing by the IIS service. Worker threads running application code pick up these requests and handle them. The thread pool must be of sufficient size to prevent requests from backing up in the IIS queue (and possibly timing out, causing the request to be rejected), and the processing performed must run quickly enough to satisfy the time requirements for recording event information. To reduce these concerns, it is possible to scale the system by adding more instances. The Azure load-balancer can transparently direct requests to ensure an even distribution. However, there is a limit of 25 role instances per deployment. For a system of the size anticipated by the customer this should be fine, but other customers may have requirements that require many more instances; Fabrikam don't want to have to radically redesign the system in the future.\n \n-> ![Poe](media/PersonaPoe.png) \n-\"We briefly considered building a set of custom virtual machines running an open source web server in the cloud to see whether we could optimize it specifically for this task. We know that you can distribute the load across VMs by configuring load balancing with Azure. However, I asked the developers whether they really wanted Fabrikam to have to take responsibility for maintaining and patching these VMs and the web server software. Additionally, Gary was concerned about the security aspects of this approach - hardening a custom web server is a complex task. We decided against this approach pretty quickly.\"\n+- **Throughput.** The system must avoid request timeouts. IIS puts requests in a queue until a worker thread running application code picks them up. The thread pool must be large enough so that requests don't back up in the queue, possibly timing out. You can scale by adding more instances, and the Azure load-balancer will transparently direct requests to ensure an even distribution. However, there is a limit of 25 role instances per deployment. That should be enough for the Fabrikam scenario, but may not be enough for other scenarios.\n \n-- **Connectivity**. Many simple devices just emit signals that indicate status and don't necessarily send out HTTP packets. Additionally, those devices that can create HTTP messages are unlikely to all use the same schema. It may be necessary to incorporate local field gateways to perform message translation and formatting.\n+> We briefly considered whether we could use virtual machines running an open source web server, optimized specifically for this task. However, that means taking responsibility for maintaining and patching the VMs and the web server software. There are also security concerns with this approach &mdash; it's not easy to harden a custom web server.\n \n-> ![Markus](media/PersonaMarkus.png) \n-\"Many devices are designed to be simple; they output signals indicating events that have occurred, and they can receive signals that indicate commands to be performed. They might not be capable of translating this data into different formats for integration into an IoT solution; this process typically requires some auxiliary hardware and/or software.\"\n+- **Connectivity**. Many simple devices can't send HTTP messages, and devices that *can* send HTTP messages are unlikely to use the same schema. Therefore, a field gateway may be needed to translate device messages.\n \n-![cloud service solution based on web roles](media/01-cold-storage/physical-architecture-cloud-service.png)\n+> Many devices are designed to be simple; they output signals indicating events, and can receive signals for commands to be performed. They might not be capable of translating this data into different formats for integration into an IoT solution; this process typically requires some auxiliary hardware and/or software.\n \n-- **Resilience and reliability.** If an instance of the service fails, then any messages that it is processing might be lost.\n+- **Resilience and reliability.** If an instance of the service fails, then any messages it is processing might be lost.\n \n-- **Scalability.** Event data might need to be handled in multiple ways, such as copying to cold storage, performing warm analysis and aggregation, or for raising alerts. If all of these tasks become the responsibility of the cloud service it might not be capable of handling this work together with the large ingress of event information.\n+- **Scalability.** The HTTP service handles both ingestion and processing. That's feasible for the cold-storage scenario, but what happens when we add more processing tasks, such as warm storage, event aggregation, or critical alerts? Can the service still handle the load *and* process events quickly enough? A big advantage of the other solutions we explored is the use of a publisher/consumer model, separating ingestion from processing.      ","path":"docs/journal/01-cold-storage.md","position":104,"original_position":104,"commit_id":"1c1ae768402ae3899b1b97d0506cc53ecf74eaf0","original_commit_id":"1c1ae768402ae3899b1b97d0506cc53ecf74eaf0","user":{"login":"MikeWasson","id":3992422,"avatar_url":"https://avatars.githubusercontent.com/u/3992422?v=3","gravatar_id":"","url":"https://api.github.com/users/MikeWasson","html_url":"https://github.com/MikeWasson","followers_url":"https://api.github.com/users/MikeWasson/followers","following_url":"https://api.github.com/users/MikeWasson/following{/other_user}","gists_url":"https://api.github.com/users/MikeWasson/gists{/gist_id}","starred_url":"https://api.github.com/users/MikeWasson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MikeWasson/subscriptions","organizations_url":"https://api.github.com/users/MikeWasson/orgs","repos_url":"https://api.github.com/users/MikeWasson/repos","events_url":"https://api.github.com/users/MikeWasson/events{/privacy}","received_events_url":"https://api.github.com/users/MikeWasson/received_events","type":"User","site_admin":false},"body":"re publisher/consumer, possible link: https://msdn.microsoft.com/en-us/library/Dn568101.aspx\r\n","created_at":"2015-07-21T19:35:42Z","updated_at":"2015-07-21T19:35:42Z","html_url":"https://github.com/mspnp/iot-journey/pull/236#discussion_r35144413","pull_request_url":"https://api.github.com/repos/mspnp/iot-journey/pulls/236","_links":{"self":{"href":"https://api.github.com/repos/mspnp/iot-journey/pulls/comments/35144413"},"html":{"href":"https://github.com/mspnp/iot-journey/pull/236#discussion_r35144413"},"pull_request":{"href":"https://api.github.com/repos/mspnp/iot-journey/pulls/236"}}},"pull_request":{"url":"https://api.github.com/repos/mspnp/iot-journey/pulls/236","id":40278592,"html_url":"https://github.com/mspnp/iot-journey/pull/236","diff_url":"https://github.com/mspnp/iot-journey/pull/236.diff","patch_url":"https://github.com/mspnp/iot-journey/pull/236.patch","issue_url":"https://api.github.com/repos/mspnp/iot-journey/issues/236","number":236,"state":"open","locked":false,"title":"Revise journal 1 (Cold Storage)","user":{"login":"MikeWasson","id":3992422,"avatar_url":"https://avatars.githubusercontent.com/u/3992422?v=3","gravatar_id":"","url":"https://api.github.com/users/MikeWasson","html_url":"https://github.com/MikeWasson","followers_url":"https://api.github.com/users/MikeWasson/followers","following_url":"https://api.github.com/users/MikeWasson/following{/other_user}","gists_url":"https://api.github.com/users/MikeWasson/gists{/gist_id}","starred_url":"https://api.github.com/users/MikeWasson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MikeWasson/subscriptions","organizations_url":"https://api.github.com/users/MikeWasson/orgs","repos_url":"https://api.github.com/users/MikeWasson/repos","events_url":"https://api.github.com/users/MikeWasson/events{/privacy}","received_events_url":"https://api.github.com/users/MikeWasson/received_events","type":"User","site_admin":false},"body":"#192 \r\n","created_at":"2015-07-17T22:50:36Z","updated_at":"2015-07-21T19:35:42Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9bcc18c822a0f3fc1d89270365e2880dc465bca3","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/mspnp/iot-journey/pulls/236/commits","review_comments_url":"https://api.github.com/repos/mspnp/iot-journey/pulls/236/comments","review_comment_url":"https://api.github.com/repos/mspnp/iot-journey/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mspnp/iot-journey/issues/236/comments","statuses_url":"https://api.github.com/repos/mspnp/iot-journey/statuses/1c1ae768402ae3899b1b97d0506cc53ecf74eaf0","head":{"label":"mspnp:wasson/journal1","ref":"wasson/journal1","sha":"1c1ae768402ae3899b1b97d0506cc53ecf74eaf0","user":{"login":"mspnp","id":1373420,"avatar_url":"https://avatars.githubusercontent.com/u/1373420?v=3","gravatar_id":"","url":"https://api.github.com/users/mspnp","html_url":"https://github.com/mspnp","followers_url":"https://api.github.com/users/mspnp/followers","following_url":"https://api.github.com/users/mspnp/following{/other_user}","gists_url":"https://api.github.com/users/mspnp/gists{/gist_id}","starred_url":"https://api.github.com/users/mspnp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mspnp/subscriptions","organizations_url":"https://api.github.com/users/mspnp/orgs","repos_url":"https://api.github.com/users/mspnp/repos","events_url":"https://api.github.com/users/mspnp/events{/privacy}","received_events_url":"https://api.github.com/users/mspnp/received_events","type":"Organization","site_admin":false},"repo":{"id":34227406,"name":"iot-journey","full_name":"mspnp/iot-journey","owner":{"login":"mspnp","id":1373420,"avatar_url":"https://avatars.githubusercontent.com/u/1373420?v=3","gravatar_id":"","url":"https://api.github.com/users/mspnp","html_url":"https://github.com/mspnp","followers_url":"https://api.github.com/users/mspnp/followers","following_url":"https://api.github.com/users/mspnp/following{/other_user}","gists_url":"https://api.github.com/users/mspnp/gists{/gist_id}","starred_url":"https://api.github.com/users/mspnp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mspnp/subscriptions","organizations_url":"https://api.github.com/users/mspnp/orgs","repos_url":"https://api.github.com/users/mspnp/repos","events_url":"https://api.github.com/users/mspnp/events{/privacy}","received_events_url":"https://api.github.com/users/mspnp/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mspnp/iot-journey","description":"a guidance project for implementing an IoT solution on Azure","fork":false,"url":"https://api.github.com/repos/mspnp/iot-journey","forks_url":"https://api.github.com/repos/mspnp/iot-journey/forks","keys_url":"https://api.github.com/repos/mspnp/iot-journey/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mspnp/iot-journey/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mspnp/iot-journey/teams","hooks_url":"https://api.github.com/repos/mspnp/iot-journey/hooks","issue_events_url":"https://api.github.com/repos/mspnp/iot-journey/issues/events{/number}","events_url":"https://api.github.com/repos/mspnp/iot-journey/events","assignees_url":"https://api.github.com/repos/mspnp/iot-journey/assignees{/user}","branches_url":"https://api.github.com/repos/mspnp/iot-journey/branches{/branch}","tags_url":"https://api.github.com/repos/mspnp/iot-journey/tags","blobs_url":"https://api.github.com/repos/mspnp/iot-journey/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mspnp/iot-journey/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mspnp/iot-journey/git/refs{/sha}","trees_url":"https://api.github.com/repos/mspnp/iot-journey/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mspnp/iot-journey/statuses/{sha}","languages_url":"https://api.github.com/repos/mspnp/iot-journey/languages","stargazers_url":"https://api.github.com/repos/mspnp/iot-journey/stargazers","contributors_url":"https://api.github.com/repos/mspnp/iot-journey/contributors","subscribers_url":"https://api.github.com/repos/mspnp/iot-journey/subscribers","subscription_url":"https://api.github.com/repos/mspnp/iot-journey/subscription","commits_url":"https://api.github.com/repos/mspnp/iot-journey/commits{/sha}","git_commits_url":"https://api.github.com/repos/mspnp/iot-journey/git/commits{/sha}","comments_url":"https://api.github.com/repos/mspnp/iot-journey/comments{/number}","issue_comment_url":"https://api.github.com/repos/mspnp/iot-journey/issues/comments{/number}","contents_url":"https://api.github.com/repos/mspnp/iot-journey/contents/{+path}","compare_url":"https://api.github.com/repos/mspnp/iot-journey/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mspnp/iot-journey/merges","archive_url":"https://api.github.com/repos/mspnp/iot-journey/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mspnp/iot-journey/downloads","issues_url":"https://api.github.com/repos/mspnp/iot-journey/issues{/number}","pulls_url":"https://api.github.com/repos/mspnp/iot-journey/pulls{/number}","milestones_url":"https://api.github.com/repos/mspnp/iot-journey/milestones{/number}","notifications_url":"https://api.github.com/repos/mspnp/iot-journey/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mspnp/iot-journey/labels{/name}","releases_url":"https://api.github.com/repos/mspnp/iot-journey/releases{/id}","created_at":"2015-04-19T22:49:18Z","updated_at":"2015-07-20T13:00:19Z","pushed_at":"2015-07-20T23:06:54Z","git_url":"git://github.com/mspnp/iot-journey.git","ssh_url":"git@github.com:mspnp/iot-journey.git","clone_url":"https://github.com/mspnp/iot-journey.git","svn_url":"https://github.com/mspnp/iot-journey","homepage":"","size":6375,"stargazers_count":28,"watchers_count":28,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":13,"mirror_url":null,"open_issues_count":56,"forks":13,"open_issues":56,"watchers":28,"default_branch":"master"}},"base":{"label":"mspnp:master","ref":"master","sha":"1a4b06b2221f9a1fe6e6e9e11ab2b52756aa5acb","user":{"login":"mspnp","id":1373420,"avatar_url":"https://avatars.githubusercontent.com/u/1373420?v=3","gravatar_id":"","url":"https://api.github.com/users/mspnp","html_url":"https://github.com/mspnp","followers_url":"https://api.github.com/users/mspnp/followers","following_url":"https://api.github.com/users/mspnp/following{/other_user}","gists_url":"https://api.github.com/users/mspnp/gists{/gist_id}","starred_url":"https://api.github.com/users/mspnp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mspnp/subscriptions","organizations_url":"https://api.github.com/users/mspnp/orgs","repos_url":"https://api.github.com/users/mspnp/repos","events_url":"https://api.github.com/users/mspnp/events{/privacy}","received_events_url":"https://api.github.com/users/mspnp/received_events","type":"Organization","site_admin":false},"repo":{"id":34227406,"name":"iot-journey","full_name":"mspnp/iot-journey","owner":{"login":"mspnp","id":1373420,"avatar_url":"https://avatars.githubusercontent.com/u/1373420?v=3","gravatar_id":"","url":"https://api.github.com/users/mspnp","html_url":"https://github.com/mspnp","followers_url":"https://api.github.com/users/mspnp/followers","following_url":"https://api.github.com/users/mspnp/following{/other_user}","gists_url":"https://api.github.com/users/mspnp/gists{/gist_id}","starred_url":"https://api.github.com/users/mspnp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mspnp/subscriptions","organizations_url":"https://api.github.com/users/mspnp/orgs","repos_url":"https://api.github.com/users/mspnp/repos","events_url":"https://api.github.com/users/mspnp/events{/privacy}","received_events_url":"https://api.github.com/users/mspnp/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mspnp/iot-journey","description":"a guidance project for implementing an IoT solution on Azure","fork":false,"url":"https://api.github.com/repos/mspnp/iot-journey","forks_url":"https://api.github.com/repos/mspnp/iot-journey/forks","keys_url":"https://api.github.com/repos/mspnp/iot-journey/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mspnp/iot-journey/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mspnp/iot-journey/teams","hooks_url":"https://api.github.com/repos/mspnp/iot-journey/hooks","issue_events_url":"https://api.github.com/repos/mspnp/iot-journey/issues/events{/number}","events_url":"https://api.github.com/repos/mspnp/iot-journey/events","assignees_url":"https://api.github.com/repos/mspnp/iot-journey/assignees{/user}","branches_url":"https://api.github.com/repos/mspnp/iot-journey/branches{/branch}","tags_url":"https://api.github.com/repos/mspnp/iot-journey/tags","blobs_url":"https://api.github.com/repos/mspnp/iot-journey/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mspnp/iot-journey/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mspnp/iot-journey/git/refs{/sha}","trees_url":"https://api.github.com/repos/mspnp/iot-journey/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mspnp/iot-journey/statuses/{sha}","languages_url":"https://api.github.com/repos/mspnp/iot-journey/languages","stargazers_url":"https://api.github.com/repos/mspnp/iot-journey/stargazers","contributors_url":"https://api.github.com/repos/mspnp/iot-journey/contributors","subscribers_url":"https://api.github.com/repos/mspnp/iot-journey/subscribers","subscription_url":"https://api.github.com/repos/mspnp/iot-journey/subscription","commits_url":"https://api.github.com/repos/mspnp/iot-journey/commits{/sha}","git_commits_url":"https://api.github.com/repos/mspnp/iot-journey/git/commits{/sha}","comments_url":"https://api.github.com/repos/mspnp/iot-journey/comments{/number}","issue_comment_url":"https://api.github.com/repos/mspnp/iot-journey/issues/comments{/number}","contents_url":"https://api.github.com/repos/mspnp/iot-journey/contents/{+path}","compare_url":"https://api.github.com/repos/mspnp/iot-journey/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mspnp/iot-journey/merges","archive_url":"https://api.github.com/repos/mspnp/iot-journey/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mspnp/iot-journey/downloads","issues_url":"https://api.github.com/repos/mspnp/iot-journey/issues{/number}","pulls_url":"https://api.github.com/repos/mspnp/iot-journey/pulls{/number}","milestones_url":"https://api.github.com/repos/mspnp/iot-journey/milestones{/number}","notifications_url":"https://api.github.com/repos/mspnp/iot-journey/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mspnp/iot-journey/labels{/name}","releases_url":"https://api.github.com/repos/mspnp/iot-journey/releases{/id}","created_at":"2015-04-19T22:49:18Z","updated_at":"2015-07-20T13:00:19Z","pushed_at":"2015-07-20T23:06:54Z","git_url":"git://github.com/mspnp/iot-journey.git","ssh_url":"git@github.com:mspnp/iot-journey.git","clone_url":"https://github.com/mspnp/iot-journey.git","svn_url":"https://github.com/mspnp/iot-journey","homepage":"","size":6375,"stargazers_count":28,"watchers_count":28,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":13,"mirror_url":null,"open_issues_count":56,"forks":13,"open_issues":56,"watchers":28,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mspnp/iot-journey/pulls/236"},"html":{"href":"https://github.com/mspnp/iot-journey/pull/236"},"issue":{"href":"https://api.github.com/repos/mspnp/iot-journey/issues/236"},"comments":{"href":"https://api.github.com/repos/mspnp/iot-journey/issues/236/comments"},"review_comments":{"href":"https://api.github.com/repos/mspnp/iot-journey/pulls/236/comments"},"review_comment":{"href":"https://api.github.com/repos/mspnp/iot-journey/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mspnp/iot-journey/pulls/236/commits"},"statuses":{"href":"https://api.github.com/repos/mspnp/iot-journey/statuses/1c1ae768402ae3899b1b97d0506cc53ecf74eaf0"}}}}