Skip to content

Commit a4834ed

Browse files
stefan-hudelmaiergitbook-bot
authored andcommitted
GITBOOK-223: No subject
1 parent ca02c1c commit a4834ed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1791
-63
lines changed

.gitbook/assets/image (1) (1).png

35.7 KB
Loading

.gitbook/assets/image (1).png

-11.8 KB
Loading

.gitbook/assets/image (10).png

21.7 KB
Loading

.gitbook/assets/image (11).png

14.1 KB
Loading

.gitbook/assets/image (12).png

-52.7 KB
Loading

.gitbook/assets/image (13).png

-95.5 KB
Loading

.gitbook/assets/image (14).png

71.9 KB
Loading

.gitbook/assets/image (15).png

56.5 KB
Loading

.gitbook/assets/image (16).png

-59.5 KB
Loading

.gitbook/assets/image (17).png

-53.3 KB
Loading

.gitbook/assets/image (18).png

62.4 KB
Loading

.gitbook/assets/image (19).png

85.1 KB
Loading

.gitbook/assets/image (2) (2).png

37.4 KB
Loading

.gitbook/assets/image (2).png

74.1 KB
Loading

.gitbook/assets/image (20).png

23.5 KB
Loading

.gitbook/assets/image (21).png

23.5 KB
Loading

.gitbook/assets/image (22).png

35.7 KB
Loading

.gitbook/assets/image (23).png

66.1 KB
Loading

.gitbook/assets/image (3).png

95.8 KB
Loading

.gitbook/assets/image (4).png

-8.04 KB
Loading

.gitbook/assets/image (5).png

-5.56 KB
Loading

.gitbook/assets/image (6).png

56.6 KB
Loading

.gitbook/assets/image (8).png

3.93 KB
Loading

.gitbook/assets/image (9).png

21.2 KB
Loading

.gitbook/assets/image.png

-3.33 KB
Loading

.gitbook/assets/migrate-redis.py

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#!/usr/bin/env python
2+
import json
3+
import re
4+
import subprocess
5+
import sys
6+
7+
from termcolor import colored
8+
9+
10+
def run_command(command):
11+
runnable_command = command.split()
12+
output = subprocess.check_output(runnable_command).decode("utf-8")
13+
14+
return output
15+
16+
17+
def run_command_with_json_output(command):
18+
output = run_command(command)
19+
result = json.loads(output)
20+
21+
return result
22+
23+
24+
def print_usage(error=None):
25+
if error:
26+
print(colored(error, 'red'))
27+
28+
print(f"""
29+
{colored('Usage:', 'white')}
30+
Recommended usage:
31+
- ./migrate-redis.py https://url-to-source-ux4iot-in-azure-portal.com/ https://url-to-target-ux4iot-in-azure-portal.com/
32+
33+
Alternative usage:
34+
- ./migrate-redis.py source_subscription_id source_resource_group source_ux4iot_name target_subscription_id target_resource_group target_ux4iot_name
35+
""")
36+
37+
38+
def parse_ux4iot_args(args):
39+
if len(args) == 0:
40+
print_usage('Illegal number of parameters')
41+
sys.exit(1)
42+
43+
url_pattern = r'^https?://' # Regular expression pattern to match the start of a URL
44+
source_url = args[0]
45+
target_url = args[1]
46+
47+
if re.match(url_pattern, source_url) and re.match(url_pattern, target_url):
48+
# The variable contains a valid URL
49+
# Extract the subscription ID
50+
source_subscription_id = re.search(
51+
r'subscriptions/([^/]+)', source_url).group(1)
52+
53+
# Extract the resource group
54+
source_resource_group = re.search(
55+
r'resourceGroups/([^/]+)', source_url).group(1)
56+
57+
# Extract the service name
58+
source_ux4iot_name = re.search(
59+
r'applications/([^/]+)', source_url).group(1)
60+
61+
# The variable contains a valid URL
62+
# Extract the subscription ID
63+
target_subscription_id = re.search(
64+
r'subscriptions/([^/]+)', target_url).group(1)
65+
66+
# Extract the resource group
67+
target_resource_group = re.search(
68+
r'resourceGroups/([^/]+)', target_url).group(1)
69+
70+
# Extract the service name
71+
target_ux4iot_name = re.search(
72+
r'applications/([^/]+)', target_url).group(1)
73+
74+
else:
75+
# The variable does not contain a valid URL
76+
if len(args) < 6:
77+
print_usage("Illegal number of parameters")
78+
sys.exit(1)
79+
80+
print(args)
81+
82+
source_subscription_id = args[0]
83+
source_resource_group = args[1]
84+
source_ux4iot_name = args[2]
85+
target_subscription_id = args[3]
86+
target_resource_group = args[4]
87+
target_ux4iot_name = args[5]
88+
89+
return {
90+
"source_subscription_id": source_subscription_id,
91+
"source_resource_group": source_resource_group,
92+
"source_ux4iot_name": source_ux4iot_name,
93+
"target_subscription_id": target_subscription_id,
94+
"target_resource_group": target_resource_group,
95+
"target_ux4iot_name": target_ux4iot_name,
96+
}
97+
98+
99+
def copy_redis_file_share(source_storage_account, target_storage_account):
100+
pass
101+
102+
103+
def get_dump_file_url(subscription_id, resource_group, ux4iot_name):
104+
managed_app = run_command_with_json_output(
105+
f"az managedapp show --subscription {subscription_id} --resource-group {resource_group} --name {ux4iot_name}")
106+
managed_resource_group_id = managed_app['managedResourceGroupId']
107+
managed_resource_group_resource = run_command_with_json_output(
108+
f"az resource show --ids {managed_resource_group_id}") # | jq -r .name)
109+
managed_resource_group_name = managed_resource_group_resource['name']
110+
resources = run_command_with_json_output(
111+
f"az resource list --resource-group {managed_resource_group_name}")
112+
storage_account_name = next(
113+
(r['name'] for r in resources if r["type"] == "Microsoft.Storage/storageAccounts"), None)
114+
115+
print('Getting redisi dump file url')
116+
storage_redis_dump_file_url = run_command_with_json_output(
117+
f"az storage file url --account-name {storage_account_name} --path dump.rdb --share-name redis")
118+
119+
print('Getting sas token for redis dump file')
120+
sas_token = run_command_with_json_output(
121+
f"az storage file generate-sas --account-name {storage_account_name} --start 2023-01-09T00:00:00Z --expiry 2023-12-31T23:59:00Z --path dump.rdb --permissions rw --share-name redis")
122+
123+
return f"{storage_redis_dump_file_url}?{sas_token}"
124+
125+
126+
def main():
127+
args = sys.argv[1:]
128+
if len(args) != 2 and len(args) != 6:
129+
print_usage('Invalid number of arguments')
130+
return
131+
132+
try:
133+
ux4iot = parse_ux4iot_args(args)
134+
source_storage_account_url = get_dump_file_url(
135+
ux4iot['source_subscription_id'], ux4iot['source_resource_group'], ux4iot['source_ux4iot_name'])
136+
target_storage_account_url = get_dump_file_url(
137+
ux4iot['target_subscription_id'], ux4iot['target_resource_group'], ux4iot['target_ux4iot_name'])
138+
print(source_storage_account_url)
139+
print(target_storage_account_url)
140+
copy_command = f"azcopy copy {source_storage_account_url} {target_storage_account_url}"
141+
subprocess.run(copy_command.split(), check=True, text=True)
142+
except AttributeError as e:
143+
print_usage()
144+
print(e)
145+
sys.exit(1)
146+
147+
148+
if __name__ == '__main__':
149+
main()
Loading
Loading
Loading
Loading
8.63 KB
Loading

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ ux4iot is a tool for directly communicating with your IoT devices from your web
66

77
### General architecture
88

9-
![](<.gitbook/assets/ux4iot-architecture (1).png>)
9+
![IoTHub + Ux4iot + Frontend Architecture setup](<.gitbook/assets/ux4iot-architecture (1).png>)
1010

1111
With ux4iot your frontend gets access to Azure IoT Hub's communication primitives without having a custom-built backend middleware translating between IoT Hub and your user interface. No need to design a REST API so that your UI can offer IoT functionality.
1212

SUMMARY.md

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,18 @@
44
* [Quickstart](quickstart.md)
55
* [Concepts](concepts.md)
66
* [How Ux4iot works](how-ux4iot-works.md)
7+
* [REST API Reference](rest-api-reference.md)
8+
* [Configuration Options](configuration-options.md)
9+
* [Create your ux4iot Instance](create-ux4iot-instance.md)
710

8-
## Setup
11+
## EventHub / IoTHub
912

10-
* [Create your ux4iot Instance](setup/create-ux4iot-instance.md)
11-
* [Configure your existing IoT Hub](setup/configure-your-iot-hub.md)
12-
* [Create IoT Hub and linked ux4iot](setup/create-iot-hub-and-linked-ux4iot.md)
13-
* [Using a separate Event Hub](setup/using-a-separate-event-hub.md)
13+
* [Configure your existing IoT Hub](eventhub-iothub/configure-your-iot-hub.md)
14+
* [Create IoT Hub and linked ux4iot](eventhub-iothub/create-iot-hub-and-linked-ux4iot.md)
15+
* [Using a separate Event Hub](eventhub-iothub/using-a-separate-event-hub.md)
1416

15-
## Developing web apps with React <a href="#using-react" id="using-react"></a>
17+
## ux4iot-react <a href="#using-react" id="using-react"></a>
1618

17-
* [Installing the library](using-react/introduction.md)
1819
* [Initialization](using-react/initialization.md)
1920
* [Hooks](using-react/hooks.md)
2021
* [Grant Request Function](using-react/implementing-the-grantrequestforwarder-function.md)
@@ -24,17 +25,15 @@
2425

2526
* [Introduction](implementing-your-custom-security-backend/introduction.md)
2627
* [Security Backend](implementing-your-custom-security-backend/implementing-the-security-backend.md)
27-
* [Security Backend Examples](implementing-your-custom-security-backend/security-backend-examples/README.md)
28-
* [Azure Function using Javascript](implementing-your-custom-security-backend/security-backend-examples/azure-function-example-for-security-backend.md)
29-
* [Ux4iot Typescript Client](implementing-your-custom-security-backend/ux4iot-typescript-client.md)
30-
* [Admin REST API](implementing-your-custom-security-backend/admin-rest-api.md)
28+
* [Security Backend Example - Azure Function](implementing-your-custom-security-backend/security-backend-examples.md)
29+
* [ux4iot-admin-node](implementing-your-custom-security-backend/ux4iot-admin-node.md)
3130

3231
## Resources
3332

3433
* [Pricing](resources/cost.md)
3534
* [Performance](resources/performance.md)
3635
* [Limitations](resources/limitations.md)
37-
* [FAQ](resources/faq.md)
36+
* [Known Bugs & Nice to know's](resources/faq.md)
3837
* [Changelog](resources/changelog.md)
3938

4039
***

configuration-options.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
description: All available deployment options for ux4iot
3+
---
4+
5+
# Configuration Options
6+
7+
You can generally deploy a ux4iot without specifying any parameters, except for the `iotHubEventHubConnectionString`. This is because we provide default values for all other configuration variables. However we **highly recommend setting a serverVersion. Without it you will deploy the latest code version which is basically a version of a single commit. You will use a development version of ux4iot then.**
8+
9+
The configuration options are somewhat ordered by priority. You will need the last ones the least amount of time. We recommend to deploy a ux4iot service with at least the following configuration variables:
10+
11+
* serverVersion
12+
* iotHubEventHubConnectionString
13+
* iotHubServiceConnectionString
14+
* eventHubConsumerGroup
15+
* sku
16+
17+
<table data-full-width="true"><thead><tr><th width="311.5">Bicep / ARM Parameter</th><th width="148">Default Value</th><th width="369">Description</th><th>Allowed Values</th><th>type</th></tr></thead><tbody><tr><td>serverVersion</td><td>latest</td><td>ux4iot docker image version to deploy</td><td></td><td>infra</td></tr><tr><td>iotHubEventHubConnectionString</td><td></td><td>The connection string of the EventHub that publishes data you want to subscribe to</td><td></td><td>server</td></tr><tr><td>iotHubServiceConnectionString</td><td>""</td><td>The service connection string of the IoTHub you want to access for devices. <strong>You need to pick a connection string that includes the policies "Registry Read" and "Service Connect"</strong></td><td></td><td>server</td></tr><tr><td>eventHubConsumerGroup</td><td>$Default</td><td>The consumer group of the EventHub that publishes data you want to subscribe to</td><td></td><td>server</td></tr><tr><td>sku</td><td>standard</td><td>The scaling tier of ux4iot. Influences cpu and memory of ux4iot and redis containers within the container app.<br><br>Standard:<br>cpu cores redis: 0.5<br>memory redis: 1Gi<br>cpu cores ux4iot: 1.0<br>memory ux4iot: 2Gi<br><br>Small:<br>cpu cores redis: 0.25<br>memory redis: 0.5Gi<br>cpu cores ux4iot: 0.5<br>memory ux4iot: 1Gi</td><td>standard | small</td><td>infra</td></tr><tr><td>throttlingInterval</td><td>-1</td><td>Throttle time to delay messages put on the websocket for consumers in milliseconds.</td><td></td><td>server</td></tr><tr><td>connectionStateCacheTTL</td><td>60</td><td>Time how long a connection state update is persisted in the internal ux4iot cache, in seconds. Set to -1 set the lifetime to infinity.</td><td></td><td>server</td></tr><tr><td>customTimestampKey</td><td>_ts</td><td>Custom object key of a message to look for the timestamp</td><td></td><td>server</td></tr><tr><td>customDeviceIdKey</td><td>deviceId</td><td>Custom object key of a message to look for the deviceId</td><td></td><td>server</td></tr><tr><td>customConnectionStateKey</td><td>""</td><td>Custom object key of a message to look for the connectionState.</td><td></td><td>server</td></tr><tr><td>connectionStateOnTelemetry</td><td>true</td><td>Flag on whether the connection state of a device should be updated whenever a telemetry message for that device is received.</td><td>true | false</td><td>server</td></tr><tr><td>logLevel</td><td>info</td><td>Sets the initial log level of ux4iot</td><td>error | warn | info | verbose | debug</td><td>server</td></tr><tr><td>location</td><td>resourceGroup().location</td><td>The location where all resources of ux4iot should be deployed</td><td></td><td>infra</td></tr><tr><td>logAnalyticsTracesTableTier</td><td>Analytics</td><td>Tier of the log analytics traces table. <strong>You can only change this value once a week, as dictated by microsoft.</strong><br>Basic Tier will give you less options when querying for logs, but is cheaper. Also the retention time will be set to 7 days instead of 90.</td><td>Basic | Analytics</td><td>infra</td></tr><tr><td>redisVersion</td><td>1.2.0</td><td>redis docker image version to deploy</td><td></td><td>infra</td></tr><tr><td>skipCustomResource</td><td>false</td><td>Skips deployment of the internal function app for the custom resource provider</td><td>true | false</td><td>infra</td></tr><tr><td>skipKeyVaultContents</td><td>false</td><td>Skips deployment of key vault secrets, which leads to the update of the iotHubServiceConnectionStringSecret, iotHubEventHubConnectionStringSecret, storageAccountConnectionStringSecret, backendFuncTriggerUrlSecret</td><td>true | false</td><td>infra</td></tr><tr><td>primaryAdminSecret</td><td>""</td><td>Primary Shared Access Key of the Ux4iot</td><td></td><td>infra</td></tr><tr><td>secondaryAdminSecret</td><td>""</td><td>Secondary Shared Access Key of the Ux4iot</td><td></td><td>infra</td></tr></tbody></table>
18+

create-ux4iot-instance.md

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
# Create your ux4iot Instance
2+
3+
ux4iot is installed in your Azure subscription as a Managed Application. Billing will be handled by Microsoft.
4+
5+
## Prerequisits:
6+
7+
* You need to have an azure subscription
8+
* You need to be owner of the resource group that you deploy your ux4iot into. This is because during the deployment, there is a role assigned between managed resources.
9+
10+
### Creating via Azure Marketplace
11+
12+
Visit the [offer on Azure Marketplace](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/deviceinsightgmbh-4961725.ux4iot) and click "Get It Now".
13+
14+
### Creating via Azure Portal
15+
16+
Go to [https://portal.azure.com](https://portal.azure.com) and search for "ux4iot".
17+
18+
### Creating via the command line
19+
20+
If you prefer the command line, the following snippet shows how to do it. See further below for how to retrieve the values for the two parameters.
21+
22+
{% tabs %}
23+
{% tab title="AZ CLI" %}
24+
```bash
25+
RESOURCE_GROUP=ux4iot
26+
SUBSCRIPTION=yourazuresubscription
27+
28+
az managedapp create \
29+
--name ux4iot \
30+
--location westeurope \
31+
--kind marketplace \
32+
--resource-group $RESOURCE_GROUP \
33+
--managed-rg-id /subscriptions/${SUBSCRIPTION}/resourceGroups/ux4iot-resources \
34+
--plan-product ux4iot \
35+
--plan-name standard \
36+
--plan-version 1.5.0 \
37+
--plan-publisher deviceinsightgmbh-4961725 \
38+
--parameters "{\"iotHubEventHubConnectionString\": {\"value\": \"${IOT_HUB_EVENT_HUB_CONNECTION_STRING}\"}, \"iotHubServiceConnectionString\": {\"value\": \"${IOT_HUB_CONNECTION_STRING}\"}}"
39+
```
40+
{% endtab %}
41+
{% endtabs %}
42+
43+
Concerning the parameters: Specifying the Event Hub compatible connection is required. Configuring the service connection string is optional. It is necessary for the following hooks:
44+
45+
* [useDirectMethod](using-react/hooks.md#usedirectmethod)
46+
* [usePatchDesiredProperties](using-react/hooks.md#usepatchdesiredproperties)
47+
48+
In effect, everything that not only consumes information but accesses the devices in some way.
49+
50+
You can retrieve the service connection string for the IoT Hub with:
51+
52+
```bash
53+
IOT_HUB_CONNECTION_STRING=$(az iot hub connection-string show \
54+
--resource-group RESOURCE_GROUP_OF_IOT_HUB \
55+
--subscription SUBSCRIPTION \
56+
--hub-name NAME_OF_IOT_HUB \
57+
--policy-name service
58+
--query connectionString \
59+
-o tsv)
60+
```
61+
62+
You can retrieve the Event Hub compatible endpoint connection string with:
63+
64+
```bash
65+
IOT_HUB_EVENT_HUB_CONNECTION_STRING=$(az iot hub connection-string show \
66+
--resource-group RESOURCE_GROUP_OF_IOT_HUB \
67+
--subscription SUBSCRIPTION \
68+
--hub-name NAME_OF_IOT_HUB \
69+
--query connectionString \
70+
--default-eventhub \
71+
--policy-name service \
72+
-o tsv)
73+
```
74+
75+
Replace `RESOURCE_GROUP_OF_IOT_HUB` with the resource group that your IoT Hub resides in. Replace`NAME_OF_IOT_HUB` with the name of the IoT Hub. Replace `SUBSCRIPTION` with your Azure Subscription.
76+
77+
### Creating via Bicep (Azure Resource Manager)
78+
79+
Here is an example Bicep template that you can use to deploy a ux4iot instance.
80+
81+
<pre><code>resource managedApp 'Microsoft.Solutions/applications@2019-07-01' = {
82+
name: 'ux4iot'
83+
kind: 'marketplace'
84+
location: resourceGroup().location
85+
plan: {
86+
name: 'standard'
87+
product: 'ux4iot'
88+
publisher: 'deviceinsightgmbh-4961725'
89+
version: '1.5.0'
90+
}
91+
properties: {
92+
managedResourceGroupId: 'ux4iot-resources'
93+
parameters: {
94+
// Required
95+
iotHubEventHubConnectionString: {
96+
value: iotHubEventHubConnectionString
97+
}
98+
// Optional
99+
iotHubServiceConnectionString: {
100+
value: iotHubServiceConnectionString
101+
}
102+
// Optional
103+
sku: {
104+
value: 'standard'
105+
}
106+
// Optional
107+
eventHubConsumerGroup: {
108+
value: '$Default'
109+
}
110+
// Optional
111+
customTimestampKey: {
112+
value: '_ts'
113+
}
114+
// Optional
115+
customDeviceIdKey: {
116+
value: 'deviceId'
117+
}
118+
// Optional
119+
primaryAdminSecret: {
120+
value: 'supersecret'
121+
}
122+
// Optional
123+
secondaryAdminSecret: {
124+
<strong> value: 'supersecretaswell'
125+
</strong> }
126+
// Optional
127+
connectionStateCacheTTL: {
128+
value: 60
129+
}
130+
}
131+
}
132+
}
133+
</code></pre>
134+
135+
{% hint style="warning" %}
136+
Notice when you redeploy ux4iot with a different iotHubEventHubConnectionString, **you will need to restart your ux4iot**. You can do this by navigating in the azure portal to your ux4iot instance and clicking the restart button on the top icon bar.&#x20;
137+
{% endhint %}
138+
139+
{% hint style="info" %}
140+
Any tags you specify for the managed app will be inherited by the created managed resource group.
141+
{% endhint %}
142+
143+
Before deploying **for the first time**, you will have to accept the legal terms:
144+
145+
```
146+
az vm image accept-terms \
147+
--publisher 'deviceinsightgmbh-4961725' \
148+
--offer 'ux4iot' \
149+
--plan 'standard'
150+
```
151+
152+
You can now deploy the Bicep template:
153+
154+
```
155+
az deployment group create \
156+
--resource-group ux4iot \
157+
--subscription yourazuresubscription \
158+
--template-file template.bicep
159+
```

0 commit comments

Comments
 (0)