ably 1.2.1 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/.rspec_parallel +3 -0
  3. data/.github/workflows/check.yml +24 -4
  4. data/.github/workflows/docs.yml +36 -0
  5. data/CHANGELOG.md +26 -0
  6. data/INTRO.md +14 -0
  7. data/ably.gemspec +1 -0
  8. data/lib/ably/auth.rb +26 -23
  9. data/lib/ably/models/auth_details.rb +9 -6
  10. data/lib/ably/models/channel_details.rb +69 -0
  11. data/lib/ably/models/channel_metrics.rb +107 -0
  12. data/lib/ably/models/channel_occupancy.rb +50 -0
  13. data/lib/ably/models/channel_options.rb +26 -3
  14. data/lib/ably/models/channel_state_change.rb +45 -15
  15. data/lib/ably/models/channel_status.rb +63 -0
  16. data/lib/ably/models/cipher_params.rb +36 -13
  17. data/lib/ably/models/connection_details.rb +91 -10
  18. data/lib/ably/models/connection_state_change.rb +54 -15
  19. data/lib/ably/models/delta_extras.rb +6 -7
  20. data/lib/ably/models/device_details.rb +60 -21
  21. data/lib/ably/models/device_push_details.rb +27 -19
  22. data/lib/ably/models/error_info.rb +59 -17
  23. data/lib/ably/models/http_paginated_response.rb +27 -5
  24. data/lib/ably/models/idiomatic_ruby_wrapper.rb +3 -2
  25. data/lib/ably/models/message.rb +64 -24
  26. data/lib/ably/models/message_encoders/base.rb +6 -0
  27. data/lib/ably/models/paginated_result.rb +29 -14
  28. data/lib/ably/models/presence_message.rb +72 -22
  29. data/lib/ably/models/protocol_message.rb +0 -4
  30. data/lib/ably/models/push_channel_subscription.rb +40 -15
  31. data/lib/ably/models/stats.rb +76 -40
  32. data/lib/ably/models/stats_types.rb +16 -40
  33. data/lib/ably/models/token_details.rb +34 -12
  34. data/lib/ably/models/token_request.rb +63 -2
  35. data/lib/ably/modules/async_wrapper.rb +1 -0
  36. data/lib/ably/modules/enum.rb +2 -0
  37. data/lib/ably/modules/event_emitter.rb +14 -1
  38. data/lib/ably/modules/model_common.rb +5 -0
  39. data/lib/ably/modules/state_emitter.rb +2 -0
  40. data/lib/ably/modules/state_machine.rb +4 -0
  41. data/lib/ably/realtime/channel/channel_properties.rb +9 -2
  42. data/lib/ably/realtime/channel/publisher.rb +2 -0
  43. data/lib/ably/realtime/channel/push_channel.rb +17 -10
  44. data/lib/ably/realtime/channel.rb +79 -42
  45. data/lib/ably/realtime/channels.rb +4 -3
  46. data/lib/ably/realtime/client/incoming_message_dispatcher.rb +6 -14
  47. data/lib/ably/realtime/client.rb +53 -32
  48. data/lib/ably/realtime/connection/connection_manager.rb +4 -0
  49. data/lib/ably/realtime/connection/websocket_transport.rb +4 -2
  50. data/lib/ably/realtime/connection.rb +94 -55
  51. data/lib/ably/realtime/presence.rb +61 -36
  52. data/lib/ably/realtime/push/admin.rb +16 -2
  53. data/lib/ably/realtime/push.rb +15 -3
  54. data/lib/ably/rest/channel/push_channel.rb +0 -3
  55. data/lib/ably/rest/channel.rb +33 -18
  56. data/lib/ably/rest/channels.rb +6 -3
  57. data/lib/ably/rest/client.rb +41 -35
  58. data/lib/ably/rest/presence.rb +27 -12
  59. data/lib/ably/rest/push/admin.rb +4 -0
  60. data/lib/ably/rest/push/device_registrations.rb +13 -2
  61. data/lib/ably/rest/push.rb +2 -0
  62. data/lib/ably/util/crypto.rb +14 -10
  63. data/lib/ably/version.rb +1 -1
  64. data/spec/acceptance/realtime/connection_spec.rb +0 -15
  65. data/spec/acceptance/realtime/message_spec.rb +3 -3
  66. data/spec/acceptance/rest/channel_spec.rb +18 -0
  67. data/spec/unit/models/channel_details_spec.rb +30 -0
  68. data/spec/unit/models/channel_metrics_spec.rb +42 -0
  69. data/spec/unit/models/channel_occupancy_spec.rb +17 -0
  70. data/spec/unit/models/channel_status_spec.rb +36 -0
  71. data/spec/unit/models/protocol_message_spec.rb +0 -26
  72. data/spec/unit/realtime/incoming_message_dispatcher_spec.rb +0 -38
  73. metadata +32 -3
@@ -11,27 +11,39 @@ module Ably
11
11
  @client = client
12
12
  end
13
13
 
14
- # Admin features for push notifications like managing devices and channel subscriptions
14
+ # A {Ably::Realtime::Push::Admin} object.
15
+ #
16
+ # @spec RSH1
17
+ #
15
18
  # @return [Ably::Realtime::Push::Admin]
19
+ #
16
20
  def admin
17
21
  @admin ||= Admin.new(self)
18
22
  end
19
23
 
20
- # Activate this device for push notifications by registering with the push transport such as GCM/APNS
24
+ # Activates the device for push notifications with FCM or APNS, obtaining a unique identifier from them.
25
+ # Subsequently registers the device with Ably and stores the deviceIdentityToken in local storage.
26
+ #
27
+ # @spec RSH2a
21
28
  #
22
29
  # @note This is unsupported in the Ruby library
30
+ #
23
31
  def activate(*arg)
24
32
  raise_unsupported
25
33
  end
26
34
 
27
- # Deactivate this device for push notifications by removing the registration with the push transport such as GCM/APNS
35
+ # Deactivates the device from receiving push notifications with Ably and FCM or APNS.
36
+ #
37
+ # @spec RSH2b
28
38
  #
29
39
  # @note This is unsupported in the Ruby library
40
+ #
30
41
  def deactivate(*arg)
31
42
  raise_unsupported
32
43
  end
33
44
 
34
45
  private
46
+
35
47
  def raise_unsupported
36
48
  raise Ably::Exceptions::PushNotificationsNotSupported, 'This device does not support receiving or subscribing to push notifications. All PushChannel methods are unavailable'
37
49
  end
@@ -3,9 +3,6 @@ module Ably::Rest
3
3
  # A push channel used for push notifications
4
4
  # Each PushChannel maps to exactly one Rest Channel
5
5
  #
6
- # @!attribute [r] channel
7
- # @return [Ably::Rest::Channel] Underlying channel object
8
- #
9
6
  class PushChannel
10
7
  attr_reader :channel
11
8
 
@@ -1,12 +1,7 @@
1
1
  module Ably
2
2
  module Rest
3
- # The Ably Realtime service organises the traffic within any application into named channels.
4
- # Channels are the "unit" of message distribution; clients attach to channels to subscribe to messages, and every message broadcast by the service is associated with a unique channel.
3
+ # Enables messages to be published and historic messages to be retrieved for a channel.
5
4
  #
6
- # @!attribute [r] name
7
- # @return {String} channel name
8
- # @!attribute [r] options
9
- # @return {Hash} channel options configured for this channel, see {#initialize} for channel_options
10
5
  class Channel
11
6
  include Ably::Modules::Conversions
12
7
 
@@ -15,9 +10,14 @@ module Ably
15
10
  # @api private
16
11
  attr_reader :client
17
12
 
18
- attr_reader :name, :options
13
+ # The channel name.
14
+ # @return [String]
15
+ attr_reader :name
19
16
 
20
- # Push channel used for push notification (client-side)
17
+ attr_reader :options
18
+
19
+ # A {Ably::Rest::Channel::PushChannel} object
20
+ # @spec RSH4
21
21
  # @return [Ably::Rest::Channel::PushChannel]
22
22
  # @api private
23
23
  attr_reader :push
@@ -39,7 +39,10 @@ module Ably
39
39
  @push = PushChannel.new(self)
40
40
  end
41
41
 
42
- # Publish one or more messages to the channel. Five overloaded forms
42
+ # Publishes a message to the channel. A callback may optionally be passed in to this call to be notified of success or failure of the operation.
43
+ #
44
+ # @spec RSL1
45
+ #
43
46
  # @param name [String, Array<Ably::Models::Message|Hash>, Ably::Models::Message, nil] The event name of the message to publish, or an Array of [Ably::Model::Message] objects or [Hash] objects with +:name+ and +:data+ pairs, or a single Ably::Model::Message object
44
47
  # @param data [String, Array, Hash, nil] The message payload unless an Array of [Ably::Model::Message] objects passed in the first argument, in which case an optional hash of query parameters
45
48
  # @param attributes [Hash, nil] Optional additional message attributes such as :extras, :id, :client_id or :connection_id, applied when name attribute is nil or a string (Deprecated, will be removed in 2.0 in favour of constructing a Message object)
@@ -112,15 +115,19 @@ module Ably
112
115
  [201, 204].include?(response.status)
113
116
  end
114
117
 
115
- # Return the message of the channel
118
+ # Retrieves a {Ably::Models::PaginatedResult} object, containing an array of historical {Ably::Models::Message}
119
+ # objects for the channel. If the channel is configured to persist messages, then messages can be retrieved from
120
+ # history for up to 72 hours in the past. If not, messages can only be retrieved from history for up to two minutes in the past.
121
+ #
122
+ # @spec RSL2a
116
123
  #
117
124
  # @param [Hash] options the options for the message history request
118
- # @option options [Integer,Time] :start Ensure earliest time or millisecond since epoch for any messages retrieved is +:start+
119
- # @option options [Integer,Time] :end Ensure latest time or millisecond since epoch for any messages retrieved is +:end+
120
- # @option options [Symbol] :direction +:forwards+ or +:backwards+, defaults to +:backwards+
121
- # @option options [Integer] :limit Maximum number of messages to retrieve up to 1,000, defaults to 100
125
+ # @option options [Integer,Time] :start The time from which messages are retrieved, specified as milliseconds since the Unix epoch. RSL2b1
126
+ # @option options [Integer,Time] :end The time until messages are retrieved, specified as milliseconds since the Unix epoch. RSL2b1
127
+ # @option options [Symbol] :direction The order for which messages are returned in. Valid values are backwards which orders messages from most recent to oldest, or forwards which orders messages from oldest to most recent. The default is backwards. RSL2b2
128
+ # @option options [Integer] :limit An upper limit on the number of messages returned. The default is 100, and the maximum is 1000. RSL2b3
122
129
  #
123
- # @return [Ably::Models::PaginatedResult<Ably::Models::Message>] First {Ably::Models::PaginatedResult page} of {Ably::Models::Message} objects accessible with {Ably::Models::PaginatedResult#items #items}.
130
+ # @return [Ably::Models::PaginatedResult<Ably::Models::Message>] A {Ably::Models::PaginatedResult} object containing an array of {Ably::Models::Message} objects.
124
131
  #
125
132
  def history(options = {})
126
133
  url = "#{base_path}/messages"
@@ -146,14 +153,15 @@ module Ably
146
153
  end
147
154
  end
148
155
 
149
- # Return the {Ably::Rest::Presence} object
150
- #
156
+ # A {Ably::Rest::Presence} object.
157
+ # @spec RSL3
151
158
  # @return [Ably::Rest::Presence]
152
159
  def presence
153
160
  @presence ||= Presence.new(client, self)
154
161
  end
155
162
 
156
- # Sets or updates the stored channel options. (#RSL7)
163
+ # Sets the {Ably::Models::ChannelOptions} for the channel.
164
+ # @spec RSL7
157
165
  # @param channel_options [Hash, Ably::Models::ChannelOptions] A hash of options or a {Ably::Models::ChannelOptions}
158
166
  # @return [Ably::Models::ChannelOptions]
159
167
  def set_options(channel_options)
@@ -161,6 +169,13 @@ module Ably
161
169
  end
162
170
  alias options= set_options
163
171
 
172
+ # Retrieves a {Ably::Models::ChannelDetails} object for the channel, which includes status and occupancy metrics.
173
+ # @spec RSL8
174
+ # @return [Ably::Models::ChannelDetails] A {Ably::Models::ChannelDetails} object.
175
+ def status
176
+ Ably::Models::ChannelDetails.new(client.get(base_path).body)
177
+ end
178
+
164
179
  private
165
180
 
166
181
  def base_path
@@ -8,24 +8,26 @@ module Ably
8
8
  super client, Ably::Rest::Channel
9
9
  end
10
10
 
11
- # @!method get(name, channel_options = {})
12
11
  # Return a {Ably::Rest::Channel} for the given name
13
12
  #
14
13
  # @param name [String] The name of the channel
15
14
  # @param channel_options [Hash] Channel options, currently reserved for Encryption options
16
- # @return [Ably::Rest::Channel}
15
+ #
16
+ # @return [Ably::Rest::Channel]
17
+ #
17
18
  def get(*args)
18
19
  super
19
20
  end
20
21
 
21
- # @!method fetch(name, &missing_block)
22
22
  # Return a {Ably::Rest::Channel} for the given name if it exists, else the block will be called.
23
23
  # This method is intentionally similar to {http://ruby-doc.org/core-2.1.3/Hash.html#method-i-fetch Hash#fetch} providing a simple way to check if a channel exists or not without creating one
24
24
  #
25
25
  # @param name [String] The name of the channel
26
26
  # @yield [options] (optional) if a missing_block is passed to this method and no channel exists matching the name, this block is called
27
27
  # @yieldparam [String] name of the missing channel
28
+ #
28
29
  # @return [Ably::Rest::Channel]
30
+ #
29
31
  def fetch(*args)
30
32
  super
31
33
  end
@@ -36,6 +38,7 @@ module Ably
36
38
  # {Ably::Rest::Channel} object. Explicitly release channels to free up resources if required
37
39
  #
38
40
  # @return [void]
41
+ #
39
42
  def release(*args)
40
43
  super
41
44
  end
@@ -10,12 +10,7 @@ require 'ably/rest/middleware/exceptions'
10
10
 
11
11
  module Ably
12
12
  module Rest
13
- # Client for the Ably REST API
14
- #
15
- # @!attribute [r] client_id
16
- # @return [String] A client ID, used for identifying this client for presence purposes
17
- # @!attribute [r] auth_options
18
- # @return [Hash] {Ably::Auth} options configured for this client
13
+ # A client that offers a simple stateless API to interact directly with Ably's REST API.
19
14
  #
20
15
  class Client
21
16
  include Ably::Modules::Conversions
@@ -59,11 +54,13 @@ module Ably
59
54
  # @return [String]
60
55
  attr_reader :agent
61
56
 
62
- # {Ably::Auth} authentication object configured for this connection
57
+ # An {Ably::Auth} object.
58
+ # @spec RSC5
63
59
  # @return [Ably::Auth]
64
60
  attr_reader :auth
65
61
 
66
- # The collection of {Ably::Rest::Channel}s that have been created
62
+ # A {Ably::Rest::Channels} object.
63
+ # @spec RSN1
67
64
  # @return [Aby::Rest::Channels]
68
65
  attr_reader :channels
69
66
 
@@ -127,9 +124,11 @@ module Ably
127
124
  # @return [Integer]
128
125
  attr_reader :max_frame_size
129
126
 
130
- # Creates a {Ably::Rest::Client Rest Client} and configures the {Ably::Auth} object for the connection.
127
+ # Constructs a {Ably::Rest::Client} object using an Ably API key or token string.
128
+ #
129
+ # @spec RSC1
131
130
  #
132
- # @param [Hash,String] options an options Hash used to configure the client and the authentication, or String with an API key or Token ID
131
+ # @param [Hash,String] options an options Hash or String used to configure the client and the authentication, or String with an API key or Token ID
133
132
  # @option options [Boolean] :tls (true) When false, TLS is disabled. Please note Basic Auth is disallowed without TLS as secrets cannot be transmitted over unsecured connections.
134
133
  # @option options [String] :key API key comprising the key name and key secret in a single string
135
134
  # @option options [String] :token Token string or {Models::TokenDetails} used to authenticate requests
@@ -167,10 +166,10 @@ module Ably
167
166
  # @return [Ably::Rest::Client]
168
167
  #
169
168
  # @example
170
- # # create a new client authenticating with basic auth
169
+ # # Create a new client authenticating with basic auth using a String object
171
170
  # client = Ably::Rest::Client.new('key.id:secret')
172
171
  #
173
- # # create a new client and configure a client ID used for presence
172
+ # # Construct a RestClient object using a Hash object.
174
173
  # client = Ably::Rest::Client.new(key: 'key.id:secret', client_id: 'john')
175
174
  #
176
175
  def initialize(options)
@@ -275,16 +274,18 @@ module Ably
275
274
  channels.get(name, channel_options)
276
275
  end
277
276
 
278
- # Retrieve the Stats for the application
277
+ # Queries the REST /stats API and retrieves your application's usage statistics. Returns a {Ably::Models::PaginatedResult} object, containing an array of {Ably::Models::Stats} objects. See the Stats docs.
278
+ #
279
+ # @spec RSC6a, RSC6b1, RSC6b2, RSC6b3, RSC6b4
279
280
  #
280
281
  # @param [Hash] options the options for the stats request
281
- # @option options [Integer,Time] :start Ensure earliest time or millisecond since epoch for any stats retrieved is +:start+
282
- # @option options [Integer,Time] :end Ensure latest time or millisecond since epoch for any stats retrieved is +:end+
283
- # @option options [Symbol] :direction +:forwards+ or +:backwards+, defaults to +:backwards+
284
- # @option options [Integer] :limit Maximum number of messages to retrieve up to 1,000, defaults to 100
285
- # @option options [Symbol] :unit `:minute`, `:hour`, `:day` or `:month`. Defaults to `:minute`
282
+ # @option options [Integer,Time] :start The time from which stats are retrieved, specified as milliseconds since the Unix epoch. RSC6b1
283
+ # @option options [Integer,Time] :end The time until stats are retrieved, specified as milliseconds since the Unix epoch. RSC6b1
284
+ # @option options [Symbol] :direction The order for which stats are returned in. Valid values are backwards which orders stats from most recent to oldest, or forwards which orders stats from oldest to most recent. The default is backwards. RSC6b2
285
+ # @option options [Integer] :limit An upper limit on the number of stats returned. The default is 100, and the maximum is 1000. RSC6b3
286
+ # @option options [Symbol] :unit minute, hour, day or month. Based on the unit selected, the given start or end times are rounded down to the start of the relevant interval depending on the unit granularity of the query. RSC6b4
286
287
  #
287
- # @return [Ably::Models::PaginatedResult<Ably::Models::Stats>] An Array of Stats
288
+ # @return [Ably::Models::PaginatedResult<Ably::Models::Stats>] A {Ably::Models::PaginatedResult} object containing an array of {Ably::Models::Stats} objects.
288
289
  #
289
290
  def stats(options = {})
290
291
  options = {
@@ -306,9 +307,13 @@ module Ably
306
307
  Ably::Models::PaginatedResult.new(response, url, self, paginated_options)
307
308
  end
308
309
 
309
- # Retrieve the Ably service time
310
+ # Retrieves the time from the Ably service as milliseconds since the Unix epoch. Clients that do not have access
311
+ # to a sufficiently well maintained time source and wish to issue Ably {Ably::Models::TokenRequest} with
312
+ # a more accurate timestamp should use the {Ably::Rest::Client#queryTime} property instead of this method.
310
313
  #
311
- # @return [Time] The time as reported by the Ably service
314
+ # @spec RSC16
315
+ #
316
+ # @return [Time] The time as milliseconds since the Unix epoch.
312
317
  def time
313
318
  response = get('/time', {}, send_auth_header: false)
314
319
 
@@ -357,20 +362,19 @@ module Ably
357
362
  raw_request(:delete, path, params, options)
358
363
  end
359
364
 
360
- # Perform an HTTP request to the Ably API
361
- # This is a convenience for customers who wish to use bleeding edge REST API functionality
362
- # that is either not documented or is not included in the API for our client libraries.
363
- # The REST client library provides a function to issue HTTP requests to the Ably endpoints
364
- # with all the built in functionality of the library such as authentication, paging,
365
- # fallback hosts, MsgPack and JSON support etc.
365
+ # Makes a REST request to a provided path. This is provided as a convenience for developers who wish to use REST API
366
+ # functionality that is either not documented or is not yet included in the public API, without having to directly
367
+ # handle features such as authentication, paging, fallback hosts, MsgPack and JSON support.
368
+ #
369
+ # @spec RSC19
366
370
  #
367
- # @param method [Symbol] The HTTP method symbol such as +:get+, +:post+, +:put+
368
- # @param path [String] The path of the URL such +/channel/foo/publish+
369
- # @param params [Hash, nil] Optional querystring params
370
- # @param body [Hash, nil] Optional body for the POST or PUT request, must be nil or a JSON-like object
371
- # @param headers [Hash, nil] Optional additional headers
371
+ # @param method [Symbol] The request method to use, such as :get, :post.
372
+ # @param path [String] The request path.
373
+ # @param params [Hash, nil] The parameters to include in the URL query of the request. The parameters depend on the endpoint being queried. See the REST API reference for the available parameters of each endpoint.
374
+ # @param body [Hash, nil] The JSON body of the request.
375
+ # @param headers [Hash, nil] Additional HTTP headers to include in the request.
372
376
  #
373
- # @return [Ably::Models::HttpPaginatedResponse<>]
377
+ # @return [Ably::Models::HttpPaginatedResponse<>] An {Ably::Models::HttpPaginatedResponse} object returned by the HTTP request, containing an empty or JSON-encodable object.
374
378
  def request(method, path, params = {}, body = nil, headers = {}, options = {})
375
379
  raise "Method #{method.to_s.upcase} not supported" unless %i(get put patch post delete).include?(method.to_sym)
376
380
 
@@ -408,7 +412,8 @@ module Ably
408
412
  Models::HttpPaginatedResponse.new(response, path, self)
409
413
  end
410
414
 
411
- # The local device detilas
415
+ # Retrieves an object that represents the current state of the device as a target for push notifications.
416
+ # @spec RSH8
412
417
  # @return [Ably::Models::LocalDevice]
413
418
  #
414
419
  # @note This is unsupported in the Ruby library
@@ -416,7 +421,8 @@ module Ably
416
421
  raise Ably::Exceptions::PushNotificationsNotSupported, 'This device does not support receiving or subscribing to push notifications. The local device object is not unavailable'
417
422
  end
418
423
 
419
- # Push notification object for publishing and managing push notifications
424
+ # A {Ably::Rest::Push} object.
425
+ # @spec RSH7
420
426
  # @return [Ably::Rest::Push]
421
427
  def push
422
428
  @push ||= Push.new(self)
@@ -1,34 +1,45 @@
1
1
  module Ably
2
2
  module Rest
3
+ # Enables the retrieval of the current and historic presence set for a channel.
4
+ #
3
5
  class Presence
4
6
  include Ably::Modules::Conversions
5
7
 
6
8
  # {Ably::Rest::Client} for this Presence object
9
+ #
7
10
  # @return {Ably::Rest::Client}
11
+ #
8
12
  # @private
9
13
  attr_reader :client
10
14
 
11
15
  # {Ably::Rest::Channel} this Presence object is associated with
12
- # @return {Ably::Rest::Channel}
16
+ #
17
+ # @return [Ably::Rest::Channel]
18
+ #
13
19
  attr_reader :channel
14
20
 
15
21
  # Initialize a new Presence object
16
22
  #
17
23
  # @param client [Ably::Rest::Client]
18
24
  # @param channel [Channel] The channel object
25
+ #
19
26
  def initialize(client, channel)
20
27
  @client = client
21
28
  @channel = channel
22
29
  end
23
30
 
24
- # Obtain the set of members currently present for a channel
31
+ # Retrieves the current members present on the channel and the metadata for each member, such as their
32
+ # {Ably::Models::PresenceMessage::ACTION} and ID. Returns a {Ably::Models::PaginatedResult} object,
33
+ # containing an array of {Ably::Models::PresenceMessage} objects.
34
+ #
35
+ # @spec RSPa, RSP3a, RSP3a2, RSP3a3
25
36
  #
26
37
  # @param [Hash] options the options for the set of members present
27
- # @option options [Integer] :limit Maximum number of members to retrieve up to 1,000, defaults to 100
28
- # @option options [String] :client_id optional client_id filter for the member
29
- # @option options [String] :connection_id optional connection_id filter for the member
38
+ # @option options [Integer] :limit An upper limit on the number of messages returned. The default is 100, and the maximum is 1000. (RSP3a)
39
+ # @option options [String] :client_id Filters the list of returned presence members by a specific client using its ID. (RSP3a2)
40
+ # @option options [String] :connection_id Filters the list of returned presence members by a specific connection using its ID. (RSP3a3)
30
41
  #
31
- # @return [Ably::Models::PaginatedResult<Ably::Models::PresenceMessage>] First {Ably::Models::PaginatedResult page} of {Ably::Models::PresenceMessage} objects accessible with {Ably::Models::PaginatedResult#items #items}.
42
+ # @return [Ably::Models::PaginatedResult<Ably::Models::PresenceMessage>] A {Ably::Models::PaginatedResult} object containing an array of {Ably::Models::PresenceMessage} objects.
32
43
  #
33
44
  def get(options = {})
34
45
  options = options = {
@@ -49,15 +60,19 @@ module Ably
49
60
  end
50
61
  end
51
62
 
52
- # Return the presence messages history for the channel
63
+ # Retrieves a {Ably::Models::PaginatedResult} object, containing an array of historical {Ably::Models::PresenceMessage}
64
+ # objects for the channel. If the channel is configured to persist messages, then presence messages can be retrieved
65
+ # from history for up to 72 hours in the past. If not, presence messages can only be retrieved from history for up to two minutes in the past.
66
+ #
67
+ # @spec RSP4a
53
68
  #
54
69
  # @param [Hash] options the options for the message history request
55
- # @option options [Integer,Time] :start Ensure earliest time or millisecond since epoch for any presence messages retrieved is +:start+
56
- # @option options [Integer,Time] :end Ensure latest time or millisecond since epoch for any presence messages retrieved is +:end+
57
- # @option options [Symbol] :direction +:forwards+ or +:backwards+, defaults to +:backwards+
58
- # @option options [Integer] :limit Maximum number of messages to retrieve up to 1,000, defaults to 100
70
+ # @option options [Integer,Time] :start The time from which messages are retrieved, specified as milliseconds since the Unix epoch. (RSP4b1)
71
+ # @option options [Integer,Time] :end The time until messages are retrieved, specified as milliseconds since the Unix epoch. (RSP4b1)
72
+ # @option options [Symbol] :direction The order for which messages are returned in. Valid values are backwards which orders messages from most recent to oldest, or forwards which orders messages from oldest to most recent. The default is backwards. (RSP4b2)
73
+ # @option options [Integer] :limit An upper limit on the number of messages returned. The default is 100, and the maximum is 1000. (RSP4b3)
59
74
  #
60
- # @return [Ably::Models::PaginatedResult<Ably::Models::PresenceMessage>] First {Ably::Models::PaginatedResult page} of {Ably::Models::PresenceMessage} objects accessible with {Ably::Models::PaginatedResult#items #items}.
75
+ # @return [Ably::Models::PaginatedResult<Ably::Models::PresenceMessage>] A {Ably::Models::PaginatedResult} object containing an array of {Ably::Models::PresenceMessage} objects.
61
76
  #
62
77
  def history(options = {})
63
78
  url = "#{base_path}/history"
@@ -39,13 +39,17 @@ module Ably::Rest
39
39
  end
40
40
 
41
41
  # Manage device registrations
42
+ #
42
43
  # @return [Ably::Rest::Push::DeviceRegistrations]
44
+ #
43
45
  def device_registrations
44
46
  @device_registrations ||= DeviceRegistrations.new(self)
45
47
  end
46
48
 
47
49
  # Manage channel subscriptions for devices or clients
50
+ #
48
51
  # @return [Ably::Rest::Push::ChannelSubscriptions]
52
+ #
49
53
  def channel_subscriptions
50
54
  @channel_subscriptions ||= ChannelSubscriptions.new(self)
51
55
  end
@@ -17,6 +17,8 @@ module Ably::Rest
17
17
 
18
18
  # Get registered device by device ID
19
19
  #
20
+ # @spec RSH1b1
21
+ #
20
22
  # @param [String, Ably::Models::DeviceDetails] device_id the device to retrieve
21
23
  #
22
24
  # @return [Ably::Models::DeviceDetails] Returns {Ably::Models::DeviceDetails} if a match is found else a {Ably::Exceptions::ResourceMissing} is raised
@@ -30,6 +32,8 @@ module Ably::Rest
30
32
 
31
33
  # List registered devices filtered by optional params
32
34
  #
35
+ # @spec RSH1b2
36
+ #
33
37
  # @param [Hash] params the filter options for the list registered device request
34
38
  # @option params [String] :client_id filter by devices registered to a client identifier. Cannot be used with +device_id+ param
35
39
  # @option params [String] :device_id filter by unique device ID. Cannot be used with +client_id+ param
@@ -54,7 +58,10 @@ module Ably::Rest
54
58
  Ably::Models::PaginatedResult.new(response, '', client, paginated_options)
55
59
  end
56
60
 
57
- # Save and register device
61
+ # Registers or updates a {Ably::Models::DeviceDetails} object with Ably.
62
+ # Returns the new, or updated {Ably::Models::DeviceDetails} object.
63
+ #
64
+ # @spec RSH1b3
58
65
  #
59
66
  # @param [Ably::Models::DeviceDetails, Hash] device the device details to save
60
67
  #
@@ -69,6 +76,8 @@ module Ably::Rest
69
76
 
70
77
  # Remove device
71
78
  #
79
+ # @spec RSH1b4
80
+ #
72
81
  # @param [String, Ably::Models::DeviceDetails] device_id the device to remove
73
82
  #
74
83
  # @return [void]
@@ -80,7 +89,9 @@ module Ably::Rest
80
89
  client.delete("/push/deviceRegistrations/#{device_id}", {})
81
90
  end
82
91
 
83
- # Remove device matching where params
92
+ # Removes all devices registered to receive push notifications from Ably matching the filter params provided.
93
+ #
94
+ # @spec RSH1b5
84
95
  #
85
96
  # @param [Hash] params the filter params for the remove request
86
97
  # @option params [String] :client_id remove devices registered to a client identifier. Cannot be used with +device_id+ param
@@ -14,7 +14,9 @@ module Ably
14
14
  end
15
15
 
16
16
  # Admin features for push notifications like managing devices and channel subscriptions
17
+ #
17
18
  # @return [Ably::Rest::Push::Admin]
19
+ #
18
20
  def admin
19
21
  @admin ||= Admin.new(self)
20
22
  end
@@ -2,6 +2,8 @@ require 'msgpack'
2
2
  require 'openssl'
3
3
 
4
4
  module Ably::Util
5
+ # Contains the properties required to configure the encryption of {Ably::Models::Message} payloads.
6
+ #
5
7
  class Crypto
6
8
  DEFAULTS = {
7
9
  algorithm: 'aes',
@@ -14,6 +16,7 @@ module Ably::Util
14
16
  # Configured {Ably::Models::CipherParams} for this Crypto object, see {#initialize} for a list of configureable options
15
17
  #
16
18
  # @return [Ably::Models::CipherParams]
19
+ #
17
20
  attr_reader :cipher_params
18
21
 
19
22
  # Creates a {Ably::Util::Crypto} object
@@ -34,13 +37,12 @@ module Ably::Util
34
37
  @cipher_params = Ably::Models::CipherParams(params)
35
38
  end
36
39
 
37
- # Obtain a default {Ably::Models::CipherParams}. This uses default algorithm, mode and
38
- # padding and key length. An IV is generated using the default
39
- # system SecureRandom; the key may be obtained from the returned {Ably::Models::CipherParams}
40
- # for out-of-band distribution to other clients.
41
-
40
+ # Returns a {Ably::Models::CipherParams} object, using the default values for any fields not supplied by the `Hash` object.
41
+ #
42
+ # @spec RSE1, RSE1b, RSE1b
43
+ #
42
44
  # @param [Hash] params a Hash used to configure the Crypto library's {Ably::Models::CipherParams}
43
- # @option params (see Ably::Models::CipherParams#initialize)
45
+ # @option params (see {Ably::Models::CipherParams#initialize})
44
46
  #
45
47
  # @return [Ably::Models::CipherParams] Configured cipher params with :key, :algorithm, :mode, :key_length attributes
46
48
  #
@@ -48,11 +50,13 @@ module Ably::Util
48
50
  Ably::Models::CipherParams(params)
49
51
  end
50
52
 
51
- # Generate a random encryption key from the supplied keylength (or the
52
- # default key_length of 256 if none supplied)
53
+ # Generates a random key to be used in the encryption of the channel. If the language cryptographic randomness
54
+ # primitives are blocking or async, a callback is used. The callback returns a generated binary key.
55
+ #
56
+ # @spec RSE2, RSE2a, RSE2b
53
57
  #
54
- # @param [Integer] key_length Optional (default 256) key length for the generated random key. 128 and 256 bit key lengths are supported
55
- # @return Binary String (byte array) with ASCII_8BIT encoding
58
+ # @param [Integer] key_length The length of the key, in bits, to be generated. If not specified, this is equal to the default keyLength of the default algorithm: for AES this is 256 bits.
59
+ # @return Binary The key as a binary, for example, a byte array.
56
60
  #
57
61
  def self.generate_random_key(key_length = DEFAULTS.fetch(:key_length))
58
62
  params = DEFAULTS.merge(key_length: key_length)
data/lib/ably/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Ably
2
- VERSION = '1.2.1'
2
+ VERSION = '1.2.3'
3
3
  PROTOCOL_VERSION = '1.2'
4
4
 
5
5
  # @api private
@@ -1620,21 +1620,6 @@ describe Ably::Realtime::Connection, :event_machine do
1620
1620
  end
1621
1621
  end
1622
1622
 
1623
- context 'with invalid formatted value sent to server' do
1624
- let(:client_options) { default_options.merge(recover: 'not-a-valid-connection-key:1:0', log_level: :none) }
1625
-
1626
- it 'sets the #error_reason and moves the connection to FAILED' do
1627
- connection.once(:failed) do |state_change|
1628
- expect(connection.state).to eq(:failed)
1629
- expect(state_change.reason.message).to match(/Invalid connectionKey/i)
1630
- expect(connection.error_reason.message).to match(/Invalid connectionKey/i)
1631
- expect(connection.error_reason.code).to eql(80018)
1632
- expect(connection.error_reason).to eql(state_change.reason)
1633
- stop_reactor
1634
- end
1635
- end
1636
- end
1637
-
1638
1623
  context 'with expired (missing) value sent to server' do
1639
1624
  let(:client_options) { default_options.merge(recover: 'wVIsgTHAB1UvXh7z-1991d8586:0:0', log_level: :fatal) }
1640
1625
 
@@ -523,7 +523,7 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
523
523
 
524
524
  resources_root = File.expand_path('../../../../lib/submodules/ably-common/test-resources', __FILE__)
525
525
 
526
- def self.add_tests_for_data(data)
526
+ shared_examples 'add_tests_for_data' do |data|
527
527
  data['items'].each_with_index do |item, index|
528
528
  context "item #{index} with encrypted encoding #{item['encrypted']['encoding']}" do
529
529
  it_behaves_like 'an Ably encrypter and decrypter', item, data
@@ -533,12 +533,12 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
533
533
 
534
534
  context 'with AES-128-CBC using crypto-data-128.json fixtures (#RTL7d)' do
535
535
  data = JSON.parse(File.read(File.join(resources_root, 'crypto-data-128.json')))
536
- add_tests_for_data data
536
+ include_examples 'add_tests_for_data', data
537
537
  end
538
538
 
539
539
  context 'with AES-256-CBC using crypto-data-256.json fixtures (#RTL7d)' do
540
540
  data = JSON.parse(File.read(File.join(resources_root, 'crypto-data-256.json')))
541
- add_tests_for_data data
541
+ include_examples 'add_tests_for_data', data
542
542
  end
543
543
 
544
544
  context 'with multiple sends from one client to another' do
@@ -595,5 +595,23 @@ describe Ably::Rest::Channel do
595
595
  expect(channel.presence).to be_a(Ably::Rest::Presence)
596
596
  end
597
597
  end
598
+
599
+ context '#status' do
600
+ let(:channel_name) { "persisted:#{random_str(4)}" }
601
+ let(:channel) { client.channel(channel_name) }
602
+ let(:channel_details) { channel.status }
603
+
604
+ it 'should return channel details status (#RSL8, #RSL8a)' do
605
+ expect(channel_details.channel_id).to eq(channel_name)
606
+ expect(channel_details.name).to eq(channel_name)
607
+ expect(channel_details.status).to be_a(Ably::Models::ChannelStatus)
608
+ expect(channel_details.status.is_active).to eq(true)
609
+ expect(channel_details.status.occupancy.metrics.publishers).to eq(0)
610
+ expect(channel_details.status.occupancy.metrics.subscribers).to eq(0)
611
+ expect(channel_details.status.occupancy.metrics.presence_connections).to eq(0)
612
+ expect(channel_details.status.occupancy.metrics.presence_members).to eq(0)
613
+ expect(channel_details.status.occupancy.metrics.presence_subscribers).to eq(0)
614
+ end
615
+ end
598
616
  end
599
617
  end