During Connect(); 2017 event this year we presented beautiful app demos using Xamarin and many features of Azure. For //build/ 2018's keynote, we updated some components of the back-end API code to support Azure Kubernetes Service (AKS). This repository contains the setup instructions and sample code needed for the Internet of Things (IoT) Demo utilizing Digital Twins that was announced at Ignite 2018.
For this reference app scenario, we built several consumer and line-of-business apps and an Azure backend. You can find all SmartHotel360 repos in the following locations:
- SmartHotel360
- IoT Demo
- Backend Services (optimized for Kubernetes)
- Public Website
- Pet Checker Serverless Function
- Mobile Apps
- Sentiment Analysis
- Migrating Internal apps to Azure
- Original Backend Services
Welcome to the SmartHotel360 IoT repository. Here you'll find everything you need to run the website and backend for the IoT demo.
SmartHotel360 uses a microservice oriented architecture implemented using containers. For the IoT Demo, there are various services developed in different technologies: .NET Core 2, Asp.Net Core 2, and Angular. These services use different Azure Resources like Digital Twins, App Services, Cosmos DB, Event Hubs, Azure Functions, and IoT Hubs to name a few. The step by step walkthrough for creating and provisioning the demo can be found next in the Setup section.
End-to-end setup takes about an hour provided you have all of the development environment prerequisites met AND that your user has the required permissions in your Azure subscription.
- Powershell for running provisioning Azure provisioning scripts. Powershell Core is available for Mac and Linux users.
- Docker to build the containers.
- Visual Studio 2017 with the
.NET desktop development
andASP.NET and web development
workloads installed. - Azure CLI
- Kubernetes CLI
- Angular CLI
- Required Azure Subscription Permissions
- Create and modify Azure AD Application Registrations or have someone else do it for you
- Create a new Service Principal for Role Based Access Control (RBAC) or have someone else do it for you
- Create or add 2 new guest users to the Active Directory (AD) or have someone else do it for you and get you the Object Ids of those users
- Create a ResourceGroup or have one that someone else already created for you to use
- Create a deployment into a ResourceGroup
- Give the Service Principal in #2 read permissions to read from the ACR created by the deployment (if not, then script provides the user with an Azure Cli command to execute to be run by someone with the required permission, and pauses until the user says this step has been completed)
Follow these instructions to create a service principal and register an Azure Active Directory application.
During the creation process you will need to take note of the following information:
- Tenant Id
- App Id
- App Key
To obtain the service principal Id, open a Powershell window and follow these steps:
Login-AzureRmAccount -SubscriptionId {subcription id}
Get-AzureRmADServicePrincipal -ApplicationId {app Id}
Click settings --> Required Permissions
- Click Add on the top left
- Select the API you'd like to use to get external data into Digital Twins (e.g. Microsoft Graph)
- Select the permissions that your app needs to have in order to access the correct information
- Select Save, and then click Add again
- Select the "Azure Smart Spaces Service" API
- Check the Read/Write Access delegated permissions box
- Save, and select Grant Permissions
To create a service principal for an AKS Cluster, open a Powershell/Command Prompt/Bash window and follow these steps:
az login
az account set -s {subscription id}
az ad sp create-for-rbac --skip-assignment
The sp create-for-rbac
command will return a json object that will have the information needed later in this process.
{
"appId": "{aks app id}",
"displayName": "{aks display name}",
"name": "{aks uri}",
"password": "{aks service principal password}",
"tenant": "{aks tenant id}"
}
You need to create two users having access to your AAD. These can either be users created in your AAD or guest users that you add. For both of these users, you need to collect the Object Id for them. One user will be used for the Manager role and the other the Employee role.
- To get the Object Id, view the user in AAD and you will see Object ID under the Identity Section. This is a similar process to using the Admin Center of a subscription backed by an Office 365 environment.
In the /arm/
folder of this repository is the deployment script to create and stand up all of the resources to run this demo in Azure. To execute the deployment script, run the following in a Powershell window:
.\deploy.ps1 -subscriptionId {subscription id} -resourceGroupName {resource group name} -resourceGroupLocation {resource group location} -managerObjId {manager object id} -employeeObjId {employee object id} -clientId {app id} -clientSecret {app key} -clientServicePrincipalId {service principal id} -aksServicePrincipalId {AKS Service Principal App Id} -aksServicePrincipalKey {AKS Service Principal password}
The following information parameters are required for the deployment script:
{subscription id}
: the Azure subscription id that has been used in this setup{resource group name}
: the resource group name to add the created resource, if it doesn't exist it will be created{resource group location}
: location for the resource group: (ie. 'westus2'){manager object id}
: object Id obtained when creating Manager user above{employee object id}
: object Id obtained when creating Employee user above{app id}
: app id obtained from creating an AAD app{app key}
: app key obtained from creating an AAD app{service principal id}
: service principal id from above{AKS service principal app id}
: AKS app id from above{AKS service principal password}
: AKS service principal password from above
There is a collection of parameters that are used by the deployment script that determine properties like resource location, pricing tiers, and naming. If you wish to modify any of these parameters you can edit the values in parameters.json.
When the deployment script is complete, it will output a userSettings.json
file with information needed for the rest of the deployment.
{
"tenantId": "{tenant id}",
"clientId": "{client id}",
"aadReplyUrl": "{facility management web reply uri for ADAL}",
"digitalTwinsManagementEndpoint": "{digital twins management endpoint}",
"facilityManagementWebsiteUri": "url to the facility management website",
"facilityManagementApiUri": "{facility management api}",
"facilityManagementApiEndpoint": "{facility management api endpoint}",
"storageConnectionString": "{connection string to azure storage account}",
"eventHubConsumerConnectionString": "{consumer connection string to the event hub}",
"iotHubConnectionString": "{connection string to the iot hub}",
"cosmosDbConnectionString": "{connection string to the cosmos db}",
"roomDevicesApiEndpoint": "{room devices api endpoint - needed for running the Xamarin Mobile Clients}",
"room11SpaceId": "{room 11 space id - needed for running the Xamarin Mobile Clients}"
}
NOTE: If you are going to run the IoT Demo for the Xamarin Mobile Apps, then you will need the roomDevicesApiEndpoint
and room11SpaceId
values from the userSettings.json
file.
To verify that everything is working correctly, open up the facilityManagementWebsiteUri
(from the userSettings.json
in the browser and log in with one of the two users created during the provisioning steps.
Portions of this demo can be run locally. In order to do so, you still must complete the Setup section. Once you have completed the provisioning, you can follow these steps to configure, build, and deploy the resource locally.
The Sensor Data function can run locally in Visual Studio. However, in order to avoid conflicts, you must first disable the Azure Function that was created during Setup.
- Log in to the Azure Portal.
- Navigate to Function Apps and select the Azure Function that was created during Setup.
- Click the Stop button to disable the Azure Function.
- Open the
/backend/src/SmartHotel.Services/SmartHotel.Services.sln
solution in Visual Studio 2017 - Set the
SmartHotel.Services.SensorDataFunction
project as the startup project - Right-click the
SmartHotel.Services.SensorDataFunction
project in the Solution Explorer - Add a new json file named:
local.settings.json
and set the contents to this:{ "IsEncrypted": false, "Values": { "AzureWebJobsStorage": "{storage connection string}", "AzureWebJobsDashboard": "{storage connection string}", "FUNCTIONS_WORKER_RUNTIME": "dotnet", "EventHubConnectionString": "{event hub consumer connection string}", "CosmosDBConnectionString": "{cosmos db connection string}", } }
- {storage connection string}:
storageConnectionString
from the userSettings.json file from the User Settings section - {event hub consumer connection string}:
eventHubConsumerConnectionString
from the userSettings.json file from the User Settings section - {cosmos db connection string}:
cosmosDbConnectionString
from the userSettings.json file from the User Settings section
- {storage connection string}:
- Run in debug mode.
While running the devices locally, we need to remove the instances that exist in the Kubernetes cluster. Run the following steps from a Powershell/Command Prompt/Bash window:
kubectl delete pods,deployments,replicasets --all
- this removes ALL pods from the cluster, including the Room Devices Api pod.- If NOT running the Room Devices Api locally, then re-deploy that pod to the cluster:
- Change directory to
/backend/src/SmartHotel.Services
kubectl apply -f deployments.demo.yaml
- Change directory to
To redeploy the devices to the cluster:
- Change directory to
/backend/src/SmartHotel.Devices
kubectl apply -f deployments.demo.yaml
The Apis can be run locally at the same time as their Azure counterparts.
From a Powershell/Command Prompt/Bash window
- Change directory to
/backend/src/SmartHotel.Services
docker-compose build
- only required if you're making changes and want to see them.docker-compose -f docker-compose.yml -f docker-compose.override.yml up
- Open the
/backend/src/SmartHotel.Services/SmartHotel.Services.sln
solution in Visual Studio 2017 - Select either the
SmartHotel.Services.FacilityManagement
orSmartHotel.Services.FacilityManagement
project as the startup project - Update the
appsettings.json
file.- SmartHotel.Services.FacilityManagement:
- ManagementApiUrl:
digitalTwinsManagementEndpoint
from the userSettings.json file from the User Settings section - MongoDBConnectionString:
cosmosDbConnectionString
from the userSettings.json file from the User Settings section
- ManagementApiUrl:
- SmartHotel.Services.RoomDevicesApi:
- IoTHubConnectionString:
iotHubConnectionString
from the userSettings.json file from the User Settings section - DatabaseConnectionString:
cosmosDbConnectionString
from the userSettings.json file from the User Settings section
- IoTHubConnectionString:
- SmartHotel.Services.FacilityManagement:
- Run in debug mode.
The Website can be run locally at the same time as its Azure counterpart.
-
Open the
/FacilityManagementWebsite/SmartHotel.FacilityManagementWeb/SmartHotel.FacilityManagementWeb.sln
solution in Visual Studio 2017 -
If you desire the website to connect to the Facility Management API in Azure, then run in debug mode.
-
Otherwise, update the
environment.ts
andenvironment.prod.ts
files under/SmartHotel.FacilityManagementWeb/ClientApp/src/environments
:export const environment = { production: true, version: 'Production', sensorDataTimer: {sensorDataTime}, adalConfig: { tenant: '{tenantId}', clientId: '{clientId}', endpoints: { '{apiUri}': '{clientId}' } } as adal.Config, apiEndpoint: '{apiEndpoint}', resourceId: '0b07f429-9f4b-4714-9392-cc5e8e80c8b0' };
- {apiUri}: Must be updated to point to wherever your local Facility Management Api is running (e.g.
http://localhost:3000
) - {apiEndpoint}: Must be updated to point to wherever your local Facility Management Api is running, but append
/api
(e.g.http://localhost:3000/api
)
- {apiUri}: Must be updated to point to wherever your local Facility Management Api is running (e.g.
-
Then run in debug mode.
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.