ably-rest 1.0.5 → 1.1.3

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.
Files changed (118) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +6 -3
  3. data/CHANGELOG.md +1 -1
  4. data/LICENSE +1 -1
  5. data/README.md +26 -7
  6. data/SPEC.md +2003 -1605
  7. data/ably-rest.gemspec +4 -2
  8. data/lib/submodules/ably-ruby/.editorconfig +14 -0
  9. data/lib/submodules/ably-ruby/.travis.yml +10 -8
  10. data/lib/submodules/ably-ruby/CHANGELOG.md +97 -1
  11. data/lib/submodules/ably-ruby/LICENSE +1 -3
  12. data/lib/submodules/ably-ruby/README.md +12 -7
  13. data/lib/submodules/ably-ruby/Rakefile +32 -0
  14. data/lib/submodules/ably-ruby/SPEC.md +1277 -835
  15. data/lib/submodules/ably-ruby/ably.gemspec +17 -11
  16. data/lib/submodules/ably-ruby/lib/ably/auth.rb +34 -8
  17. data/lib/submodules/ably-ruby/lib/ably/exceptions.rb +10 -4
  18. data/lib/submodules/ably-ruby/lib/ably/logger.rb +8 -2
  19. data/lib/submodules/ably-ruby/lib/ably/models/channel_state_change.rb +1 -1
  20. data/lib/submodules/ably-ruby/lib/ably/models/connection_state_change.rb +1 -1
  21. data/lib/submodules/ably-ruby/lib/ably/models/device_details.rb +87 -0
  22. data/lib/submodules/ably-ruby/lib/ably/models/device_push_details.rb +86 -0
  23. data/lib/submodules/ably-ruby/lib/ably/models/error_info.rb +23 -2
  24. data/lib/submodules/ably-ruby/lib/ably/models/idiomatic_ruby_wrapper.rb +12 -12
  25. data/lib/submodules/ably-ruby/lib/ably/models/message.rb +6 -4
  26. data/lib/submodules/ably-ruby/lib/ably/models/presence_message.rb +6 -4
  27. data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +32 -2
  28. data/lib/submodules/ably-ruby/lib/ably/models/push_channel_subscription.rb +89 -0
  29. data/lib/submodules/ably-ruby/lib/ably/modules/async_wrapper.rb +2 -2
  30. data/lib/submodules/ably-ruby/lib/ably/modules/conversions.rb +2 -2
  31. data/lib/submodules/ably-ruby/lib/ably/modules/encodeable.rb +2 -2
  32. data/lib/submodules/ably-ruby/lib/ably/modules/event_emitter.rb +2 -2
  33. data/lib/submodules/ably-ruby/lib/ably/modules/exception_codes.rb +128 -0
  34. data/lib/submodules/ably-ruby/lib/ably/modules/model_common.rb +15 -2
  35. data/lib/submodules/ably-ruby/lib/ably/modules/safe_deferrable.rb +1 -1
  36. data/lib/submodules/ably-ruby/lib/ably/modules/safe_yield.rb +1 -1
  37. data/lib/submodules/ably-ruby/lib/ably/modules/state_emitter.rb +5 -5
  38. data/lib/submodules/ably-ruby/lib/ably/modules/state_machine.rb +2 -2
  39. data/lib/submodules/ably-ruby/lib/ably/realtime.rb +1 -0
  40. data/lib/submodules/ably-ruby/lib/ably/realtime/auth.rb +2 -2
  41. data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +27 -105
  42. data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +4 -8
  43. data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_state_machine.rb +2 -2
  44. data/lib/submodules/ably-ruby/lib/ably/realtime/channel/publisher.rb +74 -0
  45. data/lib/submodules/ably-ruby/lib/ably/realtime/channel/push_channel.rb +62 -0
  46. data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +91 -3
  47. data/lib/submodules/ably-ruby/lib/ably/realtime/client/incoming_message_dispatcher.rb +9 -4
  48. data/lib/submodules/ably-ruby/lib/ably/realtime/client/outgoing_message_dispatcher.rb +1 -1
  49. data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +45 -26
  50. data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +25 -9
  51. data/lib/submodules/ably-ruby/lib/ably/realtime/connection/websocket_transport.rb +2 -2
  52. data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +7 -7
  53. data/lib/submodules/ably-ruby/lib/ably/realtime/presence/members_map.rb +9 -9
  54. data/lib/submodules/ably-ruby/lib/ably/realtime/push.rb +40 -0
  55. data/lib/submodules/ably-ruby/lib/ably/realtime/push/admin.rb +61 -0
  56. data/lib/submodules/ably-ruby/lib/ably/realtime/push/channel_subscriptions.rb +108 -0
  57. data/lib/submodules/ably-ruby/lib/ably/realtime/push/device_registrations.rb +105 -0
  58. data/lib/submodules/ably-ruby/lib/ably/rest.rb +1 -0
  59. data/lib/submodules/ably-ruby/lib/ably/rest/channel.rb +54 -18
  60. data/lib/submodules/ably-ruby/lib/ably/rest/channel/push_channel.rb +62 -0
  61. data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +171 -41
  62. data/lib/submodules/ably-ruby/lib/ably/rest/middleware/parse_message_pack.rb +17 -1
  63. data/lib/submodules/ably-ruby/lib/ably/rest/presence.rb +1 -0
  64. data/lib/submodules/ably-ruby/lib/ably/rest/push.rb +42 -0
  65. data/lib/submodules/ably-ruby/lib/ably/rest/push/admin.rb +54 -0
  66. data/lib/submodules/ably-ruby/lib/ably/rest/push/channel_subscriptions.rb +121 -0
  67. data/lib/submodules/ably-ruby/lib/ably/rest/push/device_registrations.rb +103 -0
  68. data/lib/submodules/ably-ruby/lib/ably/version.rb +7 -2
  69. data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +253 -49
  70. data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +33 -21
  71. data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +180 -62
  72. data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +155 -2
  73. data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +293 -13
  74. data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +142 -39
  75. data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +38 -36
  76. data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_history_spec.rb +12 -3
  77. data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +207 -173
  78. data/lib/submodules/ably-ruby/spec/acceptance/realtime/push_admin_spec.rb +736 -0
  79. data/lib/submodules/ably-ruby/spec/acceptance/realtime/push_spec.rb +27 -0
  80. data/lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb +62 -51
  81. data/lib/submodules/ably-ruby/spec/acceptance/rest/base_spec.rb +2 -2
  82. data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +79 -4
  83. data/lib/submodules/ably-ruby/spec/acceptance/rest/channels_spec.rb +6 -0
  84. data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +318 -74
  85. data/lib/submodules/ably-ruby/spec/acceptance/rest/message_spec.rb +158 -6
  86. data/lib/submodules/ably-ruby/spec/acceptance/rest/push_admin_spec.rb +952 -0
  87. data/lib/submodules/ably-ruby/spec/acceptance/rest/push_spec.rb +25 -0
  88. data/lib/submodules/ably-ruby/spec/acceptance/rest/time_spec.rb +1 -1
  89. data/lib/submodules/ably-ruby/spec/run_parallel_tests +33 -0
  90. data/lib/submodules/ably-ruby/spec/shared/client_initializer_behaviour.rb +1 -9
  91. data/lib/submodules/ably-ruby/spec/spec_helper.rb +3 -1
  92. data/lib/submodules/ably-ruby/spec/support/debug_failure_helper.rb +9 -5
  93. data/lib/submodules/ably-ruby/spec/support/event_emitter_helper.rb +31 -0
  94. data/lib/submodules/ably-ruby/spec/support/event_machine_helper.rb +1 -1
  95. data/lib/submodules/ably-ruby/spec/support/test_app.rb +2 -2
  96. data/lib/submodules/ably-ruby/spec/support/test_logger_helper.rb +42 -0
  97. data/lib/submodules/ably-ruby/spec/unit/logger_spec.rb +11 -12
  98. data/lib/submodules/ably-ruby/spec/unit/models/device_details_spec.rb +102 -0
  99. data/lib/submodules/ably-ruby/spec/unit/models/device_push_details_spec.rb +101 -0
  100. data/lib/submodules/ably-ruby/spec/unit/models/error_info_spec.rb +51 -3
  101. data/lib/submodules/ably-ruby/spec/unit/models/message_spec.rb +17 -2
  102. data/lib/submodules/ably-ruby/spec/unit/models/presence_message_spec.rb +1 -1
  103. data/lib/submodules/ably-ruby/spec/unit/models/push_channel_subscription_spec.rb +86 -0
  104. data/lib/submodules/ably-ruby/spec/unit/modules/async_wrapper_spec.rb +2 -2
  105. data/lib/submodules/ably-ruby/spec/unit/modules/enum_spec.rb +1 -1
  106. data/lib/submodules/ably-ruby/spec/unit/modules/event_emitter_spec.rb +3 -3
  107. data/lib/submodules/ably-ruby/spec/unit/modules/state_emitter_spec.rb +10 -10
  108. data/lib/submodules/ably-ruby/spec/unit/realtime/channel_spec.rb +1 -1
  109. data/lib/submodules/ably-ruby/spec/unit/realtime/client_spec.rb +13 -1
  110. data/lib/submodules/ably-ruby/spec/unit/realtime/connection_spec.rb +2 -2
  111. data/lib/submodules/ably-ruby/spec/unit/realtime/presence_spec.rb +1 -1
  112. data/lib/submodules/ably-ruby/spec/unit/realtime/push_channel_spec.rb +36 -0
  113. data/lib/submodules/ably-ruby/spec/unit/rest/channel_spec.rb +30 -1
  114. data/lib/submodules/ably-ruby/spec/unit/rest/client_spec.rb +30 -0
  115. data/lib/submodules/ably-ruby/spec/unit/rest/push_channel_spec.rb +36 -0
  116. data/lib/submodules/ably-ruby/spec/unit/util/pub_sub_spec.rb +3 -3
  117. data/spec/spec_helper.rb +1 -0
  118. metadata +51 -10
@@ -18,34 +18,40 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_runtime_dependency 'eventmachine', '~> 1.0'
21
+ spec.add_runtime_dependency 'eventmachine', '~> 1.2.6'
22
22
  spec.add_runtime_dependency 'em-http-request', '~> 1.1'
23
23
  spec.add_runtime_dependency 'statesman', '~> 1.0.0'
24
- spec.add_runtime_dependency 'faraday', '~> 0.9'
24
+ spec.add_runtime_dependency 'faraday', '>= 0.12', '< 2.0.0'
25
+ spec.add_runtime_dependency 'excon', '~> 0.55'
25
26
 
26
- if RUBY_VERSION.match(/^1/)
27
+ if RUBY_VERSION.match(/^1\./)
27
28
  spec.add_runtime_dependency 'json', '< 2.0'
28
29
  else
29
30
  spec.add_runtime_dependency 'json'
30
31
  end
31
- spec.add_runtime_dependency 'websocket-driver', '~> 0.6'
32
- spec.add_runtime_dependency 'msgpack', '>= 0.6.2'
32
+ spec.add_runtime_dependency 'websocket-driver', '~> 0.7'
33
+ spec.add_runtime_dependency 'msgpack', '>= 1.3.0'
33
34
  spec.add_runtime_dependency 'addressable', '>= 2.0.0'
34
35
 
35
- spec.add_development_dependency 'bundler', '~> 1.3'
36
36
  spec.add_development_dependency 'rake', '~> 11.3'
37
37
  spec.add_development_dependency 'redcarpet', '~> 3.3'
38
- spec.add_development_dependency 'rspec', '~> 3.2.0' # version lock, see config.around(:example, :event_machine) in event_machine_helper.rb
39
- spec.add_development_dependency 'rspec-retry', '~> 0.4'
38
+ spec.add_development_dependency 'rspec', '~> 3.3.0' # version lock, see config.around(:example, :event_machine) in event_machine_helper.rb
39
+ spec.add_development_dependency 'rspec-retry', '~> 0.6'
40
40
  spec.add_development_dependency 'yard', '~> 0.9'
41
+ spec.add_development_dependency 'rspec-instafail', '~> 1.0'
42
+ spec.add_development_dependency 'bundler', '>= 1.3.0'
41
43
 
42
- if RUBY_VERSION.match(/^1/)
44
+ if RUBY_VERSION.match(/^1\./)
43
45
  spec.add_development_dependency 'public_suffix', '~> 1.4.6' # Later versions do not support Ruby 1.9
44
46
  spec.add_development_dependency 'webmock', '2.2'
47
+ spec.add_development_dependency 'parallel_tests', '~> 2.9.0'
45
48
  else
46
49
  spec.add_development_dependency 'webmock', '~> 2.2'
47
50
  spec.add_development_dependency 'coveralls'
48
- spec.add_development_dependency 'pry'
49
- spec.add_development_dependency 'pry-byebug'
51
+ spec.add_development_dependency 'parallel_tests', '~> 2.22'
52
+ if !RUBY_VERSION.match(/^2\.[0123]/)
53
+ spec.add_development_dependency 'pry'
54
+ spec.add_development_dependency 'pry-byebug'
55
+ end
50
56
  end
51
57
  end
@@ -35,6 +35,28 @@ module Ably
35
35
 
36
36
  API_KEY_REGEX = /^[\w-]{2,}\.[\w-]{2,}:[\w-]{2,}$/
37
37
 
38
+ # Supported AuthOption keys, see https://www.ably.io/documentation/realtime/types#auth-options
39
+ # TODO: Review client_id usage embedded incorrectly within AuthOptions.
40
+ # This is legacy code to configure a client with a client_id from the ClientOptions
41
+ # TODO: Review inclusion of use_token_auth, ttl, token_params in auth options
42
+ AUTH_OPTIONS_KEYS = %w(
43
+ auth_callback
44
+ auth_url
45
+ auth_method
46
+ auth_headers
47
+ auth_params
48
+ client_id
49
+ key
50
+ key_name
51
+ key_secret
52
+ query_time
53
+ token
54
+ token_details
55
+ token_params
56
+ ttl
57
+ use_token_auth
58
+ )
59
+
38
60
  attr_reader :options, :token_params, :current_token_details
39
61
  alias_method :auth_options, :options
40
62
 
@@ -82,7 +104,7 @@ module Ably
82
104
 
83
105
  if has_client_id? && !token_creatable_externally? && !token_option
84
106
  raise ArgumentError, 'client_id cannot be provided without a complete API key or means to authenticate. An API key is needed to automatically authenticate with Ably and obtain a token' unless api_key_present?
85
- ensure_utf_8 :client_id, client_id
107
+ @client_id = ensure_utf_8(:client_id, client_id) if client_id
86
108
  end
87
109
 
88
110
  # If a token details object or token string is provided in the initializer
@@ -119,7 +141,7 @@ module Ably
119
141
  # token_details = client.auth.authorize
120
142
  #
121
143
  # # will use token request from block to authorize if not already authorized
122
- # token_details = client.auth.authorize {}, auth_callback: Proc.new do
144
+ # token_details = client.auth.authorize {}, auth_callback: lambda do |token_parmas|
123
145
  # # create token_request object
124
146
  # token_request
125
147
  # end
@@ -207,7 +229,7 @@ module Ably
207
229
  # client.auth.request_token ttl: 1.hour
208
230
  #
209
231
  # # token request using auth block
210
- # token_details = client.auth.request_token {}, auth_callback: Proc.new do
232
+ # token_details = client.auth.request_token {}, auth_callback: lambda do |token_params|
211
233
  # # create token_request object
212
234
  # token_request
213
235
  # end
@@ -231,7 +253,7 @@ module Ably
231
253
  auth_callback.call(token_params)
232
254
  end
233
255
  rescue StandardError => err
234
- raise Ably::Exceptions::AuthenticationFailed.new("auth_callback failed: #{err.message}", nil, nil, err, fallback_status: 500, fallback_code: 80019)
256
+ raise Ably::Exceptions::AuthenticationFailed.new("auth_callback failed: #{err.message}", nil, nil, err, fallback_status: 500, fallback_code: Ably::Exceptions::Codes::CONNECTION_NOT_ESTABLISHED_NO_TRANSPORT_HANDLE)
235
257
  end
236
258
  elsif auth_url = auth_options.delete(:auth_url)
237
259
  begin
@@ -239,7 +261,7 @@ module Ably
239
261
  token_request_from_auth_url(auth_url, auth_options, token_params)
240
262
  end
241
263
  rescue StandardError => err
242
- raise Ably::Exceptions::AuthenticationFailed.new("auth_url failed: #{err.message}", nil, nil, err, fallback_status: 500, fallback_code: 80019)
264
+ raise Ably::Exceptions::AuthenticationFailed.new("auth_url failed: #{err.message}", nil, nil, err, fallback_status: 500, fallback_code: Ably::Exceptions::Codes::CONNECTION_NOT_ESTABLISHED_NO_TRANSPORT_HANDLE)
243
265
  end
244
266
  else
245
267
  create_token_request(token_params, auth_options)
@@ -504,6 +526,10 @@ module Ably
504
526
  end
505
527
 
506
528
  def ensure_valid_auth_attributes(attributes)
529
+ (attributes.keys.map(&:to_s) - AUTH_OPTIONS_KEYS).tap do |unsupported_keys|
530
+ raise ArgumentError, "The key(s) #{unsupported_keys.map { |k| ":#{k}" }.join(', ')} are not valid AuthOptions" unless unsupported_keys.empty?
531
+ end
532
+
507
533
  if attributes[:timestamp]
508
534
  unless attributes[:timestamp].kind_of?(Time) || attributes[:timestamp].kind_of?(Numeric)
509
535
  raise ArgumentError, ':timestamp must be a Time or positive Integer value of seconds since epoch'
@@ -631,9 +657,9 @@ module Ably
631
657
  uri = URI.parse(auth_url)
632
658
  connection = Faraday.new("#{uri.scheme}://#{uri.host}", connection_options)
633
659
  method = auth_options[:auth_method] || options[:auth_method] || :get
634
- params = (auth_options[:auth_params] || options[:auth_method] || {}).merge(token_params)
660
+ params = (auth_options[:auth_params] || options[:auth_params] || {}).merge(token_params)
635
661
 
636
- response = connection.send(method) do |request|
662
+ response = connection.public_send(method) do |request|
637
663
  request.url uri.path
638
664
  request.headers = auth_options[:auth_headers] || {}
639
665
  if method.to_s.downcase == 'post'
@@ -643,7 +669,7 @@ module Ably
643
669
  end
644
670
  end
645
671
 
646
- if !response.body.kind_of?(Hash) && !response.headers['Content-Type'].to_s.match(%r{text/plain}i)
672
+ if !response.body.kind_of?(Hash) && !response.headers['Content-Type'].to_s.match(%r{text/plain|application/jwt}i)
647
673
  raise Ably::Exceptions::InvalidResponseBody,
648
674
  "Content Type #{response.headers['Content-Type']} is not supported by this client library"
649
675
  end
@@ -1,10 +1,11 @@
1
+ require 'ably/modules/exception_codes'
2
+
1
3
  module Ably
2
4
  module Exceptions
3
5
  TOKEN_EXPIRED_CODE = 40140..40149
4
- INVALID_CLIENT_ID = 40012
5
6
 
6
7
  # Base Ably exception class that contains status and code values used by Ably
7
- # Refer to https://github.com/ably/ably-common/blob/master/protocol/errors.json
8
+ # Refer to https://github.com/ably/ably-common/blob/main/protocol/errors.json
8
9
  #
9
10
  # @!attribute [r] message
10
11
  # @return [String] Error message from Ably
@@ -37,6 +38,7 @@ module Ably
37
38
  additional_info << "base exception: #{@base_exception.class}" if @base_exception
38
39
  additional_info << "request_id: #{request_id}" if request_id
39
40
  message << "(#{additional_info.join(', ')})"
41
+ message << "-> see https://help.ably.io/error/#{code} for help" if code
40
42
  end
41
43
  message.join(' ')
42
44
  end
@@ -53,6 +55,8 @@ module Ably
53
55
  # An invalid request was received by Ably
54
56
  class InvalidRequest < BaseAblyException; end
55
57
 
58
+ class InvalidCredentials < BaseAblyException; end
59
+
56
60
  # Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided
57
61
  class UnauthorizedRequest < BaseAblyException; end
58
62
 
@@ -112,7 +116,7 @@ module Ably
112
116
  class InvalidState < BaseAblyException; end
113
117
 
114
118
  # A generic Ably exception taht supports a status & code.
115
- # See https://github.com/ably/ably-common/blob/master/protocol/errors.json for a list of Ably errors
119
+ # See https://github.com/ably/ably-common/blob/main/protocol/errors.json for a list of Ably errors
116
120
  class Standard < BaseAblyException; end
117
121
 
118
122
  # The HTTP request has returned a 500 error
@@ -146,12 +150,14 @@ module Ably
146
150
  class ChannelInactive < BaseAblyException; end
147
151
 
148
152
  class IncompatibleClientId < BaseAblyException
149
- def initialize(messages, status = 400, code = INVALID_CLIENT_ID, *args)
153
+ def initialize(messages, status = 400, code = Ably::Exceptions::Codes::INVALID_CLIENT_ID, *args)
150
154
  super(message, status, code, *args)
151
155
  end
152
156
  end
153
157
 
154
158
  # Token request has missing or invalid attributes
155
159
  class InvalidTokenRequest < BaseAblyException; end
160
+
161
+ class PushNotificationsNotSupported < BaseAblyException; end
156
162
  end
157
163
  end
@@ -20,6 +20,8 @@ module Ably
20
20
  ensure_logger_interface_is_valid
21
21
 
22
22
  @logger.level = log_level
23
+
24
+ @log_mutex = Mutex.new
23
25
  end
24
26
 
25
27
  # The logger used by this class, defaults to {http://www.ruby-doc.org/stdlib-1.9.3/libdoc/logger/rdoc/Logger.html Ruby Logger}
@@ -38,7 +40,9 @@ module Ably
38
40
  %w(fatal error warn info debug).each do |method_name|
39
41
  define_method(method_name) do |*args, &block|
40
42
  begin
41
- logger.public_send(method_name, *args, &block)
43
+ log_mutex.synchronize do
44
+ logger.public_send(method_name, *args, &block)
45
+ end
42
46
  rescue StandardError => e
43
47
  logger.error "Logger: Failed to log #{method_name} block - #{e.class}: #{e.message}\n#{e.backtrace.join("\n")}"
44
48
  end
@@ -46,6 +50,8 @@ module Ably
46
50
  end
47
51
 
48
52
  private
53
+ attr_reader :log_mutex
54
+
49
55
  def client
50
56
  @client
51
57
  end
@@ -82,7 +88,7 @@ module Ably
82
88
 
83
89
  def default_logger
84
90
  ::Logger.new(STDOUT).tap do |logger|
85
- logger.formatter = proc do |severity, datetime, progname, msg|
91
+ logger.formatter = lambda do |severity, datetime, progname, msg|
86
92
  severity = ::Logger::SEV_LABEL.index(severity) if severity.kind_of?(String)
87
93
 
88
94
  formatted_date = if severity == ::Logger::DEBUG
@@ -48,7 +48,7 @@ module Ably::Models
48
48
  end
49
49
 
50
50
  def to_s
51
- "ChannelStateChange: current state #{current}, previous state #{previous}"
51
+ "<ChannelStateChange: current state #{current}, previous state #{previous}>"
52
52
  end
53
53
  end
54
54
  end
@@ -38,7 +38,7 @@ module Ably::Models
38
38
  end
39
39
 
40
40
  def to_s
41
- "ConnectionStateChange: current state #{current}, previous state #{previous}"
41
+ "<ConnectionStateChange: current state #{current}, previous state #{previous}>"
42
42
  end
43
43
  end
44
44
  end
@@ -0,0 +1,87 @@
1
+ module Ably::Modules
2
+ module Conversions
3
+ private
4
+ # Convert device_details argument to a {Ably::Models::DeviceDetails} object
5
+ #
6
+ # @param device_details [Ably::Models::DeviceDetails,Hash,nil] A device details object
7
+ #
8
+ # @return [Ably::Models::DeviceDetails]
9
+ def DeviceDetails(device_details)
10
+ case device_details
11
+ when Ably::Models::DeviceDetails
12
+ device_details
13
+ else
14
+ Ably::Models::DeviceDetails.new(device_details)
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ module Ably::Models
21
+ # An object representing a devices details, used currently for push notifications
22
+ #
23
+ # @!attribute [r] id
24
+ # @return [String] Unique device identifier assigned randomly by the device
25
+ # @!attribute [r] platform
26
+ # @return [String] Device platform such as android, ios or browser
27
+ # @!attribute [r] form_factor
28
+ # @return [String] Device form factor such as phone, tablet, watch
29
+ # @!attribute [r] client_id
30
+ # @return [String] The authenticated client identifier for this device. See {https://www.ably.io/documentation/general/authentication#identified-clients auth documentation}.
31
+ # @!attribute [r] metadata
32
+ # @return [Hash] Arbitrary metadata that can be associated with a device
33
+ # @!attribute [r] device_secret
34
+ # @return [String] This secret is used internally by Ably client libraries to authenticate with Ably when push registration updates are required such as when the GCM token expires and needs renewing
35
+ # @!attribute [r] push
36
+ # @return [DevicePushDetails] The push notification specific properties for this device allowing push notifications to be delivered to the device
37
+ #
38
+ class DeviceDetails < Ably::Exceptions::BaseAblyException
39
+ include Ably::Modules::ModelCommon
40
+
41
+ # @param hash_object [Hash,nil] Device detail attributes
42
+ #a
43
+ def initialize(hash_object = {})
44
+ @raw_hash_object = hash_object || {}
45
+ @hash_object = IdiomaticRubyWrapper(hash_object)
46
+ end
47
+
48
+ %w(id platform form_factor client_id device_secret).each do |attribute|
49
+ define_method attribute do
50
+ attributes[attribute.to_sym]
51
+ end
52
+
53
+ define_method "#{attribute}=" do |val|
54
+ unless val.nil? || val.kind_of?(String)
55
+ raise ArgumentError, "#{attribute} must be nil or a string value"
56
+ end
57
+ attributes[attribute.to_sym] = val
58
+ end
59
+ end
60
+
61
+ def metadata
62
+ attributes[:metadata] || {}
63
+ end
64
+
65
+ def metadata=(val)
66
+ unless val.nil? || val.kind_of?(Hash)
67
+ raise ArgumentError, "metadata must be nil or a Hash value"
68
+ end
69
+ attributes[:metadata] = val
70
+ end
71
+
72
+ def push
73
+ DevicePushDetails(attributes[:push] || {})
74
+ end
75
+
76
+ def push=(val)
77
+ unless val.nil? || val.kind_of?(Hash) || val.kind_of?(Ably::Models::DevicePushDetails)
78
+ raise ArgumentError, "push must be nil, a Hash value or a DevicePushDetails object"
79
+ end
80
+ attributes[:push] = DevicePushDetails(val)
81
+ end
82
+
83
+ def attributes
84
+ @hash_object
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,86 @@
1
+ module Ably::Modules
2
+ module Conversions
3
+ private
4
+ # Convert device_push_details argument to a {Ably::Models::DevicePushDetails} object
5
+ #
6
+ # @param device_push_details [Ably::Models::DevicePushDetails,Hash,nil] A device push notification details object
7
+ #
8
+ # @return [Ably::Models::DevicePushDetails]
9
+ def DevicePushDetails(device_push_details)
10
+ case device_push_details
11
+ when Ably::Models::DevicePushDetails
12
+ device_push_details
13
+ else
14
+ Ably::Models::DevicePushDetails.new(device_push_details)
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ module Ably::Models
21
+ # An object with the push notification details for {DeviceDetails} object
22
+ #
23
+ # @!attribute [r] transport_type
24
+ # @return [String] Transport type for push notifications such as gcm, apns, web
25
+ # @!attribute [r] state
26
+ # @return [String] The current state of this push target such as Active, Failing or Failed
27
+ # @!attribute [r] error_reason
28
+ # @return [ErrorInfo] If the state is Failing of Failed, this field may optionally contain a reason
29
+ # @!attribute [r] metadata
30
+ # @return [Hash] Arbitrary metadata that can be associated with this object
31
+ #
32
+ class DevicePushDetails < Ably::Exceptions::BaseAblyException
33
+ include Ably::Modules::ModelCommon
34
+
35
+ # @param hash_object [Hash,nil] Device push detail attributes
36
+ #a
37
+ def initialize(hash_object = {})
38
+ @raw_hash_object = hash_object || {}
39
+ @hash_object = IdiomaticRubyWrapper(@raw_hash_object)
40
+ end
41
+
42
+ %w(state).each do |attribute|
43
+ define_method attribute do
44
+ attributes[attribute.to_sym]
45
+ end
46
+
47
+ define_method "#{attribute}=" do |val|
48
+ unless val.nil? || val.kind_of?(String)
49
+ raise ArgumentError, "#{attribute} must be nil or a string value"
50
+ end
51
+ attributes[attribute.to_sym] = val
52
+ end
53
+ end
54
+
55
+ def recipient
56
+ attributes[:recipient] || {}
57
+ end
58
+
59
+ def recipient=(val)
60
+ unless val.nil? || val.kind_of?(Hash)
61
+ raise ArgumentError, "recipient must be nil or a Hash value"
62
+ end
63
+ attributes[:recipient] = val
64
+ end
65
+
66
+ def error_reason
67
+ attributes[:error_reason]
68
+ end
69
+
70
+ def error_reason=(val)
71
+ unless val.nil? || val.kind_of?(Hash) || val.kind_of?(Ably::Models::ErrorInfo)
72
+ raise ArgumentError, "error_reason must be nil, a Hash value or a ErrorInfo object"
73
+ end
74
+
75
+ attributes[:error_reason] = if val.nil?
76
+ nil
77
+ else
78
+ ErrorInfo(val)
79
+ end
80
+ end
81
+
82
+ def attributes
83
+ @hash_object
84
+ end
85
+ end
86
+ end
@@ -1,3 +1,22 @@
1
+ module Ably::Modules
2
+ module Conversions
3
+ private
4
+ # Convert error_details argument to a {ErrorInfo} object
5
+ #
6
+ # @param error_details [ErrorInfo,Hash] Error info attributes
7
+ #
8
+ # @return [ErrorInfo]
9
+ def ErrorInfo(error_details)
10
+ case error_details
11
+ when Ably::Models::ErrorInfo
12
+ error_details
13
+ else
14
+ Ably::Models::ErrorInfo.new(error_details)
15
+ end
16
+ end
17
+ end
18
+ end
19
+
1
20
  module Ably::Models
2
21
  # An exception type encapsulating error information containing
3
22
  # an Ably-specific error code and generic status code.
@@ -19,7 +38,7 @@ module Ably::Models
19
38
  @hash_object = IdiomaticRubyWrapper(hash_object.clone.freeze)
20
39
  end
21
40
 
22
- %w(message code status_code).each do |attribute|
41
+ %w(message code href status_code).each do |attribute|
23
42
  define_method attribute do
24
43
  attributes[attribute.to_sym]
25
44
  end
@@ -31,7 +50,9 @@ module Ably::Models
31
50
  end
32
51
 
33
52
  def to_s
34
- "Error: #{message} (code: #{code}, http status: #{status})"
53
+ error_href = href || (code ? "https://help.ably.io/error/#{code}" : '')
54
+ see_msg = " -> see #{error_href} for help" unless message.to_s.include?(error_href.to_s)
55
+ "<Error: #{message} (code: #{code}, http status: #{status})>#{see_msg}"
35
56
  end
36
57
  end
37
58
  end