aws_iot_device 0.1.5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/README.md +155 -148
  4. data/aws_iot_device.gemspec +11 -11
  5. data/codeclimate.yml +6 -0
  6. data/lib/aws_iot_device.rb +2 -1
  7. data/lib/aws_iot_device/mqtt_adapter.rb +1 -2
  8. data/lib/aws_iot_device/mqtt_adapter/client.rb +74 -6
  9. data/lib/aws_iot_device/mqtt_adapter/paho_mqtt_adapter.rb +207 -0
  10. data/lib/aws_iot_device/mqtt_adapter/ruby_mqtt_adapter.rb +10 -4
  11. data/lib/aws_iot_device/mqtt_shadow_client.rb +1 -0
  12. data/lib/aws_iot_device/mqtt_shadow_client/mqtt_manager.rb +133 -67
  13. data/lib/aws_iot_device/mqtt_shadow_client/shadow_action_manager.rb +229 -146
  14. data/lib/aws_iot_device/mqtt_shadow_client/shadow_client.rb +78 -20
  15. data/lib/aws_iot_device/mqtt_shadow_client/shadow_topic_manager.rb +51 -26
  16. data/lib/aws_iot_device/mqtt_shadow_client/topic_builder.rb +15 -30
  17. data/lib/aws_iot_device/version.rb +1 -1
  18. data/samples/config_shadow.rb +72 -0
  19. data/samples/mqtt_client_samples/mqtt_client_samples.rb +7 -59
  20. data/samples/shadow_action_samples/sample_shadow_action_update.rb +7 -61
  21. data/samples/shadow_client_samples/samples_shadow_client_block.rb +25 -0
  22. data/samples/shadow_client_samples/samples_shadow_client_delete.rb +9 -58
  23. data/samples/shadow_client_samples/samples_shadow_client_description.rb +64 -0
  24. data/samples/shadow_client_samples/samples_shadow_client_get.rb +11 -62
  25. data/samples/shadow_client_samples/samples_shadow_client_getting_started.rb +22 -0
  26. data/samples/shadow_client_samples/samples_shadow_client_update.rb +7 -58
  27. data/samples/shadow_topic_samples/sample_topic_manager.rb +10 -61
  28. metadata +71 -16
  29. data/lib/aws_iot_device/mqtt_adapter/mqtt_adapter.rb +0 -139
@@ -4,47 +4,72 @@ module AwsIotDevice
4
4
  module MqttShadowClient
5
5
  class ShadowTopicManager
6
6
 
7
- def initialize(mqtt_manager)
8
- if mqtt_manager.nil?
9
- raise "TopicAction_error: TopicAction should be initialized with a mqtt_manager but was undefined"
10
- end
7
+ def initialize(mqtt_manager, shadow_name)
8
+ raise ArgumentError, "topic manager should be initialized with a mqtt_manager but was undefined" if mqtt_manager.nil?
9
+ raise ArgumentError, "topic manager should be initialize with a mqtt mmanager but was undefined" if shadow_name.nil?
10
+
11
11
  @mqtt_manager = mqtt_manager
12
12
  @sub_unsub_mutex = Mutex.new()
13
+ @topic = TopicBuilder.new(shadow_name)
14
+ @timeout = mqtt_manager.mqtt_operation_timeout_s
13
15
  end
14
16
 
15
- def client_id
16
- @mqtt_manager.client_id
17
+ def shadow_topic_publish(action, payload)
18
+ @mqtt_manager.publish(@topic.get_topic_general(action), payload, false, 0)
17
19
  end
18
20
 
19
- def shadow_topic_publish(shadow_name, shadow_action, payload)
20
- topic = TopicBuilder.new(shadow_name, shadow_action)
21
- @mqtt_manager.publish(topic.get_topic_general, payload, false, 0)
22
- end
23
-
24
- def shadow_topic_subscribe(shadow_name, shadow_action, callback=nil)
25
- @sub_unsub_mutex.synchronize(){
26
- topic = TopicBuilder.new(shadow_name, shadow_action)
27
- if topic.is_delta?(shadow_action)
28
- @mqtt_manager.subscribe(topic.get_topic_delta, 0, callback)
21
+ def shadow_topic_subscribe(action, callback=nil)
22
+ @sub_unsub_mutex.synchronize() {
23
+ @subacked = false
24
+ if @topic.is_delta?(action)
25
+ @mqtt_manager.subscribe(@topic.get_topic_delta, 0, callback)
29
26
  else
30
- @mqtt_manager.subscribe(topic.get_topic_accepted, 0, callback)
31
- @mqtt_manager.subscribe(topic.get_topic_rejected, 0, callback)
27
+ @mqtt_manager.subscribe_bunch([@topic.get_topic_accepted(action), 1, callback], [@topic.get_topic_rejected(action), 1, callback])
32
28
  end
33
29
  }
34
- sleep 2
35
30
  end
36
-
37
- def shadow_topic_unsubscribe(shadow_name, shadow_action)
31
+
32
+ def shadow_topic_unsubscribe(action)
38
33
  @sub_unsub_mutex.synchronize(){
39
- topic = TopicBuilder.new(shadow_name, shadow_action)
40
- if topic.is_delta?(shadow_name)
41
- @mqtt_manager.unsubscribe(topic.get_topic_delta)
34
+ @unsubacked = false
35
+ if @topic.is_delta?(action)
36
+ @mqtt_manager.unsubscribe(@topic.get_topic_delta)
42
37
  else
43
- @mqtt_manager.unsubscribe(topic.get_topic_accepted)
44
- @mqtt_manager.unsubscribe(topic.get_topic_rejected)
38
+ @mqtt_manager.unsubscribe_bunch(@topic.get_topic_accepted(action), @topic.get_topic_rejected(action))
45
39
  end
46
40
  }
47
41
  end
42
+
43
+ def retrieve_action(topic)
44
+ res = nil
45
+ ACTION_NAME.each do |action|
46
+ if topic[0] == @topic.get_topic_accepted(action)
47
+ res = action.to_sym
48
+ break
49
+ end
50
+ end
51
+ res
52
+ end
53
+
54
+ def paho_client?
55
+ @mqtt_manager.paho_client?
56
+ end
57
+
58
+ def on_suback=(callback)
59
+ @mqtt_manager.on_suback = callback
60
+ end
61
+
62
+ def on_suback(&block)
63
+ @mqtt_manager.on_suback(&block)
64
+ end
65
+
66
+ def on_unsuback=(callback)
67
+ @mqtt_manager.on_unsuback = callback
68
+ end
69
+
70
+ def on_unsuback(&block)
71
+ @mqtt_manager.on_unsuback(&block)
72
+ end
48
73
  end
49
74
  end
50
75
  end
@@ -1,45 +1,30 @@
1
1
  module AwsIotDevice
2
2
  module MqttShadowClient
3
3
  class TopicBuilder
4
- ACTION_NAME = %w(get update delete delta).freeze
5
-
6
- def initialize(shadow_name, action_name)
7
- unless ACTION_NAME.include?(action_name)
8
- raise "action_name_error: unreconized action_name \"#{action_name}\""
9
- end
10
-
11
- if shadow_name.nil?
12
- raise "shadow_name_error: shadow_name is required but undefined"
13
-
14
- end
15
-
4
+ def initialize(shadow_name)
5
+ raise ArgumentError, "topic_builder initialization, shadow_name is required but undefined" if shadow_name.nil?
6
+
16
7
  @shadow_name = shadow_name
17
- @action_name = action_name
18
-
19
- ### The case of delta's action
20
- if is_delta?(action_name)
21
- @topic_delta = "$aws/things/#{shadow_name}/shadow/update/delta"
22
- else
23
- @topic_general = "$aws/things/#{shadow_name}/shadow/#{action_name}"
24
- @topic_accepted = "$aws/things/#{shadow_name}/shadow/#{action_name}/accepted"
25
- @topic_rejected = "$aws/things/#{shadow_name}/shadow/#{action_name}/rejected"
26
- end
8
+
9
+ @topic_delta = "$aws/things/#{shadow_name}/shadow/update/delta"
10
+ @topic_general = "$aws/things/#{shadow_name}/shadow/"
27
11
  end
28
12
 
29
- def is_delta?(action_name)
30
- action_name == ACTION_NAME[3]
13
+ def is_delta?(action)
14
+ action == ACTION_NAME[3]
31
15
  end
32
16
 
33
- def get_topic_general
34
- @topic_general
17
+ def get_topic_general(action)
18
+ raise ArgumentError, "topic_builder, get topic, unreconized action_name \"#{action}\"" unless ACTION_NAME.include?(action)
19
+ @topic_general + action
35
20
  end
36
21
 
37
- def get_topic_accepted
38
- @topic_accepted
22
+ def get_topic_accepted(action)
23
+ get_topic_general(action) + "/accepted"
39
24
  end
40
25
 
41
- def get_topic_rejected
42
- @topic_rejected
26
+ def get_topic_rejected(action)
27
+ get_topic_general(action) + "/rejected"
43
28
  end
44
29
 
45
30
  def get_topic_delta
@@ -1,3 +1,3 @@
1
1
  module AwsIotDevice
2
- VERSION = "0.1.5"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -0,0 +1,72 @@
1
+ require 'optparse'
2
+
3
+ options = {}
4
+
5
+ OptionParser.new do |opts|
6
+ opts.banner = "Basic usage basic_greeting.rb -c \"YOUR_CERTIFICATE_PATH\" -k \"YOUR_KEY_FILE_PATH\" -ca \"YOUR_ROOT_CA_PATH -H \"YOUR_ENDPOINT\" -p 8883 -t \"YOUR THING NAME\"\n"
7
+
8
+ opts.separator ""
9
+ opts.separator "Common options"
10
+ opts.on_tail("-h", "--help", "--usage", "Show this message") do
11
+ puts opts
12
+ exit
13
+ end
14
+
15
+ opts.on("-H", "--host [END_POINT]", "The endpoint where you want to connect") do |host|
16
+ options[:host] = host
17
+ end
18
+
19
+ opts.on("-p", "--port [MQTT_PORT]", "The port used for the connection Default is 8883") do |port|
20
+ options[:port] = port
21
+ end
22
+
23
+ opts.on("-c", "--cert [CERT_FILE_PATH]", "The path to the certificate file of the private key.") do |cert|
24
+ options[:cert] = cert
25
+ end
26
+
27
+ opts.on("-k", "--key [KEY_FILE_PATH]", "The path to private key file that would be used for encryption") do |key|
28
+ options[:key] = key
29
+ end
30
+
31
+ opts.on("-a", "--root_ca [ROOT_CA_PATH]", "The path to the authority certification file") do |root_ca|
32
+ options[:root_ca] = root_ca
33
+ end
34
+
35
+ opts.on("-t", "--thing [THING_NAME]", "The Thing name on which the action would be done") do |thing|
36
+ options[:things] = thing
37
+ end
38
+ end.parse!(ARGV)
39
+
40
+ @host = options[:host]
41
+ @port = options[:port] || 8883
42
+ @certificate_path = options[:cert]
43
+ @private_key_path = options[:key]
44
+ @root_ca_path = options[:root_ca]
45
+ @thing = options[:things]
46
+
47
+ def setting_mqtt_client
48
+ mqtt_client = AwsIotDevice::MqttShadowClient::MqttManager.new(host: @host,
49
+ port: @port,
50
+ ssl: true)
51
+ mqtt_client.config_ssl_context(@root_ca_path, @private_key_path, @certificate_path)
52
+ mqtt_client.connect
53
+ mqtt_client
54
+ end
55
+
56
+ def setting_topic_manager(mqtt_client)
57
+ topic_manager = AwsIotDevice::MqttShadowClient::ShadowTopicManager.new(mqtt_client, @thing)
58
+ end
59
+
60
+ def setting_action_manager(mqtt_client)
61
+ action_manager = AwsIotDevice::MqttShadowClient::ShadowActionManager.new(@thing, mqtt_client, false)
62
+ action_manager
63
+ end
64
+
65
+ def setting_shadow
66
+ shadow_client = AwsIotDevice::MqttShadowClient::ShadowClient.new
67
+ shadow_client.configure_endpoint(@host, @port)
68
+ shadow_client.configure_credentials(@root_ca_path, @private_key_path, @certificate_path)
69
+ shadow_client.create_shadow_handler_with_name(@thing, true)
70
+ shadow_client.connect
71
+ shadow_client
72
+ end
@@ -1,61 +1,11 @@
1
- require 'aws_iot_device'
2
- require 'optparse'
3
-
4
- options = {}
5
-
6
- OptionParser.new do |opts|
7
- opts.banner = "Basic usage basic_greeting.rb -c \"YOUR_CERTIFICATE_PATH\" -k \"YOUR_KEY_FILE_PATH\" -ca \"YOUR_ROOT_CA_PATH -H \"YOUR_ENDPOINT\" -p 8883\n"
8
-
9
- opts.separator ""
10
- opts.separator "Common options"
11
- opts.on_tail("-h", "--help", "--usage", "Show this message") do
12
- puts opts
13
- exit
14
- end
15
-
16
- opts.on("-H", "--host [END_POINT]", "The endpoint where you want to connect") do |host|
17
- options[:host] = host
18
- end
19
-
20
- opts.on("-p", "--port [MQTT_PORT]", "The port used for the connection Default is 8883") do |port|
21
- options[:port] = port
22
- end
23
-
24
- opts.on("-c", "--cert [CERT_FILE_PATH]", "The path to the certificate file of the private key.") do |cert|
25
- options[:cert] = cert
26
- end
27
-
28
- opts.on("-k", "--key [KEY_FILE_PATH]", "The path to private key file that would be used for encryption") do |key|
29
- options[:key] = key
30
- end
31
-
32
- opts.on("-a", "--root_ca [ROOT_CA_PATH]", "The path to the authority certification file") do |root_ca|
33
- options[:root_ca] = root_ca
34
- end
35
- end.parse!(ARGV)
36
-
37
-
38
- host = options[:host]
39
- port = options[:port] || 8883
40
- cert_file_path = options[:cert]
41
- key_file_path = options[:key]
42
- ca_file_path = options[:root_ca]
43
-
44
- client = AwsIotDevice::MqttShadowClient::MqttManager.new(host: host,
45
- port: port,
46
- ssl: true,
47
- cert_file: cert_file_path,
48
- key_file: key_file_path,
49
- ca_file: ca_file_path)
1
+ $:.unshift(File.expand_path("../../../samples", __FILE__))
50
2
 
51
- client2 = AwsIotDevice::MqttShadowClient::MqttManager.new
3
+ require 'aws_iot_device'
4
+ require 'config_shadow'
52
5
 
53
- client2.config_endpoint(host, port)
54
- client2.ssl = true
55
- client2.config_ssl_context(ca_file_path, key_file_path, cert_file_path)
6
+ client = setting_mqtt_client
56
7
 
57
- client.connect()
58
- client2.connect()
8
+ client2 = setting_mqtt_client
59
9
 
60
10
  callback = Proc.new do |message|
61
11
  p " Client1 catch message event"
@@ -72,12 +22,10 @@ end
72
22
  client.subscribe("topic_2", 0, callback)
73
23
  client2.subscribe("topic_1", 0,callback2)
74
24
 
75
-
76
25
  puts "# STARTING EXAMPLE #"
77
- sleep 2
78
26
  client.publish("topic_1", "Hello Sir. My name is client 1. How do you do? ")
79
- sleep 2
80
27
  client2.publish("topic_2", "Hello Mister Client 1. My name is client 2. How do you do?")
28
+ sleep 1
81
29
 
82
30
  2.times do
83
31
  client.publish("topic_1", "How do you do?")
@@ -85,6 +33,6 @@ client2.publish("topic_2", "Hello Mister Client 1. My name is client 2. How do y
85
33
  client2.publish("topic_2", "How do you do?")
86
34
  sleep 1
87
35
  end
88
-
36
+ sleep 2
89
37
  client.disconnect
90
38
  client2.disconnect
@@ -1,76 +1,22 @@
1
- require 'aws_iot_device'
2
- require 'optparse'
3
-
4
- options = {}
5
-
6
- OptionParser.new do |opts|
7
- opts.banner = "Basic usage basic_greeting.rb -c \"YOUR_CERTIFICATE_PATH\" -k \"YOUR_KEY_FILE_PATH\" -ca \"YOUR_ROOT_CA_PATH -H \"YOUR_ENDPOINT\" -p 8883\n"
8
- opts.separator ""
9
- opts.separator "Common options"
10
- opts.on_tail("-h", "--help", "--usage", "Show this message") do
11
- puts opts
12
- exit
13
- end
14
-
15
- opts.on("-H", "--host [END_POINT]", "The endpoint where you want to connect") do |host|
16
- options[:host] = host
17
- end
18
-
19
- opts.on("-p", "--port [MQTT_PORT]", "The port used for the connection Default is 8883") do |port|
20
- options[:port] = port
21
- end
22
-
23
- opts.on("-c", "--cert [CERT_FILE_PATH]", "The path to the certificate file of the private key.") do |cert|
24
- options[:cert] = cert
25
- end
26
-
27
- opts.on("-k", "--key [KEY_FILE_PATH]", "The path to private key file that would be used for encryption") do |key|
28
- options[:key] = key
29
- end
30
-
31
- opts.on("-a", "--root_ca [ROOT_CA_PATH]", "The path to the authority certification file") do |root_ca|
32
- options[:root_ca] = root_ca
33
- end
34
-
35
- opts.on("-t", "--thing [THING_NAME]", "The Thing name on which the action would be done") do |thing|
36
- options[:things] = thing
37
- end
38
- end.parse!(ARGV)
1
+ $:.unshift(File.expand_path("../../../samples", __FILE__))
39
2
 
40
-
41
- host = options[:host]
42
- port = options[:port] || 8883
43
- cert_file_path = options[:cert]
44
- key_file_path = options[:key]
45
- ca_file_path = options[:root_ca]
46
- thing = options[:things]
47
-
48
- mqtt_client = AwsIotDevice::MqttShadowClient::MqttManager.new(host: host,
49
- port: port,
50
- ssl: true,
51
- cert_file: cert_file_path,
52
- key_file: key_file_path,
53
- ca_file: ca_file_path)
54
-
55
- mqtt_client.connect
3
+ require 'aws_iot_device'
4
+ require 'config_shadow'
56
5
 
57
6
  filter_callback = Proc.new do |message|
58
7
  puts "Executing the specific callback for topic: #{message.topic}\n##########################################\n"
59
8
  end
60
9
 
61
- timeout = 5
62
-
63
- topic_manager = AwsIotDevice::MqttShadowClient::ShadowTopicManager.new(mqtt_client)
64
-
65
- client = AwsIotDevice::MqttShadowClient::ShadowActionManager.new(thing, topic_manager, false)
10
+ mqtt_client = setting_mqtt_client
11
+ client = setting_action_manager(mqtt_client)
66
12
 
67
13
  client.register_shadow_delta_callback(filter_callback)
14
+ timeout = 5
68
15
 
69
16
  n = 1
70
-
71
17
  5.times do
72
18
  json_payload = "{\"state\":{\"desired\":{\"property\":\"RubySDK\",\"count\":#{n}}}}"
73
- client.shadow_update(json_payload, filter_callback, timeout)
19
+ client.shadow_update(json_payload, timeout, filter_callback)
74
20
  n += 1
75
21
  end
76
22
 
@@ -0,0 +1,25 @@
1
+ $:.unshift(File.expand_path("../../../samples", __FILE__))
2
+
3
+ require 'aws_iot_device'
4
+ require 'config_shadow'
5
+
6
+ filter_callback = Proc.new do |message|
7
+ puts "Executing the specific callback for topic: #{message.topic}\n##########################################\n"
8
+ end
9
+
10
+ my_shadow_client = setting_shadow
11
+
12
+ my_shadow_client.connect do |client|
13
+
14
+ puts "##### Starting test_shadow_client_get ######"
15
+ client.get_shadow(4, filter_callback)
16
+
17
+ puts "##### Starting test_shadow_client_get ######"
18
+ client.get_shadow(4) do
19
+ puts "CALLED FROM BLOCK"
20
+ end
21
+
22
+ puts "##### Starting test_shadow_client_get ######"
23
+ client.get_shadow(4, filter_callback)
24
+ sleep 5
25
+ end
@@ -1,73 +1,24 @@
1
- require 'aws_iot_device'
2
- require 'optparse'
3
-
4
- options = {}
5
-
6
- OptionParser.new do |opts|
7
- opts.banner = "Basic usage basic_greeting.rb -c \"YOUR_CERTIFICATE_PATH\" -k \"YOUR_KEY_FILE_PATH\" -ca \"YOUR_ROOT_CA_PATH -H \"YOUR_ENDPOINT\" -p 8883\n"
8
-
9
- opts.separator ""
10
- opts.separator "Common options"
11
- opts.on_tail("-h", "--help", "--usage", "Show this message") do
12
- puts opts
13
- exit
14
- end
15
-
16
- opts.on("-H", "--host [END_POINT]", "The endpoint where you want to connect") do |host|
17
- options[:host] = host
18
- end
19
-
20
- opts.on("-p", "--port [MQTT_PORT]", "The port used for the connection Default is 8883") do |port|
21
- options[:port] = port
22
- end
23
-
24
- opts.on("-c", "--cert [CERT_FILE_PATH]", "The path to the certificate file of the private key.") do |cert|
25
- options[:cert] = cert
26
- end
27
-
28
- opts.on("-k", "--key [KEY_FILE_PATH]", "The path to private key file that would be used for encryption") do |key|
29
- options[:key] = key
30
- end
31
-
32
- opts.on("-a", "--root_ca [ROOT_CA_PATH]", "The path to the authority certification file") do |root_ca|
33
- options[:root_ca] = root_ca
34
- end
35
-
36
- opts.on("-t", "--thing [THING_NAME]", "The Thing name on which the action would be done") do |thing|
37
- options[:things] = thing
38
- end
39
- end.parse!(ARGV)
40
-
41
-
42
- host = options[:host]
43
- port = options[:port] || 8883
44
- certificate_path = options[:cert]
45
- private_key_path = options[:key]
46
- root_ca_path = options[:root_ca]
47
- thing = options[:things]
1
+ $:.unshift(File.expand_path("../../../samples", __FILE__))
48
2
 
49
- my_shadow_client = AwsIotDevice::MqttShadowClient::ShadowClient.new
50
- my_shadow_client.configure_endpoint(host, port)
51
- my_shadow_client.configure_credentials(root_ca_path, private_key_path, certificate_path)
52
-
53
- my_shadow_client.connect
54
-
55
- my_shadow_client.create_shadow_handler_with_name(thing ,false)
3
+ require 'aws_iot_device'
4
+ require 'config_shadow'
56
5
 
57
6
  filter_callback = Proc.new do |message|
58
7
  puts "Executing the specific callback for topic: #{message.topic}\n##########################################\n"
59
8
  end
60
9
 
61
- n = 1
10
+ my_shadow_client = setting_shadow
62
11
 
12
+ n = 1
63
13
  3.times do
64
14
  puts "Start shadow_delete\n"
65
- my_shadow_client.delete_shadow(filter_callback, 5)
15
+ my_shadow_client.delete_shadow(5, filter_callback)
16
+ sleep 0.01
66
17
  json_payload = '{"state":{"desired":{"property":"RubySDK"}}}'
67
- my_shadow_client.update_shadow(json_payload, nil, 5)
18
+ my_shadow_client.update_shadow(json_payload, 5)
68
19
  n += 1
69
20
  end
70
21
 
71
- sleep 5
22
+ sleep 2
72
23
 
73
24
  my_shadow_client.disconnect