Skip to content

Commit d0ae85a

Browse files
Sample and command line refactor (#441)
Refactor samples to not rely on cmdUtils to make the actual MQTT connection, adjust command line parsing to return single class/struct with all the data set, and minor fixes.
1 parent 5bdbcc9 commit d0ae85a

26 files changed

+1243
-875
lines changed

.github/workflows/ci_run_custom_authorizer_connect_cfg.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
"name": "--endpoint",
99
"secret": "ci/endpoint"
1010
},
11+
{
12+
"name": "--signing_region",
13+
"data": "us-east-1"
14+
},
1115
{
1216
"name": "--custom_auth_authorizer_name",
1317
"secret": "ci/CustomAuthorizer/name"

.github/workflows/ci_run_mqtt5_custom_authorizer_cfg.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@
1515
{
1616
"name": "--custom_auth_password",
1717
"secret": "ci/CustomAuthorizer/password"
18+
},
19+
{
20+
"name": "--cert",
21+
"secret": "ci/mqtt5/us/mqtt5_thing/cert",
22+
"filename": "tmp_certificate.pem"
23+
},
24+
{
25+
"name": "--key",
26+
"secret": "ci/mqtt5/us/mqtt5_thing/key",
27+
"filename": "tmp_key.pem"
1828
}
1929
]
2030
}

.github/workflows/ci_run_mqtt5_custom_authorizer_websockets_cfg.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
{
2020
"name": "--use_websockets",
2121
"data": "true"
22+
},
23+
{
24+
"name": "--signing_region",
25+
"data": "us-east-1"
2226
}
2327
]
2428
}

.github/workflows/ci_run_mqtt5_pubsub_cfg.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
"name": "--key",
1818
"secret": "ci/mqtt5/us/mqtt5_thing/key",
1919
"filename": "tmp_key.pem"
20+
},
21+
{
22+
"name": "--is_ci",
23+
"data": "true"
2024
}
2125
]
2226
}

.github/workflows/ci_run_mqtt5_shared_subscription_cfg.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
"name": "--key",
1818
"secret": "ci/mqtt5/us/mqtt5_thing/key",
1919
"filename": "tmp_key.pem"
20+
},
21+
{
22+
"name": "--is_ci",
23+
"data": "true"
2024
}
2125
]
2226
}

.github/workflows/ci_run_pubsub_cfg.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
"name": "--key",
1818
"secret": "ci/PubSub/key",
1919
"filename": "tmp_key.pem"
20+
},
21+
{
22+
"name": "--is_ci",
23+
"data": "true"
2024
}
2125
]
2226
}

codebuild/samples/custom-auth-linux.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ AUTH_NAME=$(aws secretsmanager get-secret-value --secret-id "ci/CustomAuthorizer
1212
AUTH_PASSWORD=$(aws secretsmanager get-secret-value --secret-id "ci/CustomAuthorizer/password" --query "SecretString" | cut -f2 -d":" | sed -e 's/[\\\"\}]//g')
1313

1414
echo "Custom Authorizer test"
15-
python3 custom_authorizer_connect.py --endpoint $ENDPOINT --custom_auth_authorizer_name $AUTH_NAME --custom_auth_password $AUTH_PASSWORD
15+
python3 custom_authorizer_connect.py --endpoint $ENDPOINT --custom_auth_authorizer_name $AUTH_NAME --custom_auth_password $AUTH_PASSWORD --signing_region us-east-1
1616

1717
popd

codebuild/samples/pubsub-linux.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ pushd $CODEBUILD_SRC_DIR/samples/
1010
ENDPOINT=$(aws secretsmanager get-secret-value --secret-id "ci/endpoint" --query "SecretString" | cut -f2 -d":" | sed -e 's/[\\\"\}]//g')
1111

1212
echo "PubSub test"
13-
python3 pubsub.py --endpoint $ENDPOINT --key /tmp/privatekey.pem --cert /tmp/certificate.pem
13+
python3 pubsub.py --endpoint $ENDPOINT --key /tmp/privatekey.pem --cert /tmp/certificate.pem --is_ci "true"
1414

1515
popd

codebuild/samples/pubsub-mqtt5-linux.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ pushd $CODEBUILD_SRC_DIR/samples/
1010
ENDPOINT=$(aws secretsmanager get-secret-value --secret-id "ci/endpoint" --query "SecretString" | cut -f2 -d":" | sed -e 's/[\\\"\}]//g')
1111

1212
echo "MQTT5 PubSub test"
13-
python3 mqtt5_pubsub.py --endpoint $ENDPOINT --key /tmp/privatekey.pem --cert /tmp/certificate.pem
13+
python3 mqtt5_pubsub.py --endpoint $ENDPOINT --key /tmp/privatekey.pem --cert /tmp/certificate.pem --is_ci "true"
1414

1515
popd

samples/basic_connect.py

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,13 @@
11
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
# SPDX-License-Identifier: Apache-2.0.
33

4-
from uuid import uuid4
4+
from awscrt import http
5+
from awsiot import mqtt_connection_builder
6+
from utils.command_line_utils import CommandLineUtils
57

68
# This sample shows how to create a MQTT connection using a certificate file and key file.
79
# This sample is intended to be used as a reference for making MQTT connections.
810

9-
# Parse arguments
10-
import utils.command_line_utils as command_line_utils
11-
cmdUtils = command_line_utils.CommandLineUtils("Basic Connect - Make a MQTT connection.")
12-
cmdUtils.add_common_mqtt_commands()
13-
cmdUtils.add_common_proxy_commands()
14-
cmdUtils.add_common_logging_commands()
15-
cmdUtils.register_command("key", "<path>", "Path to your key in PEM format.", True, str)
16-
cmdUtils.register_command("cert", "<path>", "Path to your client certificate in PEM format.", True, str)
17-
cmdUtils.register_command("port", "<int>",
18-
"Connection port for direct connection. " +
19-
"AWS IoT supports 443 and 8883 (optional, default=8883).",
20-
False, int)
21-
cmdUtils.register_command("client_id", "<str>",
22-
"Client ID to use for MQTT connection (optional, default='test-*').",
23-
default="test-" + str(uuid4()))
24-
cmdUtils.register_command("is_ci", "<str>", "If present the sample will run in CI mode (optional, default='None')")
25-
# Needs to be called so the command utils parse the commands
26-
cmdUtils.get_args()
27-
is_ci = cmdUtils.get_command("is_ci", None) != None
28-
2911
# Callback when connection is accidentally lost.
3012
def on_connection_interrupted(connection, error, **kwargs):
3113
print("Connection interrupted. error: {}".format(error))
@@ -36,19 +18,39 @@ def on_connection_resumed(connection, return_code, session_present, **kwargs):
3618

3719

3820
if __name__ == '__main__':
39-
# Create a connection using a certificate and key.
40-
# Note: The data for the connection is gotten from cmdUtils.
41-
# (see build_direct_mqtt_connection for implementation)
42-
mqtt_connection = cmdUtils.build_direct_mqtt_connection(on_connection_interrupted, on_connection_resumed)
43-
44-
if is_ci == False:
45-
print("Connecting to {} with client ID '{}'...".format(
46-
cmdUtils.get_command(cmdUtils.m_cmd_endpoint), cmdUtils.get_command("client_id")))
21+
22+
# cmdData is the arguments/input from the command line placed into a single struct for
23+
# use in this sample. This handles all of the command line parsing, validating, etc.
24+
# See the Utils/CommandLineUtils for more information.
25+
cmdData = CommandLineUtils.parse_sample_input_basic_connect()
26+
27+
# Create the proxy options if the data is present in cmdData
28+
proxy_options = None
29+
if cmdData.input_proxy_host is not None and cmdData.input_proxy_port != 0:
30+
proxy_options = http.HttpProxyOptions(
31+
host_name=cmdData.input_proxy_host,
32+
port=cmdData.input_proxy_port)
33+
34+
# Create a MQTT connection from the command line data
35+
mqtt_connection = mqtt_connection_builder.mtls_from_path(
36+
endpoint=cmdData.input_endpoint,
37+
port=cmdData.input_port,
38+
cert_filepath=cmdData.input_cert,
39+
pri_key_filepath=cmdData.input_key,
40+
ca_filepath=cmdData.input_ca,
41+
on_connection_interrupted=on_connection_interrupted,
42+
on_connection_resumed=on_connection_resumed,
43+
client_id=cmdData.input_clientId,
44+
clean_session=False,
45+
keep_alive_secs=30,
46+
http_proxy_options=proxy_options)
47+
48+
if not cmdData.input_is_ci:
49+
print(f"Connecting to {cmdData.input_endpoint} with client ID '{cmdData.input_clientId}'...")
4750
else:
4851
print("Connecting to endpoint with client ID")
4952

5053
connect_future = mqtt_connection.connect()
51-
5254
# Future.result() waits until a result is available
5355
connect_future.result()
5456
print("Connected!")

samples/basic_discovery.py

Lines changed: 28 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,64 +3,42 @@
33

44
import time
55
import json
6-
from concurrent.futures import Future
76
from awscrt import io, http
87
from awscrt.mqtt import QoS
98
from awsiot.greengrass_discovery import DiscoveryClient
109
from awsiot import mqtt_connection_builder
1110

11+
from utils.command_line_utils import CommandLineUtils
12+
1213
allowed_actions = ['both', 'publish', 'subscribe']
1314

14-
# Parse arguments
15-
import utils.command_line_utils as command_line_utils
16-
cmdUtils = command_line_utils.CommandLineUtils("Basic Discovery - Greengrass discovery example.")
17-
cmdUtils.add_common_mqtt_commands()
18-
cmdUtils.add_common_topic_message_commands()
19-
cmdUtils.add_common_logging_commands()
20-
cmdUtils.register_command("key", "<path>", "Path to your key in PEM format.", True, str)
21-
cmdUtils.register_command("cert", "<path>", "Path to your client certificate in PEM format.", True, str)
22-
cmdUtils.remove_command("endpoint")
23-
cmdUtils.register_command("thing_name", "<str>", "The name assigned to your IoT Thing", required=True)
24-
cmdUtils.register_command(
25-
"mode", "<mode>",
26-
f"The operation mode (optional, default='both').\nModes:{allowed_actions}", default='both')
27-
cmdUtils.register_command("region", "<str>", "The region to connect through.", required=True)
28-
cmdUtils.register_command(
29-
"max_pub_ops", "<int>",
30-
"The maximum number of publish operations (optional, default='10').",
31-
default=10, type=int)
32-
cmdUtils.register_command(
33-
"print_discover_resp_only", "", "(optional, default='False').",
34-
default=False, type=bool, action="store_true")
35-
cmdUtils.add_common_proxy_commands()
36-
# Needs to be called so the command utils parse the commands
37-
cmdUtils.get_args()
38-
39-
tls_options = io.TlsContextOptions.create_client_with_mtls_from_path(
40-
cmdUtils.get_command_required("cert"), cmdUtils.get_command_required("key"))
41-
if cmdUtils.get_command(cmdUtils.m_cmd_ca_file):
42-
tls_options.override_default_trust_store_from_path(None, cmdUtils.get_command(cmdUtils.m_cmd_ca_file))
15+
# cmdData is the arguments/input from the command line placed into a single struct for
16+
# use in this sample. This handles all of the command line parsing, validating, etc.
17+
# See the Utils/CommandLineUtils for more information.
18+
cmdData = CommandLineUtils.parse_sample_input_basic_discovery()
19+
20+
tls_options = io.TlsContextOptions.create_client_with_mtls_from_path(cmdData.input_cert, cmdData.input_key)
21+
if (cmdData.input_ca is not None):
22+
tls_options.override_default_trust_store_from_path(None, cmdData.input_ca)
4323
tls_context = io.ClientTlsContext(tls_options)
4424

4525
socket_options = io.SocketOptions()
4626

4727
proxy_options = None
48-
if cmdUtils.get_command(cmdUtils.m_cmd_proxy_host) != None and cmdUtils.get_command(cmdUtils.m_cmd_proxy_port) != None:
49-
proxy_options = http.HttpProxyOptions(
50-
cmdUtils.get_command_required(cmdUtils.m_cmd_proxy_host),
51-
cmdUtils.get_command_required(cmdUtils.m_cmd_proxy_port))
28+
if cmdData.input_proxy_host is not None and cmdData.input_proxy_port != 0:
29+
proxy_options = http.HttpProxyOptions(cmdData.input_proxy_host, cmdData.input_proxy_port)
5230

5331
print('Performing greengrass discovery...')
5432
discovery_client = DiscoveryClient(
5533
io.ClientBootstrap.get_or_create_static_default(),
5634
socket_options,
5735
tls_context,
58-
cmdUtils.get_command_required("region"), None, proxy_options)
59-
resp_future = discovery_client.discover(cmdUtils.get_command_required("thing_name"))
36+
cmdData.input_signing_region, None, proxy_options)
37+
resp_future = discovery_client.discover(cmdData.input_thing_name)
6038
discover_response = resp_future.result()
6139

6240
print(discover_response)
63-
if cmdUtils.get_command("print_discover_resp_only"):
41+
if (cmdData.input_print_discovery_resp_only):
6442
exit(0)
6543

6644

@@ -78,16 +56,17 @@ def try_iot_endpoints():
7856
for gg_core in gg_group.cores:
7957
for connectivity_info in gg_core.connectivity:
8058
try:
81-
print (f"Trying core {gg_core.thing_arn} at host {connectivity_info.host_address} port {connectivity_info.port}")
59+
print(
60+
f"Trying core {gg_core.thing_arn} at host {connectivity_info.host_address} port {connectivity_info.port}")
8261
mqtt_connection = mqtt_connection_builder.mtls_from_path(
8362
endpoint=connectivity_info.host_address,
8463
port=connectivity_info.port,
85-
cert_filepath=cmdUtils.get_command_required("cert"),
86-
pri_key_filepath=cmdUtils.get_command_required("key"),
64+
cert_filepath=cmdData.input_cert,
65+
pri_key_filepath=cmdData.input_key,
8766
ca_bytes=gg_group.certificate_authorities[0].encode('utf-8'),
8867
on_connection_interrupted=on_connection_interupted,
8968
on_connection_resumed=on_connection_resumed,
90-
client_id=cmdUtils.get_command_required("thing_name"),
69+
client_id=cmdData.input_clientId,
9170
clean_session=False,
9271
keep_alive_secs=30)
9372

@@ -102,27 +81,26 @@ def try_iot_endpoints():
10281

10382
exit('All connection attempts failed')
10483

105-
mqtt_connection = try_iot_endpoints()
10684

107-
if cmdUtils.get_command("mode") == 'both' or cmdUtils.get_command("mode") == 'subscribe':
85+
mqtt_connection = try_iot_endpoints()
10886

87+
if cmdData.input_mode == 'both' or cmdData.input_mode == 'subscribe':
10988
def on_publish(topic, payload, dup, qos, retain, **kwargs):
11089
print('Publish received on topic {}'.format(topic))
11190
print(payload)
112-
113-
subscribe_future, _ = mqtt_connection.subscribe(cmdUtils.get_command("topic"), QoS.AT_MOST_ONCE, on_publish)
91+
subscribe_future, _ = mqtt_connection.subscribe(cmdData.input_topic, QoS.AT_MOST_ONCE, on_publish)
11492
subscribe_result = subscribe_future.result()
11593

11694
loop_count = 0
117-
while loop_count < cmdUtils.get_command("max_pub_ops"):
118-
if cmdUtils.get_command("mode") == 'both' or cmdUtils.get_command("mode") == 'publish':
95+
while loop_count < cmdData.input_max_pub_ops:
96+
if cmdData.input_mode == 'both' or cmdData.input_mode == 'publish':
11997
message = {}
120-
message['message'] = cmdUtils.get_command("message")
98+
message['message'] = cmdData.input_message
12199
message['sequence'] = loop_count
122100
messageJson = json.dumps(message)
123-
pub_future, _ = mqtt_connection.publish(cmdUtils.get_command("topic"), messageJson, QoS.AT_MOST_ONCE)
101+
pub_future, _ = mqtt_connection.publish(cmdData.input_topic, messageJson, QoS.AT_MOST_ONCE)
124102
pub_future.result()
125-
print('Published topic {}: {}\n'.format(cmdUtils.get_command("topic"), messageJson))
103+
print('Published topic {}: {}\n'.format(cmdData.input_topic, messageJson))
126104

127105
loop_count += 1
128106
time.sleep(1)

0 commit comments

Comments
 (0)