ably-rest 0.8.6 → 0.8.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/SPEC.md +1049 -1001
  3. data/lib/submodules/ably-ruby/CHANGELOG.md +75 -3
  4. data/lib/submodules/ably-ruby/LICENSE +2 -2
  5. data/lib/submodules/ably-ruby/README.md +81 -20
  6. data/lib/submodules/ably-ruby/SPEC.md +1209 -693
  7. data/lib/submodules/ably-ruby/ably.gemspec +4 -4
  8. data/lib/submodules/ably-ruby/lib/ably/auth.rb +13 -4
  9. data/lib/submodules/ably-ruby/lib/ably/exceptions.rb +10 -1
  10. data/lib/submodules/ably-ruby/lib/ably/logger.rb +3 -1
  11. data/lib/submodules/ably-ruby/lib/ably/models/cipher_params.rb +114 -0
  12. data/lib/submodules/ably-ruby/lib/ably/models/connection_details.rb +10 -7
  13. data/lib/submodules/ably-ruby/lib/ably/models/error_info.rb +3 -3
  14. data/lib/submodules/ably-ruby/lib/ably/models/idiomatic_ruby_wrapper.rb +28 -21
  15. data/lib/submodules/ably-ruby/lib/ably/models/message.rb +19 -17
  16. data/lib/submodules/ably-ruby/lib/ably/models/message_encoders/cipher.rb +10 -9
  17. data/lib/submodules/ably-ruby/lib/ably/models/paginated_result.rb +27 -1
  18. data/lib/submodules/ably-ruby/lib/ably/models/presence_message.rb +20 -18
  19. data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +26 -19
  20. data/lib/submodules/ably-ruby/lib/ably/models/{stat.rb → stats.rb} +21 -19
  21. data/lib/submodules/ably-ruby/lib/ably/models/token_details.rb +14 -12
  22. data/lib/submodules/ably-ruby/lib/ably/models/token_request.rb +16 -14
  23. data/lib/submodules/ably-ruby/lib/ably/modules/async_wrapper.rb +2 -2
  24. data/lib/submodules/ably-ruby/lib/ably/modules/channels_collection.rb +11 -1
  25. data/lib/submodules/ably-ruby/lib/ably/modules/encodeable.rb +10 -10
  26. data/lib/submodules/ably-ruby/lib/ably/modules/enum.rb +18 -2
  27. data/lib/submodules/ably-ruby/lib/ably/modules/event_emitter.rb +3 -3
  28. data/lib/submodules/ably-ruby/lib/ably/modules/model_common.rb +13 -5
  29. data/lib/submodules/ably-ruby/lib/ably/modules/safe_deferrable.rb +1 -1
  30. data/lib/submodules/ably-ruby/lib/ably/modules/safe_yield.rb +2 -2
  31. data/lib/submodules/ably-ruby/lib/ably/modules/state_emitter.rb +8 -8
  32. data/lib/submodules/ably-ruby/lib/ably/modules/statesman_monkey_patch.rb +2 -2
  33. data/lib/submodules/ably-ruby/lib/ably/modules/uses_state_machine.rb +4 -2
  34. data/lib/submodules/ably-ruby/lib/ably/realtime.rb +1 -0
  35. data/lib/submodules/ably-ruby/lib/ably/realtime/auth.rb +6 -2
  36. data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +7 -6
  37. data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +7 -1
  38. data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +7 -12
  39. data/lib/submodules/ably-ruby/lib/ably/realtime/client/incoming_message_dispatcher.rb +9 -2
  40. data/lib/submodules/ably-ruby/lib/ably/realtime/client/outgoing_message_dispatcher.rb +7 -1
  41. data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +19 -8
  42. data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +16 -9
  43. data/lib/submodules/ably-ruby/lib/ably/realtime/connection/websocket_transport.rb +12 -3
  44. data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +35 -64
  45. data/lib/submodules/ably-ruby/lib/ably/realtime/presence/members_map.rb +23 -9
  46. data/lib/submodules/ably-ruby/lib/ably/rest/channel.rb +9 -10
  47. data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +1 -1
  48. data/lib/submodules/ably-ruby/lib/ably/rest/middleware/exceptions.rb +16 -4
  49. data/lib/submodules/ably-ruby/lib/ably/rest/presence.rb +7 -5
  50. data/lib/submodules/ably-ruby/lib/ably/util/crypto.rb +50 -40
  51. data/lib/submodules/ably-ruby/lib/ably/version.rb +1 -1
  52. data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +4 -4
  53. data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +2 -4
  54. data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +46 -8
  55. data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +20 -20
  56. data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_history_spec.rb +7 -7
  57. data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +114 -111
  58. data/lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb +9 -9
  59. data/lib/submodules/ably-ruby/spec/acceptance/rest/base_spec.rb +5 -5
  60. data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +1 -1
  61. data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +1 -1
  62. data/lib/submodules/ably-ruby/spec/acceptance/rest/encoders_spec.rb +4 -4
  63. data/lib/submodules/ably-ruby/spec/acceptance/rest/message_spec.rb +15 -15
  64. data/lib/submodules/ably-ruby/spec/acceptance/rest/presence_spec.rb +4 -4
  65. data/lib/submodules/ably-ruby/spec/shared/model_behaviour.rb +7 -7
  66. data/lib/submodules/ably-ruby/spec/shared/safe_deferrable_behaviour.rb +4 -4
  67. data/lib/submodules/ably-ruby/spec/unit/models/cipher_params_spec.rb +140 -0
  68. data/lib/submodules/ably-ruby/spec/unit/models/idiomatic_ruby_wrapper_spec.rb +15 -8
  69. data/lib/submodules/ably-ruby/spec/unit/models/message_encoders/cipher_spec.rb +28 -22
  70. data/lib/submodules/ably-ruby/spec/unit/models/message_encoders/json_spec.rb +24 -0
  71. data/lib/submodules/ably-ruby/spec/unit/models/protocol_message_spec.rb +3 -3
  72. data/lib/submodules/ably-ruby/spec/unit/models/token_details_spec.rb +20 -18
  73. data/lib/submodules/ably-ruby/spec/unit/modules/event_emitter_spec.rb +2 -2
  74. data/lib/submodules/ably-ruby/spec/unit/modules/state_emitter_spec.rb +6 -6
  75. data/lib/submodules/ably-ruby/spec/unit/realtime/channel_spec.rb +4 -4
  76. data/lib/submodules/ably-ruby/spec/unit/realtime/connection_spec.rb +1 -1
  77. data/lib/submodules/ably-ruby/spec/unit/realtime/presence_spec.rb +5 -5
  78. data/lib/submodules/ably-ruby/spec/unit/util/crypto_spec.rb +50 -17
  79. metadata +5 -3
@@ -4,7 +4,7 @@ require 'ably/util/crypto'
4
4
 
5
5
  module Ably::Models::MessageEncoders
6
6
  # Cipher Encoder & Decoder that automatically encrypts & decrypts messages using Ably::Util::Crypto
7
- # when a channel has option encrypted: true.
7
+ # when a channel has the +:cipher+ channel option configured
8
8
  #
9
9
  class Cipher < Base
10
10
  ENCODING_ID = 'cipher'
@@ -20,16 +20,17 @@ module Ably::Models::MessageEncoders
20
20
 
21
21
  if channel_configured_for_encryption?(channel_options)
22
22
  add_encoding_to_message 'utf-8', message unless is_binary?(message) || is_utf8_encoded?(message)
23
-
24
23
  crypto = crypto_for(channel_options)
25
24
  message[:data] = crypto.encrypt(message[:data])
26
- add_encoding_to_message "#{ENCODING_ID}+#{crypto.cipher_type.downcase}", message
25
+ add_encoding_to_message "#{ENCODING_ID}+#{crypto.cipher_params.cipher_type.downcase}", message
27
26
  end
28
27
  rescue ArgumentError => e
29
28
  raise Ably::Exceptions::CipherError.new(e.message, nil, 92005)
30
29
  rescue RuntimeError => e
31
30
  if e.message.match(/unsupported cipher algorithm/i)
32
31
  raise Ably::Exceptions::CipherError.new(e.message, nil, 92004)
32
+ else
33
+ raise e
33
34
  end
34
35
  end
35
36
 
@@ -40,8 +41,8 @@ module Ably::Models::MessageEncoders
40
41
  end
41
42
 
42
43
  crypto = crypto_for(channel_options)
43
- unless crypto.cipher_type == cipher_algorithm(message).upcase
44
- raise Ably::Exceptions::CipherError.new("Cipher algorithm #{crypto.cipher_type} does not match message cipher algorithm of #{cipher_algorithm(message).upcase}", nil, 92002)
44
+ unless crypto.cipher_params.cipher_type == cipher_algorithm(message).upcase
45
+ raise Ably::Exceptions::CipherError.new("Cipher algorithm #{crypto.cipher_params.cipher_type} does not match message cipher algorithm of #{cipher_algorithm(message).upcase}", nil, 92002)
45
46
  end
46
47
 
47
48
  message[:data] = crypto.decrypt(message[:data])
@@ -61,11 +62,11 @@ module Ably::Models::MessageEncoders
61
62
  end
62
63
 
63
64
  def crypto_for(channel_options)
64
- @cryptos[channel_options.fetch(:cipher_params, :default)] ||= Ably::Util::Crypto.new(channel_options.fetch(:cipher_params, {}))
65
+ @cryptos[channel_options.to_s] ||= Ably::Util::Crypto.new(channel_options.fetch(:cipher, {}))
65
66
  end
66
67
 
67
68
  def channel_configured_for_encryption?(channel_options)
68
- channel_options.fetch(:encrypted, false)
69
+ channel_options[:cipher]
69
70
  end
70
71
 
71
72
  def is_cipher_encoded?(message)
@@ -73,11 +74,11 @@ module Ably::Models::MessageEncoders
73
74
  end
74
75
 
75
76
  def cipher_algorithm(message)
76
- current_encoding_part(message).to_s[/^#{ENCODING_ID}\+([\w_-]+)$/, 1]
77
+ current_encoding_part(message).to_s[/^#{ENCODING_ID}\+([\w-]+)$/, 1]
77
78
  end
78
79
 
79
80
  def already_encrypted?(message)
80
- message.fetch(:encoding, '').to_s.match(%r{(^|/)#{ENCODING_ID}\+([\w_-]+)($|/)})
81
+ message.fetch(:encoding, '').to_s.match(%r{(^|/)#{ENCODING_ID}\+([\w-]+)($|/)})
81
82
  end
82
83
  end
83
84
  end
@@ -95,7 +95,33 @@ module Ably::Models
95
95
  end
96
96
 
97
97
  private
98
- attr_reader :http_response, :base_url, :client, :coerce_into, :raw_body, :each_block, :make_async
98
+ def http_response
99
+ @http_response
100
+ end
101
+
102
+ def base_url
103
+ @base_url
104
+ end
105
+
106
+ def client
107
+ @client
108
+ end
109
+
110
+ def coerce_into
111
+ @coerce_into
112
+ end
113
+
114
+ def raw_body
115
+ @raw_body
116
+ end
117
+
118
+ def each_block
119
+ @each_block
120
+ end
121
+
122
+ def make_async
123
+ @make_async
124
+ end
99
125
 
100
126
  def coerce_items_into(items, type_string)
101
127
  items.map do |item|
@@ -34,7 +34,7 @@ module Ably::Models
34
34
  # Therefore, the `encoding` attribute should always be nil unless an Ably library decoding error has occurred.
35
35
  # @!attribute [r] timestamp
36
36
  # @return [Time] Timestamp when the message was received by the Ably the realtime service
37
- # @!attribute [r] hash
37
+ # @!attribute [r] attributes
38
38
  # @return [Hash] Access the protocol message Hash object ruby'fied to use symbolized keys
39
39
  #
40
40
  class PresenceMessage
@@ -54,17 +54,17 @@ module Ably::Models
54
54
 
55
55
  # {PresenceMessage} initializer
56
56
  #
57
- # @param hash_object [Hash] object with the underlying presence message details
57
+ # @param attributes [Hash] object with the underlying presence message key value attributes
58
58
  # @param [Hash] options an options Hash for this initializer
59
59
  # @option options [ProtocolMessage] :protocol_message An optional protocol message to assocate the presence message with
60
60
  # @option options [Logger] :logger An optional Logger to be used by {Ably::Modules::SafeDeferrable} if an exception is caught in a callback
61
61
  #
62
- def initialize(hash_object, options = {})
62
+ def initialize(attributes, options = {})
63
63
  @logger = options[:logger] # Logger expected for SafeDeferrable
64
64
  @protocol_message = options[:protocol_message]
65
- @raw_hash_object = hash_object
65
+ @raw_hash_object = attributes
66
66
 
67
- set_hash_object hash_object
67
+ set_attributes_object attributes
68
68
 
69
69
  ensure_utf_8 :client_id, client_id, allow_nil: true
70
70
  ensure_utf_8 :connection_id, connection_id, allow_nil: true
@@ -73,16 +73,16 @@ module Ably::Models
73
73
 
74
74
  %w( client_id data encoding ).each do |attribute|
75
75
  define_method attribute do
76
- hash[attribute.to_sym]
76
+ attributes[attribute.to_sym]
77
77
  end
78
78
  end
79
79
 
80
80
  def id
81
- hash.fetch(:id) { "#{protocol_message.id!}:#{protocol_message_index}" }
81
+ attributes.fetch(:id) { "#{protocol_message.id!}:#{protocol_message_index}" }
82
82
  end
83
83
 
84
84
  def connection_id
85
- hash.fetch(:connection_id) { protocol_message.connection_id if assigned_to_protocol_message? }
85
+ attributes.fetch(:connection_id) { protocol_message.connection_id if assigned_to_protocol_message? }
86
86
  end
87
87
 
88
88
  def member_key
@@ -90,24 +90,24 @@ module Ably::Models
90
90
  end
91
91
 
92
92
  def timestamp
93
- if hash[:timestamp]
94
- as_time_from_epoch(hash[:timestamp])
93
+ if attributes[:timestamp]
94
+ as_time_from_epoch(attributes[:timestamp])
95
95
  else
96
96
  protocol_message.timestamp
97
97
  end
98
98
  end
99
99
 
100
100
  def action
101
- ACTION(hash[:action])
101
+ ACTION(attributes[:action])
102
102
  end
103
103
 
104
- def hash
105
- @hash_object
104
+ def attributes
105
+ @attributes
106
106
  end
107
107
 
108
- # Return a JSON ready object from the underlying #hash using Ably naming conventions for keys
108
+ # Return a JSON ready object from the underlying #attributes using Ably naming conventions for keys
109
109
  def as_json(*args)
110
- hash.dup.tap do |presence_message|
110
+ attributes.dup.tap do |presence_message|
111
111
  presence_message['action'] = action.to_i
112
112
  end.as_json.reject { |key, val| val.nil? }
113
113
  rescue KeyError
@@ -143,14 +143,16 @@ module Ably::Models
143
143
  end
144
144
 
145
145
  private
146
- attr_reader :raw_hash_object
146
+ def raw_hash_object
147
+ @raw_hash_object
148
+ end
147
149
 
148
150
  def protocol_message_index
149
151
  protocol_message.presence.index(self)
150
152
  end
151
153
 
152
- def set_hash_object(hash)
153
- @hash_object = IdiomaticRubyWrapper(hash.clone.freeze, stop_at: [:data])
154
+ def set_attributes_object(new_attributes)
155
+ @attributes = IdiomaticRubyWrapper(new_attributes.clone.freeze, stop_at: [:data])
154
156
  end
155
157
 
156
158
  def logger
@@ -32,7 +32,7 @@ module Ably::Models
32
32
  # @return [Array<PresenceMessage>] A {ProtocolMessage} with a `:presence` action contains one or more presence updates belonging to the channel
33
33
  # @!attribute [r] flags
34
34
  # @return [Integer] Flags indicating special ProtocolMessage states
35
- # @!attribute [r] hash
35
+ # @!attribute [r] attributes
36
36
  # @return [Hash] Access the protocol message Hash object ruby'fied to use symbolized keys
37
37
  #
38
38
  class ProtocolMessage
@@ -66,6 +66,7 @@ module Ably::Models
66
66
  )
67
67
 
68
68
  # Indicates this protocol message action will generate an ACK response such as :message or :presence
69
+ # @api private
69
70
  def self.ack_required?(for_action)
70
71
  [ACTION.Presence, ACTION.Message].include?(ACTION(for_action))
71
72
  end
@@ -90,14 +91,14 @@ module Ably::Models
90
91
 
91
92
  %w(id channel channel_serial connection_id).each do |attribute|
92
93
  define_method attribute do
93
- hash[attribute.to_sym]
94
+ attributes[attribute.to_sym]
94
95
  end
95
96
  end
96
97
 
97
98
  def connection_key
98
99
  # connection_key in connection details takes precedence over connection_key on the ProtocolMessage
99
100
  # connection_key in the ProtocolMessage will be deprecated in future protocol versions > 0.8
100
- connection_details.connection_key || hash[:connection_key]
101
+ connection_details.connection_key || attributes[:connection_key]
101
102
  end
102
103
 
103
104
  def id!
@@ -106,41 +107,43 @@ module Ably::Models
106
107
  end
107
108
 
108
109
  def action
109
- ACTION(hash[:action])
110
+ ACTION(attributes[:action])
110
111
  rescue KeyError
111
- raise KeyError, "Action '#{hash[:action]}' is not supported by ProtocolMessage"
112
+ raise KeyError, "Action '#{attributes[:action]}' is not supported by ProtocolMessage"
112
113
  end
113
114
 
114
115
  def error
115
- @error ||= ErrorInfo.new(hash[:error]) if hash[:error]
116
+ @error ||= ErrorInfo.new(attributes[:error]) if attributes[:error]
116
117
  end
117
118
 
118
119
  def timestamp
119
- as_time_from_epoch(hash[:timestamp]) if hash[:timestamp]
120
+ as_time_from_epoch(attributes[:timestamp]) if attributes[:timestamp]
120
121
  end
121
122
 
122
123
  def message_serial
123
- Integer(hash[:msg_serial])
124
+ Integer(attributes[:msg_serial])
124
125
  rescue TypeError
125
- raise TypeError, "msg_serial '#{hash[:msg_serial]}' is invalid, a positive Integer is expected for a ProtocolMessage"
126
+ raise TypeError, "msg_serial '#{attributes[:msg_serial]}' is invalid, a positive Integer is expected for a ProtocolMessage"
126
127
  end
127
128
 
128
129
  def connection_serial
129
- Integer(hash[:connection_serial])
130
+ Integer(attributes[:connection_serial])
130
131
  rescue TypeError
131
- raise TypeError, "connection_serial '#{hash[:connection_serial]}' is invalid, a positive Integer is expected for a ProtocolMessage"
132
+ raise TypeError, "connection_serial '#{attributes[:connection_serial]}' is invalid, a positive Integer is expected for a ProtocolMessage"
132
133
  end
133
134
 
134
135
  def count
135
- [1, hash[:count].to_i].max
136
+ [1, attributes[:count].to_i].max
136
137
  end
137
138
 
139
+ # @api private
138
140
  def has_message_serial?
139
141
  message_serial && true
140
142
  rescue TypeError
141
143
  false
142
144
  end
143
145
 
146
+ # @api private
144
147
  def has_connection_serial?
145
148
  connection_serial && true
146
149
  rescue TypeError
@@ -155,58 +158,62 @@ module Ably::Models
155
158
  end
156
159
  end
157
160
 
161
+ # @api private
158
162
  def has_serial?
159
163
  has_connection_serial? || has_message_serial?
160
164
  end
161
165
 
162
166
  def messages
163
167
  @messages ||=
164
- Array(hash[:messages]).map do |message|
168
+ Array(attributes[:messages]).map do |message|
165
169
  Ably::Models.Message(message, protocol_message: self)
166
170
  end
167
171
  end
168
172
 
173
+ # @api private
169
174
  def add_message(message)
170
175
  messages << message
171
176
  end
172
177
 
173
178
  def presence
174
179
  @presence ||=
175
- Array(hash[:presence]).map do |message|
180
+ Array(attributes[:presence]).map do |message|
176
181
  Ably::Models.PresenceMessage(message, protocol_message: self)
177
182
  end
178
183
  end
179
184
 
180
185
  def flags
181
- Integer(hash[:flags])
186
+ Integer(attributes[:flags])
182
187
  rescue TypeError
183
188
  0
184
189
  end
185
190
 
191
+ # @api private
186
192
  def has_presence_flag?
187
193
  flags & 1 == 1
188
194
  end
189
195
 
190
196
  def connection_details
191
- @connection_details ||= Ably::Models::ConnectionDetails(hash[:connection_details])
197
+ @connection_details ||= Ably::Models::ConnectionDetails(attributes[:connection_details])
192
198
  end
193
199
 
194
200
  # Indicates this protocol message will generate an ACK response when sent
195
201
  # Examples of protocol messages required ACK include :message and :presence
202
+ # @api private
196
203
  def ack_required?
197
204
  self.class.ack_required?(action)
198
205
  end
199
206
 
200
- def hash
207
+ def attributes
201
208
  @hash_object
202
209
  end
203
210
 
204
- # Return a JSON ready object from the underlying #hash using Ably naming conventions for keys
211
+ # Return a JSON ready object from the underlying #attributes using Ably naming conventions for keys
205
212
  def as_json(*args)
206
213
  raise TypeError, ':action is missing, cannot generate a valid Hash for ProtocolMessage' unless action
207
214
  raise TypeError, ':msg_serial or :connection_serial is missing, cannot generate a valid Hash for ProtocolMessage' if ack_required? && !has_serial?
208
215
 
209
- hash.dup.tap do |hash_object|
216
+ attributes.dup.tap do |hash_object|
210
217
  hash_object['action'] = action.to_i
211
218
  hash_object['messages'] = messages.map(&:as_json) unless messages.empty?
212
219
  hash_object['presence'] = presence.map(&:as_json) unless presence.empty?
@@ -82,7 +82,7 @@ module Ably::Models
82
82
  def from_interval_id(interval_id)
83
83
  raise ArgumentError, 'Interval ID must be a string' unless interval_id.kind_of?(String)
84
84
 
85
- format = INTERVAL_FORMAT_STRING.find { |format| expected_length(format) == interval_id.length }
85
+ format = INTERVAL_FORMAT_STRING.find { |fmt| expected_length(fmt) == interval_id.length }
86
86
  raise ArgumentError, 'Interval ID is an invalid length' unless format
87
87
 
88
88
  Time.strptime("#{interval_id} +0000", "#{format} %z").utc
@@ -99,7 +99,7 @@ module Ably::Models
99
99
  def granularity_from_interval_id(interval_id)
100
100
  raise ArgumentError, 'Interval ID must be a string' unless interval_id.kind_of?(String)
101
101
 
102
- format = INTERVAL_FORMAT_STRING.find { |format| expected_length(format) == interval_id.length }
102
+ format = INTERVAL_FORMAT_STRING.find { |fmt| expected_length(fmt) == interval_id.length }
103
103
  raise ArgumentError, 'Interval ID is an invalid length' unless format
104
104
 
105
105
  GRANULARITY[INTERVAL_FORMAT_STRING.index(format)]
@@ -117,61 +117,61 @@ module Ably::Models
117
117
  #
118
118
  def initialize(hash_object)
119
119
  @raw_hash_object = hash_object
120
- set_hash_object hash_object
120
+ set_attributes_object hash_object
121
121
  end
122
122
 
123
123
  # Aggregates inbound and outbound messages
124
- # return {@Stats::MessageTypes}
124
+ # @return {Stats::MessageTypes}
125
125
  def all
126
- @all ||= Stats::MessageTypes.new(hash[:all])
126
+ @all ||= Stats::MessageTypes.new(attributes[:all])
127
127
  end
128
128
 
129
129
  # All inbound messages i.e. received by Ably from clients
130
130
  # @return {Stats::MessageTraffic}
131
131
  def inbound
132
- @inbound ||= Stats::MessageTraffic.new(hash[:inbound])
132
+ @inbound ||= Stats::MessageTraffic.new(attributes[:inbound])
133
133
  end
134
134
 
135
135
  # All outbound messages i.e. sent from Ably to clients
136
136
  # @return {Stats::MessageTraffic}
137
137
  def outbound
138
- @outbound ||= Stats::MessageTraffic.new(hash[:outbound])
138
+ @outbound ||= Stats::MessageTraffic.new(attributes[:outbound])
139
139
  end
140
140
 
141
141
  # Messages persisted for later retrieval via the history API
142
142
  # @return {Stats::MessageTypes}
143
143
  def persisted
144
- @persisted ||= Stats::MessageTypes.new(hash[:persisted])
144
+ @persisted ||= Stats::MessageTypes.new(attributes[:persisted])
145
145
  end
146
146
 
147
147
  # Breakdown of connection stats data for different (TLS vs non-TLS) connection types
148
148
  # @return {Stats::ConnectionTypes}
149
149
  def connections
150
- @connections ||= Stats::ConnectionTypes.new(hash[:connections])
150
+ @connections ||= Stats::ConnectionTypes.new(attributes[:connections])
151
151
  end
152
152
 
153
153
  # Breakdown of channels stats
154
154
  # @return {Stats::ResourceCount}
155
155
  def channels
156
- @channels ||= Stats::ResourceCount.new(hash[:channels])
156
+ @channels ||= Stats::ResourceCount.new(attributes[:channels])
157
157
  end
158
158
 
159
159
  # Breakdown of API requests received via the REST API
160
160
  # @return {Stats::RequestCount}
161
161
  def api_requests
162
- @api_requests ||= Stats::RequestCount.new(hash[:api_requests])
162
+ @api_requests ||= Stats::RequestCount.new(attributes[:api_requests])
163
163
  end
164
164
 
165
165
  # Breakdown of Token requests received via the REST API
166
166
  # @return {Stats::RequestCount}
167
167
  def token_requests
168
- @token_requests ||= Stats::RequestCount.new(hash[:token_requests])
168
+ @token_requests ||= Stats::RequestCount.new(attributes[:token_requests])
169
169
  end
170
170
 
171
171
  # @!attribute [r] interval_id
172
172
  # @return [String] The interval that this statistic applies to, see {GRANULARITY} and {INTERVAL_FORMAT_STRING}
173
173
  def interval_id
174
- hash.fetch(:interval_id)
174
+ attributes.fetch(:interval_id)
175
175
  end
176
176
 
177
177
  # @!attribute [r] interval_time
@@ -186,19 +186,21 @@ module Ably::Models
186
186
  self.class.granularity_from_interval_id(interval_id)
187
187
  end
188
188
 
189
- def hash
190
- @hash_object
189
+ def attributes
190
+ @attributes
191
191
  end
192
192
 
193
193
  def as_json(*args)
194
- hash.as_json(*args).reject { |key, val| val.nil? }
194
+ attributes.as_json(*args).reject { |key, val| val.nil? }
195
195
  end
196
196
 
197
197
  private
198
- attr_reader :raw_hash_object
198
+ def raw_hash_object
199
+ @raw_hash_object
200
+ end
199
201
 
200
- def set_hash_object(hash)
201
- @hash_object = IdiomaticRubyWrapper(hash.clone.freeze)
202
+ def set_attributes_object(new_attributes)
203
+ @attributes = IdiomaticRubyWrapper(new_attributes.clone.freeze)
202
204
  end
203
205
  end
204
206
  end