8000 Tests for device over HTTP and adds example for getting configuration… · johnmanong/python-docs-samples@eb49861 · GitHub
[go: up one dir, main page]

Skip to content

Commit eb49861

Browse files
gguussJon Wayne Parrott
authored and
Jon Wayne Parrott
committed
Tests for device over HTTP and adds example for getting configuration. (GoogleCloudPlatform#1255)
* Tests for device over HTTP and adds example for getting configuration. * Fixes circle * Fixes circle * Print is a function * Python3 encodings * Add note for manager import
1 parent 0277fa6 commit eb49861

File tree

6 files changed

+249
-3
lines changed

6 files changed

+249
-3
lines changed

iot/api-client/http_example/cloudiot_http_example.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def create_jwt(project_id, private_key_file, algorithm):
5151
print('Creating JWT using {} from private key file {}'.format(
5252
algorithm, private_key_file))
5353

54-
return jwt.encode(token, private_key, algorithm=algorithm)
54+
return jwt.encode(token, private_key, algorithm=algorithm).decode('ascii')
5555

5656

5757
def publish_message(
@@ -72,11 +72,12 @@ def publish_message(
7272
url_suffix)
7373

7474
body = None
75+
msg_bytes = base64.urlsafe_b64encode(message.encode('utf-8'))
7576
if message_type == 'event':
76-
body = {'binary_data': base64.urlsafe_b64encode(message)}
77+
body = {'binary_data': msg_bytes.decode('ascii')}
7778
else:
7879
body = {
79-
'state': {'binary_data': base64.urlsafe_b64encode(message)}
80 8000 +
'state': {'binary_data': msg_bytes.decode('ascii')}
8081
}
8182

8283
resp = requests.post(
@@ -85,6 +86,25 @@ def publish_message(
8586
return resp
8687

8788

89+
def get_config(
90+
version, message_type, base_url, project_id, cloud_region, registry_id,
91+
device_id, jwt_token):
92+
headers = {
93+
'authorization': 'Bearer {}'.format(jwt_token),
94+
'content-type': 'application/json',
95+
'cache-control': 'no-cache'
96+
}
97+
98+
basepath = '{}/projects/{}/locations/{}/registries/{}/devices/{}/'
99+
template = basepath + 'config?local_version={}'
100+
config_url = template.format(
101+
base_url, project_id, cloud_region, registry_id, device_id, version)
102+
103+
resp = requests.get(config_url, headers=headers)
104+
105+
return resp
106+
107+
88108
def parse_command_line_args():
89109
"""Parse command line arguments."""
90110
parser = argparse.ArgumentParser(description=(
@@ -143,6 +163,10 @@ def main():
143163
jwt_iat = datetime.datetime.utcnow()
144164
jwt_exp_mins = args.jwt_expires_minutes
145165

166+
print('Latest configuration: {}'.format(get_config(
167+
'0', args.message_type, args.base_url, args.project_id,
168+
args.cloud_region, args.registry_id, args.device_id, jwt_token).text))
169+
146170
# Publish num_messages mesages to the HTTP bridge once per second.
147171
for i in range(1, args.num_messages + 1):
148172
seconds_since_issue = (datetime.datetime.utcnow() - jwt_iat).seconds
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
# Copyright 2017 Google Inc. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
import os
15+
import sys
16+
import time
17+
18+
from google.cloud import pubsub
19+
20+
# Add manager for bootstrapping device registry / device for testing
21+
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'manager')) # noqa
22+
import manager
23+
24+
import pytest
25+
26+
import cloudiot_http_example
27+
28+
29+
cloud_region = 'us-central1'
30+
device_id_template = 'test-device-{}'
31+
es_cert_path = 'resources/ec_public.pem'
32+
rsa_cert_path = 'resources/rsa_cert.pem'
33+
rsa_private_path = 'resources/rsa_private.pem'
34+
topic_id = 'test-device-events-{}'.format(int(time.time()))
35+
36+
project_id = os.environ['GCLOUD_PROJECT']
37+
service_account_json = os.environ['GOOGLE_APPLICATION_CREDENTIALS']
38+
39+
pubsub_topic = 'projects/{}/topics/{}'.format(project_id, topic_id)
40+
registry_id = 'test-registry-{}'.format(int(time.time()))
41+
42+
_BASE_URL = 'https://cloudiot-device.googleapis.com/v1beta1'
43+
44+
45+
@pytest.fixture(scope='module')
46+
def test_topic() F438 :
47+
topic = manager.create_iot_topic(project_id, topic_id)
48+
49+
yield topic
50+
51+
pubsub_client = pubsub.PublisherClient()
52+
topic_path = pubsub_client.topic_path(project_id, topic_id)
53+
pubsub_client.delete_topic(topic_path)
54+
55+
56+
def test_event(test_topic, capsys):
57+
device_id = device_id_template.format('RSA256')
58+
manager.open_registry(
59+
service_account_json, project_id, cloud_region, pubsub_topic,
60+
registry_id)
61+
62+
manager.create_rs256_device(
63+
service_account_json, project_id, cloud_region, registry_id,
64+
device_id, rsa_cert_path)
65+
66+
manager.get_device(
67+
service_account_json, project_id, cloud_region, registry_id,
68+
device_id)
69+
70+
jwt_token = cloudiot_http_example.create_jwt(
71+
project_id, 'resources/rsa_private.pem', 'RS256')
72+
73+
print(cloudiot_http_example.publish_message(
74+
'hello', 'event', _BASE_URL, project_id, cloud_region,
75+
registry_id, device_id, jwt_token))
76+
77+
manager.get_state(
78+
service_account_json, project_id, cloud_region, registry_id,
79+
device_id)
80+
81+
manager.delete_device(
82+
service_account_json, project_id, cloud_region, registry_id,
83+
device_id)
84+
85+
manager.delete_registry(
86+
service_account_json, project_id, cloud_region, registry_id)
87+
88+
out, _ = capsys.readouterr()
89+
assert 'format : RSA_X509_PEM' in out
90+
assert 'State: {' in out
91+
assert '200' in out
92+
93+
94+
def test_state(test_topic, capsys):
95+
device_id = device_id_template.format('RSA256')
96+
manager.open_registry(
97+
service_account_json, project_id, cloud_region, pubsub_topic,
98+
registry_id)
99+
100+
manager.create_rs256_device(
101+
service_account_json, project_id, cloud_region, registry_id,
102+
device_id, rsa_cert_path)
103+
104+
manager.get_device(
105+
service_account_json, project_id, cloud_region, registry_id,
106+
device_id)
107+
108+
jwt_token = cloudiot_http_example.create_jwt(
109+
project_id, 'resources/rsa_private.pem', 'RS256')
110+
111+
print(cloudiot_http_example.publish_message(
112+
'hello', 'state', _BASE_URL, project_id, cloud_region,
113+
registry_id, device_id, jwt_token))
114+
115+
manager.get_state(
116+
service_account_json, project_id, cloud_region, registry_id,
117+
device_id)
118+
119+
manager.delete_device(
120+
service_account_json, project_id, cloud_region, registry_id,
121+
device_id)
122+
123+
manager.delete_registry(
124+
service_account_json, project_id, cloud_region, registry_id)
125+
126+
out, _ = capsys.readouterr()
127+
assert 'format : RSA_X509_PEM' in out
128+
assert 'State: {' in out
129+
assert 'aGVsbG8=' in out
130+
assert '200' in out
131+
132+
133+
def test_config(test_topic, capsys):
134+
device_id = device_id_template.format('RSA256')
135+
manager.open_registry(
136+
service_account_json, project_id, cloud_region, pubsub_topic,
137+
registry_id)
138+
139+
manager.create_rs256_device(
140+
service_account_json, project_id, cloud_region, registry_id,
141+
device_id, rsa_cert_path)
142+
143+
manager.get_device(
144+
service_account_json, project_id, cloud_region, registry_id,
145+
device_id)
146+
147+
jwt_token = cloudiot_http_example.create_jwt(
148+
project_id, 'resources/rsa_private.pem', 'RS256')
149+
150+
print(cloudiot_http_example.get_config(
151+
'0', 'state', _BASE_URL, project_id, cloud_region,
152+
registry_id, device_id, jwt_token).text)
153+
154+
manager.get_state(
155+
service_account_json, project_id, cloud_region, registry_id,
156+
device_id)
157+
158+
manager.delete_device(
159+
service_account_json, project_id, cloud_region, registry_id,
160+
device_id)
161+
162+
manager.delete_registry(
163+
service_account_json, project_id, cloud_region, registry_id)
164+
165+
out, _ = capsys.readouterr()
166+
assert 'format : RSA_X509_PEM' in out
167+
assert 'State: {' in out
168+
assert '"version": "1"' in out
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
cryptography==2.1.4
2+
google-api-python-client==1.6.4
3+
google-auth-httplib2==0.0.3
4+
google-auth==1.2.1
5+
google-cloud-pubsub==0.29.2
26
pyjwt==1.5.3
37
requests==2.18.4
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Test public certificate files
2+
3+
The public certificates in this folder are only provided for testing and should
4+
not be used for registering your devices.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIC9TCCAd2gAwIBAgIJALM44e3ivEWkMA0GCSqGSIb3DQEBCwUAMBExDzANBgNV
3+
BAMMBnVudXNlZDAeFw0xNzEyMDcwMDQ1MjdaFw0yNzEyMDUwMDQ1MjdaMBExDzAN
4+
BgNVBAMMBnVudXNlZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL4w
5+
BxHuEyYdbiwKiD8yXY7vYpcygeOQ4/ZdEg3wCB2OuYcaFRcCuqLcTLMnuzdcL+y3
6+
HBjWkrRW658cg3NG93Vj0iwSrga6u24CGBNYV+h8MBvwaDxk+uubnd5M/Q2OyL1J
7+
GiMxQ1blR/71Hr5hhqaQZ2+qOF6kuf1m9rLUtMUJwOKp/PjPDmy654ZGsFWFSZmy
8+
eRpNzmGU+KJg0o+Qf+sm75a8gQZ8AsrqveW0S/8o+zAjD0SkPcd01QBmYzQhjbi/
9+
LGGITrzbaB3ld9umJBIcXfnYPYisJfwSsT/jFwiXhrhpxNNaIaKlTzlQIt5l8bSs
10+
HXzJBbuIg5Jb/SyIEpkCAwEAAaNQME4wHQYDVR0OBBYEFOfaQTUVAoNb6fc7qzzl
11+
uKyHGrCYMB8GA1UdIwQYMBaAFOfaQTUVAoNb6fc7qzzluKyHGrCYMAwGA1UdEwQF
12+
MAMBAf8wDQYJKoZIhvcNAQELBQADggEBALKKDtiV1YV8k0YsNdiIXRlS3jsuoGuI
13+
VVBrvDGz5Hel0rH9YmmfPS/Yn08kk3DF8Uynr4Xo1Zt9hmhgoq3ZoWm7MIP1+a9s
14+
WyACyEMhVQSCzQrexRvG5ElpHx/vNjbcwiBkE5urlIvMBVt+BRRNKMNWq6F9ae63
15+
FxRp7CtNFSbibtLJuPgCs6qoNs0nlt2FPsNvs7jpPipj69o+egVckvQjAyppirWO
16+
+jO5hCLy7EahLz2wCn90z0Xf9lhOZni9meaV1Vy3CHHg6jwIB8/XlRaHFrOGMGXg
17+
h8eQqsmpk9/3o8pv00yj6Hkq+swVg7Rg9FZaUiOv/HO/J7stWU7qPbI=
18+
-----END CERTIFICATE-----
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC+MAcR7hMmHW4s
3+
Cog/Ml2O72KXMoHjkOP2XRIN8AgdjrmHGhUXArqi3EyzJ7s3XC/stxwY1pK0Vuuf
4+
HINzRvd1Y9IsEq4GurtuAhgTWFfofDAb8Gg8ZPrrm53eTP0Njsi9SRojMUNW5Uf+
5+
9R6+YYamkGdvqjhepLn9Zvay1LTFCcDiqfz4zw5suueGRrBVhUmZsnkaTc5hlPii
6+
YNKPkH/rJu+WvIEGfALK6r3ltEv/KPswIw9EpD3HdNUAZmM0IY24vyxhiE6822gd
7+
5XfbpiQSHF352D2IrCX8ErE/4xcIl4a4acTTWiGipU85UCLeZfG0rB18yQW7iIOS
8+
W/0siBKZAgMBAAECggEAfwLmBdRfl2m6JNFX0hSZpJY72kuRsN8XTnUzVHmDgfHJ
9+
9u61POvGpnLHCjIzdjIrk0NqETBjQup1aooJQ1gWdKAYQPSsobPc7geZ+nlaI9mj
10+
61Su1/58EBKZ6Faz/HTpnHeQbAY/OW3fmeYrBOtumBgB6/HauWH7D77Oa/lfS+Ij
11+
4f6OVAxevsi6PUtNmNtBwk5S0lZl9SFcKeHurVindquX9vWZjBEEFtNXazJttIJS
12+
z9KX29VYwoLfflIKaUKckn8X+wYc+3u3BvH8zJpd60yQ6MSo7Sb1XkxT9549m+JW
13+
Cb+i1K7MC/yQo4mvDtAQIVBh8p8qpd4VjpBwMuUbgQKBgQDexuAaLO3adSYFXGwW
14+
nom6Mz/ImYcpxYo0ouAR1talbmF5/oKl9Tcwh7l1eDHfe70gfeP+g4uwAcc1hx3a
15+
ZtXusrJFBktFezlFQnZXaE5ppryrFWeu0he0RYLAVxnL6IlP9dYQhVsTZm+7uX5d
16+
UP7aZtmOU9ZTEsAoqvjJQXvaCQKBgQDajPebXOxIUj8ffGTeiPZczTwXux04caDC
17+
eFKSCbAlHWgG7mR4P3fQONfEGWNHF0CxBSrew9CHmKdPyiISaExCfUaUWDDCPQCp
18+
UE5VAHPdjSlb4lqi+cyNVlJxBJGONtyYkbQNd6N9GHMnBS8jZi7zf8VzIXpeExA4
19+
n79Aml/YEQKBgDFrGId19AWD+z0xNWEHJjJB8CJFvHANvAzVHLOYXuEvzTvMs5qw
20+
/N8tHHzsftO+lUPB6XOqJrCSlGhRYtPx//8FcPpS3Ru6rAerKKlXIB3buPqSsv9a
21+
55s72DdmmvhayysLs8LSclOpY5vXGCsHLqGwMw6Zlm+zNyFOXAX5GspRAoGAaJMx
22+
W68ABK8OM0OzhGQm9kriKTzIg5yjXspyQBzQo0HJ6B8kBgHgk8rPO68mOPsgYlPl
23+
qogp/OgHjv9ahFJRwzLslckJM7g628loYfYAew+zrZrG4dsDjNG0Sw3zlAgeUAbQ
24+
D+2iVhZf61josFiRuMP3t9paEi+vAFk4C3KSz/ECgYBpi1akpIzsYehW5uOL7Jhw
25+
Hay5eshQ4vmHYuhDnn3gtT3h6J7TMwWs9pOygBG1I1b7GJ+tp4BZWJ2PmI7P8s45
26+
jdI99WODHwv03lAzjLwigoqDUDduaYqXcGghcGht5Sknkl2uYDChwLtI5JdBZ9/x
27+
8h9dE9oAiH/KTzhPmK1E1Q==
28+
-----END PRIVATE KEY-----

0 commit comments

Comments
 (0)
0