Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 83d1c5b

Browse filesBrowse files
gguussJon Wayne Parrott
authored andcommitted
Adds token refresh to MQTT example. (GoogleCloudPlatform#1197)
* Adds token refresh to MQTT example. * Fixes lint error.
1 parent 0715f6d commit 83d1c5b
Copy full SHA for 83d1c5b

File tree

Expand file treeCollapse file tree

4 files changed

+205
-84
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+205
-84
lines changed

‎iot/api-client/mqtt_example/README.md

Copy file name to clipboardExpand all lines: iot/api-client/mqtt_example/README.md
-51Lines changed: 0 additions & 51 deletions
This file was deleted.
+107Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
.. This file is automatically generated. Do not edit this file directly.
2+
3+
Google Cloud IoT Core API Python Samples
4+
===============================================================================
5+
6+
This directory contains samples for Google Cloud IoT Core API. `Google Cloud IoT Core`_ allows developers to easily integrate Publish and Subscribe functionality with devices and programmatically manage device authorization.
7+
The following example runs the sample using the project ID `blue-jet-123` and the device name `my-python-device`:
8+
9+
python cloudiot_mqtt_example.py \
10+
--registry_id=my-registry \
11+
--project_id=blue-jet-123 \
12+
--device_id=my-python-device \
13+
--algorithm=RS256 \
14+
--private_key_file=../rsa_private.pem
15+
16+
17+
18+
19+
.. _Google Cloud IoT Core API: https://cloud.google.com/iot/docs
20+
21+
Setup
22+
-------------------------------------------------------------------------------
23+
24+
25+
Install Dependencies
26+
++++++++++++++++++++
27+
28+
#. Install `pip`_ and `virtualenv`_ if you do not already have them. You may want to refer to the `Python Development Environment Setup Guide`_ for Google Cloud Platform for instructions.
29+
30+
.. _Python Development Environment Setup Guide:
31+
https://cloud.google.com/python/setup
32+
33+
#. Create a virtualenv. Samples are compatible with Python 2.7 and 3.4+.
34+
35+
.. code-block:: bash
36+
37+
$ virtualenv env
38+
$ source env/bin/activate
39+
40+
#. Install the dependencies needed to run the samples.
41+
42+
.. code-block:: bash
43+
44+
$ pip install -r requirements.txt
45+
46+
.. _pip: https://pip.pypa.io/
47+
.. _virtualenv: https://virtualenv.pypa.io/
48+
49+
Samples
50+
-------------------------------------------------------------------------------
51+
52+
MQTT Device Client Example
53+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
54+
55+
56+
57+
To run this sample:
58+
59+
.. code-block:: bash
60+
61+
$ python cloudiot_mqtt_example.py
62+
63+
usage: cloudiot_mqtt_example.py [-h] [--project_id PROJECT_ID] --registry_id
64+
REGISTRY_ID --device_id DEVICE_ID
65+
--private_key_file PRIVATE_KEY_FILE
66+
--algorithm {RS256,ES256}
67+
[--cloud_region CLOUD_REGION]
68+
[--ca_certs CA_CERTS]
69+
[--num_messages NUM_MESSAGES]
70+
[--message_type {event,state}]
71+
[--mqtt_bridge_hostname MQTT_BRIDGE_HOSTNAME]
72+
[--mqtt_bridge_port {8883,443}]
73+
[--jwt_expires_minutes JWT_EXPIRES_MINUTES]
74+
75+
Example Google Cloud IoT Core MQTT device connection code.
76+
77+
optional arguments:
78+
-h, --help show this help message and exit
79+
--project_id PROJECT_ID
80+
GCP cloud project name
81+
--registry_id REGISTRY_ID
82+
Cloud IoT Core registry id
83+
--device_id DEVICE_ID
84+
Cloud IoT Core device id
85+
--private_key_file PRIVATE_KEY_FILE
86+
Path to private key file.
87+
--algorithm {RS256,ES256}
88+
Which encryption algorithm to use to generate the JWT.
89+
--cloud_region CLOUD_REGION
90+
GCP cloud region
91+
--ca_certs CA_CERTS CA root from https://pki.google.com/roots.pem
92+
--num_messages NUM_MESSAGES
93+
Number of messages to publish.
94+
--message_type {event,state}
95+
Indicates whether the message to be published is a
96+
telemetry event or a device state message.
97+
--mqtt_bridge_hostname MQTT_BRIDGE_HOSTNAME
98+
MQTT bridge hostname.
99+
--mqtt_bridge_port {8883,443}
100+
MQTT bridge port.
101+
--jwt_expires_minutes JWT_EXPIRES_MINUTES
102+
Expiration time, in minutes, for JWT tokens.
103+
104+
105+
106+
107+
.. _Google Cloud SDK: https://cloud.google.com/sdk/
+30Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# This file is used to generate README.rst
2+
3+
product:
4+
name: Google Cloud IoT Core API
5+
short_name: Cloud IoT Core
6+
url: https://cloud.google.com/iot/docs
7+
description: >
8+
`Google Cloud IoT Core`_ allows developers to easily integrate Publish and
9+
Subscribe functionality with devices and programmatically manage device
10+
authorization.
11+
12+
The following example runs the sample using the project ID `blue-jet-123`
13+
and the device name `my-python-device`:
14+
15+
python cloudiot_mqtt_example.py \
16+
--registry_id=my-registry \
17+
--project_id=blue-jet-123 \
18+
--device_id=my-python-device \
19+
--algorithm=RS256 \
20+
--private_key_file=../rsa_private.pem
21+
22+
setup:
23+
- install_deps
24+
25+
samples:
26+
- name: MQTT Device Client Example
27+
file: cloudiot_mqtt_example.py
28+
show_help: True
29+
30+
cloud_client_library: false

‎iot/api-client/mqtt_example/cloudiot_mqtt_example.py

Copy file name to clipboardExpand all lines: iot/api-client/mqtt_example/cloudiot_mqtt_example.py
+68-33Lines changed: 68 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import jwt
3030
import paho.mqtt.client as mqtt
3131

32+
3233
# [START iot_mqtt_jwt]
3334
def create_jwt(project_id, private_key_file, algorithm):
3435
"""Creates a JWT (https://jwt.io) to establish an MQTT connection.
@@ -64,6 +65,8 @@ def create_jwt(project_id, private_key_file, algorithm):
6465
return jwt.encode(token, private_key, algorithm=algorithm)
6566
# [END iot_mqtt_jwt]
6667

68+
69+
# [START iot_mqtt_config]
6770
def error_str(rc):
6871
"""Convert a Paho error to a human readable string."""
6972
return '{}: {}'.format(rc, mqtt.error_string(rc))
@@ -84,6 +87,46 @@ def on_publish(unused_client, unused_userdata, unused_mid):
8487
print('on_publish')
8588

8689

90+
def get_client(
91+
project_id, cloud_region, registry_id, device_id, private_key_file,
92+
algorithm, ca_certs, mqtt_bridge_hostname, mqtt_bridge_port):
93+
"""Create our MQTT client. The client_id is a unique string that identifies
94+
this device. For Google Cloud IoT Core, it must be in the format below."""
95+
client = mqtt.Client(
96+
client_id=('projects/{}/locations/{}/registries/{}/devices/{}'
97+
.format(
98+
project_id,
99+
cloud_region,
100+
registry_id,
101+
device_id)))
102+
103+
# With Google Cloud IoT Core, the username field is ignored, and the
104+
# password field is used to transmit a JWT to authorize the device.
105+
client.username_pw_set(
106+
username='unused',
107+
password=create_jwt(
108+
project_id, private_key_file, algorithm))
109+
110+
# Enable SSL/TLS support.
111+
client.tls_set(ca_certs=ca_certs)
112+
113+
# Register message callbacks. https://eclipse.org/paho/clients/python/docs/
114+
# describes additional callbacks that Paho supports. In this example, the
115+
# callbacks just print to standard out.
116+
client.on_connect = on_connect
117+
client.on_publish = on_publish
118+
client.on_disconnect = on_disconnect
119+
120+
# Connect to the Google MQTT bridge.
121+
client.connect(mqtt_bridge_hostname, mqtt_bridge_port)
122+
123+
# Start the network loop.
124+
client.loop_start()
125+
126+
return client
127+
# [END iot_mqtt_config]
128+
129+
87130
def parse_command_line_args():
88131
"""Parse command line arguments."""
89132
parser = argparse.ArgumentParser(description=(
@@ -131,57 +174,48 @@ def parse_command_line_args():
131174
default=8883,
132175
type=int,
133176
help='MQTT bridge port.')
177+
parser.add_argument(
178+
'--jwt_expires_minutes',
179+
default=20,
180+
type=int,
181+
help=('Expiration time, in minutes, for JWT tokens.'))
134182

135183
return parser.parse_args()
136184

137185

186+
# [START iot_mqtt_run]
138187
def main():
139188
args = parse_command_line_args()
140189

141-
# Create our MQTT client. The client_id is a unique string that identifies
142-
# this device. For Google Cloud IoT Core, it must be in the format below.
143-
client = mqtt.Client(
144-
client_id=('projects/{}/locations/{}/registries/{}/devices/{}'
145-
.format(
146-
args.project_id,
147-
args.cloud_region,
148-
args.registry_id,
149-
args.device_id)))
150-
151-
# With Google Cloud IoT Core, the username field is ignored, and the
152-
# password field is used to transmit a JWT to authorize the device.
153-
client.username_pw_set(
154-
username='unused',
155-
password=create_jwt(
156-
args.project_id, args.private_key_file, args.algorithm))
157-
158-
# Enable SSL/TLS support.
159-
client.tls_set(ca_certs=args.ca_certs)
160-
161-
# Register message callbacks. https://eclipse.org/paho/clients/python/docs/
162-
# describes additional callbacks that Paho supports. In this example, the
163-
# callbacks just print to standard out.
164-
client.on_connect = on_connect
165-
client.on_publish = on_publish
166-
client.on_disconnect = on_disconnect
167-
168-
# Connect to the Google MQTT bridge.
169-
client.connect(args.mqtt_bridge_hostname, args.mqtt_bridge_port)
170-
171-
# Start the network loop.
172-
client.loop_start()
173-
174190
# Publish to the events or state topic based on the flag.
175191
sub_topic = 'events' if args.message_type == 'event' else 'state'
176192

177193
mqtt_topic = '/devices/{}/{}'.format(args.device_id, sub_topic)
178194

195+
jwt_iat = datetime.datetime.utcnow()
196+
jwt_exp_mins = args.jwt_expires_minutes
197+
client = get_client(
198+
args.project_id, args.cloud_region, args.registry_id, args.device_id,
199+
args.private_key_file, args.algorithm, args.ca_certs,
200+
args.mqtt_bridge_hostname, args.mqtt_bridge_port)
201+
179202
# Publish num_messages mesages to the MQTT bridge once per second.
180203
for i in range(1, args.num_messages + 1):
181204
payload = '{}/{}-payload-{}'.format(
182205
args.registry_id, args.device_id, i)
183206
print('Publishing message {}/{}: \'{}\''.format(
184207
i, args.num_messages, payload))
208+
seconds_since_issue = (datetime.datetime.utcnow() - jwt_iat).seconds
209+
if seconds_since_issue > 60 * jwt_exp_mins:
210+
print('Refreshing token after {}s').format(seconds_since_issue)
211+
client.loop_stop()
212+
jwt_iat = datetime.datetime.utcnow()
213+
client = get_client(
214+
args.project_id, args.cloud_region,
215+
args.registry_id, args.device_id, args.private_key_file,
216+
args.algorithm, args.ca_certs, args.mqtt_bridge_hostname,
217+
args.mqtt_bridge_port)
218+
185219
# Publish "payload" to the MQTT topic. qos=1 means at least once
186220
# delivery. Cloud IoT Core also supports qos=0 for at most once
187221
# delivery.
@@ -193,6 +227,7 @@ def main():
193227
# End the network loop and finish.
194228
client.loop_stop()
195229
print('Finished.')
230+
# [END iot_mqtt_run]
196231

197232

198233
if __name__ == '__main__':

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.