paho-mqtt 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/paho-mqtt.rb +72 -1
- data/lib/paho_mqtt/client.rb +182 -708
- data/lib/paho_mqtt/connection_helper.rb +167 -0
- data/lib/paho_mqtt/handler.rb +271 -0
- data/lib/paho_mqtt/packet.rb +14 -0
- data/lib/paho_mqtt/packet/base.rb +17 -0
- data/lib/paho_mqtt/packet/connack.rb +19 -3
- data/lib/paho_mqtt/packet/connect.rb +50 -21
- data/lib/paho_mqtt/packet/disconnect.rb +18 -1
- data/lib/paho_mqtt/packet/pingreq.rb +17 -0
- data/lib/paho_mqtt/packet/pingresp.rb +17 -0
- data/lib/paho_mqtt/packet/puback.rb +17 -1
- data/lib/paho_mqtt/packet/pubcomp.rb +17 -0
- data/lib/paho_mqtt/packet/publish.rb +17 -0
- data/lib/paho_mqtt/packet/pubrec.rb +17 -0
- data/lib/paho_mqtt/packet/pubrel.rb +17 -0
- data/lib/paho_mqtt/packet/suback.rb +17 -0
- data/lib/paho_mqtt/packet/subscribe.rb +17 -0
- data/lib/paho_mqtt/packet/unsuback.rb +17 -0
- data/lib/paho_mqtt/packet/unsubscribe.rb +17 -0
- data/lib/paho_mqtt/publisher.rb +180 -0
- data/lib/paho_mqtt/sender.rb +90 -0
- data/lib/paho_mqtt/ssl_helper.rb +42 -0
- data/lib/paho_mqtt/subscriber.rb +195 -0
- data/lib/paho_mqtt/version.rb +1 -1
- metadata +8 -3
- data/LICENSE.txt +0 -21
@@ -0,0 +1,180 @@
|
|
1
|
+
# Copyright (c) 2016-2017 Pierre Goudet <p-goudet@ruby-dev.jp>
|
2
|
+
#
|
3
|
+
# All rights reserved. This program and the accompanying materials
|
4
|
+
# are made available under the terms of the Eclipse Public License v1.0
|
5
|
+
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
6
|
+
#
|
7
|
+
# The Eclipse Public License is available at
|
8
|
+
# https://eclipse.org/org/documents/epl-v10.php.
|
9
|
+
# and the Eclipse Distribution License is available at
|
10
|
+
# https://eclipse.org/org/documents/edl-v10.php.
|
11
|
+
#
|
12
|
+
# Contributors:
|
13
|
+
# Pierre Goudet - initial committer
|
14
|
+
|
15
|
+
module PahoMqtt
|
16
|
+
class Publisher
|
17
|
+
|
18
|
+
def initialize(sender)
|
19
|
+
@waiting_puback = []
|
20
|
+
@waiting_pubrec = []
|
21
|
+
@waiting_pubrel = []
|
22
|
+
@waiting_pubcomp = []
|
23
|
+
@puback_mutex = Mutex.new
|
24
|
+
@pubrec_mutex = Mutex.new
|
25
|
+
@pubrel_mutex = Mutex.new
|
26
|
+
@pubcomp_mutex = Mutex.new
|
27
|
+
@sender = sender
|
28
|
+
end
|
29
|
+
|
30
|
+
def sender=(sender)
|
31
|
+
@sender = sender
|
32
|
+
end
|
33
|
+
|
34
|
+
def send_publish(topic, payload, retain, qos, new_id)
|
35
|
+
packet = PahoMqtt::Packet::Publish.new(
|
36
|
+
:id => new_id,
|
37
|
+
:topic => topic,
|
38
|
+
:payload => payload,
|
39
|
+
:retain => retain,
|
40
|
+
:qos => qos
|
41
|
+
)
|
42
|
+
@sender.append_to_writing(packet)
|
43
|
+
case qos
|
44
|
+
when 1
|
45
|
+
@puback_mutex.synchronize{
|
46
|
+
@waiting_puback.push({:id => new_id, :packet => packet, :timestamp => Time.now})
|
47
|
+
}
|
48
|
+
when 2
|
49
|
+
@pubrec_mutex.synchronize{
|
50
|
+
@waiting_pubrec.push({:id => new_id, :packet => packet, :timestamp => Time.now})
|
51
|
+
}
|
52
|
+
end
|
53
|
+
MQTT_ERR_SUCCESS
|
54
|
+
end
|
55
|
+
|
56
|
+
def do_publish(qos, packet_id)
|
57
|
+
case qos
|
58
|
+
when 0
|
59
|
+
when 1
|
60
|
+
send_puback(packet_id)
|
61
|
+
when 2
|
62
|
+
send_pubrec(packet_id)
|
63
|
+
else
|
64
|
+
@logger.error("The packet qos value is invalid in publish.") if logger?
|
65
|
+
raise PacketException
|
66
|
+
end
|
67
|
+
MQTT_ERR_SUCCESS
|
68
|
+
end
|
69
|
+
|
70
|
+
def send_puback(packet_id)
|
71
|
+
packet = PahoMqtt::Packet::Puback.new(
|
72
|
+
:id => packet_id
|
73
|
+
)
|
74
|
+
@sender.append_to_writing(packet)
|
75
|
+
MQTT_ERR_SUCCESS
|
76
|
+
end
|
77
|
+
|
78
|
+
def do_puback(packet_id)
|
79
|
+
@puback_mutex.synchronize{
|
80
|
+
@waiting_puback.delete_if { |pck| pck[:id] == packet_id }
|
81
|
+
}
|
82
|
+
MQTT_ERR_SUCCESS
|
83
|
+
end
|
84
|
+
|
85
|
+
def send_pubrec(packet_id)
|
86
|
+
packet = PahoMqtt::Packet::Pubrec.new(
|
87
|
+
:id => packet_id
|
88
|
+
)
|
89
|
+
@sender.append_to_writing(packet)
|
90
|
+
@pubrel_mutex.synchronize{
|
91
|
+
@waiting_pubrel.push({:id => packet_id , :packet => packet, :timestamp => Time.now})
|
92
|
+
}
|
93
|
+
MQTT_ERR_SUCCESS
|
94
|
+
end
|
95
|
+
|
96
|
+
def do_pubrec(packet_id)
|
97
|
+
@pubrec_mutex.synchronize {
|
98
|
+
@waiting_pubrec.delete_if { |pck| pck[:id] == packet_id }
|
99
|
+
}
|
100
|
+
send_pubrel(packet_id)
|
101
|
+
MQTT_ERR_SUCCESS
|
102
|
+
end
|
103
|
+
|
104
|
+
def send_pubrel(packet_id)
|
105
|
+
packet = PahoMqtt::Packet::Pubrel.new(
|
106
|
+
:id => packet_id
|
107
|
+
)
|
108
|
+
@sender.append_to_writing(packet)
|
109
|
+
@pubcomp_mutex.synchronize{
|
110
|
+
@waiting_pubcomp.push({:id => packet_id, :packet => packet, :timestamp => Time.now})
|
111
|
+
}
|
112
|
+
MQTT_ERR_SUCCESS
|
113
|
+
end
|
114
|
+
|
115
|
+
def do_pubrel(packet_id)
|
116
|
+
@pubrel_mutex.synchronize {
|
117
|
+
@waiting_pubrel.delete_if { |pck| pck[:id] == packet_id }
|
118
|
+
}
|
119
|
+
send_pubcomp(packet_id)
|
120
|
+
MQTT_ERR_SUCCESS
|
121
|
+
end
|
122
|
+
|
123
|
+
def send_pubcomp(packet_id)
|
124
|
+
packet = PahoMqtt::Packet::Pubcomp.new(
|
125
|
+
:id => packet_id
|
126
|
+
)
|
127
|
+
@sender.append_to_writing(packet)
|
128
|
+
MQTT_ERR_SUCCESS
|
129
|
+
end
|
130
|
+
|
131
|
+
def do_pubcomp(packet_id)
|
132
|
+
@pubcomp_mutex.synchronize {
|
133
|
+
@waiting_pubcomp.delete_if { |pck| pck[:id] == packet_id }
|
134
|
+
}
|
135
|
+
MQTT_ERR_SUCCESS
|
136
|
+
end
|
137
|
+
|
138
|
+
def config_all_message_queue
|
139
|
+
config_message_queue(@waiting_puback, @puback_mutex, MAX_PUBACK)
|
140
|
+
config_message_queue(@waiting_pubrec, @pubrec_mutex, MAX_PUBREC)
|
141
|
+
config_message_queue(@waiting_pubrel, @pubrel_mutex, MAX_PUBREL)
|
142
|
+
config_message_queue(@waiting_pubcomp, @pubcomp_mutex, MAX_PUBCOMP)
|
143
|
+
end
|
144
|
+
|
145
|
+
def config_message_queue(queue, mutex, max_packet)
|
146
|
+
mutex.synchronize {
|
147
|
+
cnt = 0
|
148
|
+
queue.each do |pck|
|
149
|
+
pck[:packet].dup ||= true
|
150
|
+
if cnt <= max_packet
|
151
|
+
@sender.append_to_writing(pck[:packet])
|
152
|
+
cnt += 1
|
153
|
+
end
|
154
|
+
end
|
155
|
+
}
|
156
|
+
end
|
157
|
+
|
158
|
+
def check_waiting_publisher
|
159
|
+
@sender.check_ack_alive(@waiting_puback, @puback_mutex, MAX_PUBACK)
|
160
|
+
@sender.check_ack_alive(@waiting_pubrec, @pubrec_mutex, MAX_PUBREC)
|
161
|
+
@sender.check_ack_alive(@waiting_pubrel, @pubrel_mutex, MAX_PUBREL)
|
162
|
+
@sender.check_ack_alive(@waiting_pubcomp, @pubcomp_mutex, MAX_PUBCOMP)
|
163
|
+
end
|
164
|
+
|
165
|
+
def flush_publisher
|
166
|
+
@puback_mutex.synchronize {
|
167
|
+
@waiting_puback = []
|
168
|
+
}
|
169
|
+
@pubrec_mutex.synchronize {
|
170
|
+
@waiting_pubrec = []
|
171
|
+
}
|
172
|
+
@pubrel_mutex.synchronize {
|
173
|
+
@waiting_pubrel = []
|
174
|
+
}
|
175
|
+
@pubcomp_mutex.synchronize {
|
176
|
+
@waiting_pubcomp = []
|
177
|
+
}
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# Copyright (c) 2016-2017 Pierre Goudet <p-goudet@ruby-dev.jp>
|
2
|
+
#
|
3
|
+
# All rights reserved. This program and the accompanying materials
|
4
|
+
# are made available under the terms of the Eclipse Public License v1.0
|
5
|
+
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
6
|
+
#
|
7
|
+
# The Eclipse Public License is available at
|
8
|
+
# https://eclipse.org/org/documents/epl-v10.php.
|
9
|
+
# and the Eclipse Distribution License is available at
|
10
|
+
# https://eclipse.org/org/documents/edl-v10.php.
|
11
|
+
#
|
12
|
+
# Contributors:
|
13
|
+
# Pierre Goudet - initial committer
|
14
|
+
|
15
|
+
module PahoMqtt
|
16
|
+
class Sender
|
17
|
+
|
18
|
+
attr_accessor :last_ping_req
|
19
|
+
|
20
|
+
def initialize(ack_timeout)
|
21
|
+
@socket = nil
|
22
|
+
@writing_queue = []
|
23
|
+
@writing_mutex = Mutex.new
|
24
|
+
@last_ping_req = -1
|
25
|
+
@ack_timeout = ack_timeout
|
26
|
+
end
|
27
|
+
|
28
|
+
def socket=(socket)
|
29
|
+
@socket = socket
|
30
|
+
end
|
31
|
+
|
32
|
+
def send_packet(packet)
|
33
|
+
begin
|
34
|
+
@socket.write(packet.to_s) unless @socket.nil? || @socket.closed?
|
35
|
+
@last_ping_req = Time.now
|
36
|
+
MQTT_ERR_SUCCESS
|
37
|
+
rescue StandardError
|
38
|
+
raise WritingException
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def append_to_writing(packet)
|
43
|
+
@writing_mutex.synchronize {
|
44
|
+
@writing_queue.push(packet)
|
45
|
+
}
|
46
|
+
MQTT_ERR_SUCCESS
|
47
|
+
end
|
48
|
+
|
49
|
+
@writing_mutex.synchronize {
|
50
|
+
def writing_loop(max_packet)
|
51
|
+
cnt = 0
|
52
|
+
while !@writing_queue.empty? && cnt < max_packet do
|
53
|
+
packet = @writing_queue.shift
|
54
|
+
send_packet(packet)
|
55
|
+
cnt += 1
|
56
|
+
end
|
57
|
+
}
|
58
|
+
MQTT_ERR_SUCCESS
|
59
|
+
end
|
60
|
+
|
61
|
+
def flush_waiting_packet(sending=true)
|
62
|
+
if sending
|
63
|
+
@writing_mutex.synchronize {
|
64
|
+
@writing_queue.each do |m|
|
65
|
+
send_packet(m)
|
66
|
+
end
|
67
|
+
}
|
68
|
+
else
|
69
|
+
@writing_queue = []
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def check_ack_alive(queue, mutex, max_packet)
|
74
|
+
mutex.synchronize {
|
75
|
+
now = Time.now
|
76
|
+
cnt = 0
|
77
|
+
queue.each do |pck|
|
78
|
+
if now >= pck[:timestamp] + @ack_timeout
|
79
|
+
pck[:packet].dup ||= true unless pck[:packet].class == PahoMqtt::Packet::Subscribe || pck[:packet].class == PahoMqtt::Packet::Unsubscribe
|
80
|
+
unless cnt > max_packet
|
81
|
+
append_to_writing(pck[:packet])
|
82
|
+
pck[:timestamp] = now
|
83
|
+
cnt += 1
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
}
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Copyright (c) 2016-2017 Pierre Goudet <p-goudet@ruby-dev.jp>
|
2
|
+
#
|
3
|
+
# All rights reserved. This program and the accompanying materials
|
4
|
+
# are made available under the terms of the Eclipse Public License v1.0
|
5
|
+
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
6
|
+
#
|
7
|
+
# The Eclipse Public License is available at
|
8
|
+
# https://eclipse.org/org/documents/epl-v10.php.
|
9
|
+
# and the Eclipse Distribution License is available at
|
10
|
+
# https://eclipse.org/org/documents/edl-v10.php.
|
11
|
+
#
|
12
|
+
# Contributors:
|
13
|
+
# Pierre Goudet - initial committer
|
14
|
+
|
15
|
+
require 'openssl'
|
16
|
+
|
17
|
+
module PahoMqtt
|
18
|
+
module SSLHelper
|
19
|
+
extend self
|
20
|
+
|
21
|
+
def config_ssl_context(cert_path, key_path, ca_path=nil)
|
22
|
+
ssl_context = OpenSSL::SSL::SSLContext.new
|
23
|
+
set_cert(cert_path, ssl_context)
|
24
|
+
set_key(key_path, ssl_context)
|
25
|
+
set_root_ca(ca_path, ssl_context)
|
26
|
+
ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER unless ca_path.nil?
|
27
|
+
ssl_context
|
28
|
+
end
|
29
|
+
|
30
|
+
def set_cert(cert_path, ssl_context)
|
31
|
+
ssl_context.cert = OpenSSL::X509::Certificate.new(File.read(cert_path))
|
32
|
+
end
|
33
|
+
|
34
|
+
def set_key(key_path, ssl_context)
|
35
|
+
ssl_context.key = OpenSSL::PKey::RSA.new(File.read(key_path))
|
36
|
+
end
|
37
|
+
|
38
|
+
def set_root_ca(ca_path, ssl_context)
|
39
|
+
ssl_context.ca_file = ca_path
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,195 @@
|
|
1
|
+
# Copyright (c) 2016-2017 Pierre Goudet <p-goudet@ruby-dev.jp>
|
2
|
+
#
|
3
|
+
# All rights reserved. This program and the accompanying materials
|
4
|
+
# are made available under the terms of the Eclipse Public License v1.0
|
5
|
+
# and Eclipse Distribution License v1.0 which accompany this distribution.
|
6
|
+
#
|
7
|
+
# The Eclipse Public License is available at
|
8
|
+
# https://eclipse.org/org/documents/epl-v10.php.
|
9
|
+
# and the Eclipse Distribution License is available at
|
10
|
+
# https://eclipse.org/org/documents/edl-v10.php.
|
11
|
+
#
|
12
|
+
# Contributors:
|
13
|
+
# Pierre Goudet - initial committer
|
14
|
+
|
15
|
+
module PahoMqtt
|
16
|
+
class Subscriber
|
17
|
+
|
18
|
+
attr_reader :subscribed_topics
|
19
|
+
|
20
|
+
def initialize(sender)
|
21
|
+
@waiting_suback = []
|
22
|
+
@waiting_unsuback = []
|
23
|
+
@subscribed_mutex = Mutex.new
|
24
|
+
@subscribed_topics = []
|
25
|
+
@suback_mutex = Mutex.new
|
26
|
+
@unsuback_mutex = Mutex.new
|
27
|
+
@sender = sender
|
28
|
+
end
|
29
|
+
|
30
|
+
def sender=(sender)
|
31
|
+
@sender = sender
|
32
|
+
end
|
33
|
+
|
34
|
+
def config_subscription(new_id)
|
35
|
+
unless @subscribed_topics == [] || @subscribed_topics.nil?
|
36
|
+
packet = PahoMqtt::Packet::Subscribe.new(
|
37
|
+
:id => new_id,
|
38
|
+
:topics => @subscribed_topics
|
39
|
+
)
|
40
|
+
@subscribed_mutex.synchronize {
|
41
|
+
@subscribed_topics = []
|
42
|
+
}
|
43
|
+
@suback_mutex.synchronize {
|
44
|
+
@waiting_suback.push({ :id => new_id, :packet => packet, :timestamp => Time.now })
|
45
|
+
}
|
46
|
+
@sender.send_packet(packet)
|
47
|
+
end
|
48
|
+
MQTT_ERR_SUCCESS
|
49
|
+
end
|
50
|
+
|
51
|
+
def add_subscription(max_qos, packet_id, adjust_qos)
|
52
|
+
@suback_mutex.synchronize {
|
53
|
+
adjust_qos, @waiting_suback = @waiting_suback.partition { |pck| pck[:id] == packet_id }
|
54
|
+
}
|
55
|
+
if adjust_qos.length == 1
|
56
|
+
adjust_qos = adjust_qos.first[:packet].topics
|
57
|
+
adjust_qos.each do |t|
|
58
|
+
if [0, 1, 2].include?(max_qos[0])
|
59
|
+
t[1] = max_qos.shift
|
60
|
+
elsif max_qos[0] == 128
|
61
|
+
adjust_qos.delete(t)
|
62
|
+
else
|
63
|
+
|
64
|
+
@logger.error("The qos value is invalid in subscribe.") if logger?
|
65
|
+
raise PacketException
|
66
|
+
end
|
67
|
+
end
|
68
|
+
else
|
69
|
+
@logger.error("The packet id is invalid, already used.") if logger?
|
70
|
+
raise PacketException
|
71
|
+
end
|
72
|
+
@subscribed_mutex.synchronize {
|
73
|
+
@subscribed_topics.concat(adjust_qos)
|
74
|
+
}
|
75
|
+
MQTT_ERR_SUCCESS
|
76
|
+
end
|
77
|
+
|
78
|
+
def remove_subscription(packet_id, to_unsub)
|
79
|
+
@unsuback_mutex.synchronize {
|
80
|
+
to_unsub, @waiting_unsuback = @waiting_unsuback.partition { |pck| pck[:id] == packet_id }
|
81
|
+
}
|
82
|
+
|
83
|
+
if to_unsub.length == 1
|
84
|
+
to_unsub = to_unsub.first[:packet].topics
|
85
|
+
else
|
86
|
+
@logger.error("The packet id is invalid, already used.") if logger?
|
87
|
+
raise PacketException
|
88
|
+
end
|
89
|
+
|
90
|
+
@subscribed_mutex.synchronize {
|
91
|
+
to_unsub.each do |filter|
|
92
|
+
@subscribed_topics.delete_if { |topic| match_filter(topic.first, filter.first) }
|
93
|
+
end
|
94
|
+
}
|
95
|
+
MQTT_ERR_SUCCESS
|
96
|
+
end
|
97
|
+
|
98
|
+
def send_subscribe(topics, new_id)
|
99
|
+
unless valid_topics?(topics) == MQTT_ERR_FAIL
|
100
|
+
packet = PahoMqtt::Packet::Subscribe.new(
|
101
|
+
:id => new_id,
|
102
|
+
:topics => topics
|
103
|
+
)
|
104
|
+
@sender.append_to_writing(packet)
|
105
|
+
@suback_mutex.synchronize {
|
106
|
+
@waiting_suback.push({ :id => new_id, :packet => packet, :timestamp => Time.now })
|
107
|
+
}
|
108
|
+
MQTT_ERR_SUCCESS
|
109
|
+
else
|
110
|
+
raise ProtocolViolation
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def send_unsubscribe(topics, new_id)
|
115
|
+
unless valid_topics?(topics) == MQTT_ERR_FAIL
|
116
|
+
packet = PahoMqtt::Packet::Unsubscribe.new(
|
117
|
+
:id => new_id,
|
118
|
+
:topics => topics
|
119
|
+
)
|
120
|
+
|
121
|
+
@sender.append_to_writing(packet)
|
122
|
+
@unsuback_mutex.synchronize {
|
123
|
+
@waiting_unsuback.push({:id => new_id, :packet => packet, :timestamp => Time.now})
|
124
|
+
}
|
125
|
+
MQTT_ERR_SUCCESS
|
126
|
+
else
|
127
|
+
raise ProtocolViolation
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def check_waiting_subscriber
|
132
|
+
@sender.check_ack_alive(@waiting_suback, @suback_mutex, @waiting_suback.length)
|
133
|
+
@sender.check_ack_alive(@waiting_unsuback, @unsuback_mutex, @waiting_unsuback.length)
|
134
|
+
end
|
135
|
+
|
136
|
+
def valid_topics?(topics)
|
137
|
+
unless topics.length == 0
|
138
|
+
topics.map do |topic|
|
139
|
+
return MQTT_ERR_FAIL if topic.first == ""
|
140
|
+
end
|
141
|
+
else
|
142
|
+
MQTT_ERR_FAIL
|
143
|
+
end
|
144
|
+
MQTT_ERR_SUCCESS
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
private
|
149
|
+
|
150
|
+
def match_filter(topics, filters)
|
151
|
+
check_topics(topics, filters)
|
152
|
+
index = 0
|
153
|
+
rc = false
|
154
|
+
topic = topics.split('/')
|
155
|
+
filter = filters.split('/')
|
156
|
+
while index < [topic.length, filter.length].max do
|
157
|
+
if is_end?(topic[index], filter[index])
|
158
|
+
break
|
159
|
+
elsif is_wildcard?(filter[index])
|
160
|
+
rc = index == (filter.length - 1)
|
161
|
+
break
|
162
|
+
elsif keep_running?(filter[index], topic[index])
|
163
|
+
index = index + 1
|
164
|
+
else
|
165
|
+
break
|
166
|
+
end
|
167
|
+
end
|
168
|
+
is_matching?(rc, topic.length, filter.length, index)
|
169
|
+
end
|
170
|
+
|
171
|
+
def keep_running?(filter_part, topic_part)
|
172
|
+
filter_part == topic_part || filter_part == '+'
|
173
|
+
end
|
174
|
+
|
175
|
+
def is_wildcard?(filter_part)
|
176
|
+
filter_part == '#'
|
177
|
+
end
|
178
|
+
|
179
|
+
def is_end?(topic_part, filter_part)
|
180
|
+
topic_part.nil? || filter_part.nil?
|
181
|
+
end
|
182
|
+
|
183
|
+
def is_matching?(rc, topic_length, filter_length, index)
|
184
|
+
rc || index == [topic_length, filter_length].max
|
185
|
+
end
|
186
|
+
|
187
|
+
def check_topics(topics, filters)
|
188
|
+
if topics.is_a?(String) && filters.is_a?(String)
|
189
|
+
else
|
190
|
+
@logger.error("Topics or Wildcards are not found as String.") if logger?
|
191
|
+
raise ArgumentError
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|