Class: Spire::API::Session

Inherits:
Object
  • Object
show all
Includes:
Requestable
Defined in:
lib/spire/api/session.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Requestable

included

Constructor Details

#initialize(api, data) ⇒ Session

Returns a new instance of Session.



195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/spire/api/session.rb', line 195

def initialize(api, data)
  @api = api
  @client = api.client
  @schema = api.schema["session"]
  @url = data["url"]
  @capabilities = data["capabilities"]
  @resources = data["resources"]

  @channel_error_counts = {}
  @application_error_counts = {}
  @subscription_error_counts = {}
  @notification_error_counts = {}
end

Instance Attribute Details

#capabilitiesObject (readonly)

Returns the value of attribute capabilities.



193
194
195
# File 'lib/spire/api/session.rb', line 193

def capabilities
  @capabilities
end

#resourcesObject (readonly)

Returns the value of attribute resources.



193
194
195
# File 'lib/spire/api/session.rb', line 193

def resources
  @resources
end

#schemaObject (readonly)

Spire API Schema



193
# File 'lib/spire/api/session.rb', line 193

attr_reader :url, :resources, :schema, :capabilities

#urlObject (readonly)

Url of the spire.io api.



193
194
195
# File 'lib/spire/api/session.rb', line 193

def url
  @url
end

Instance Method Details

#[](name) ⇒ Channel

Returns a channel object for the named channel

Parameters:

  • name (String)

    Name of channel returned

Returns:



212
213
214
# File 'lib/spire/api/session.rb', line 212

def [](name)
  API::Channel.new(@api, channels[name] || find_or_create_channel(name))
end

#accountObject



216
217
218
# File 'lib/spire/api/session.rb', line 216

def 
  @account ||= account!
end

#account!Object



220
221
222
# File 'lib/spire/api/session.rb', line 220

def account!
  @account = API::Account.new(@api, @resources["account"]).get
end

#applicationsObject



324
325
326
# File 'lib/spire/api/session.rb', line 324

def applications
  @applications ||= applications!
end

#applications!Object



311
312
313
314
315
316
317
318
319
320
321
322
# File 'lib/spire/api/session.rb', line 311

def applications!
  response = request(:applications)
  unless response.status == 200
    raise "Error retrieving Applications (#{response.status}) #{response.body}"
  end
  applications_data = response.data
  @applications = {}
  applications_data.each do |name, properties|
    @applications[name] = API::Application.new(@api, properties)
  end
  @applications
end

#channelsObject



354
355
356
# File 'lib/spire/api/session.rb', line 354

def channels
  @channels ||= channels!
end

#channels!Object



341
342
343
344
345
346
347
348
349
350
351
352
# File 'lib/spire/api/session.rb', line 341

def channels!
  response = request(:channels)
  unless response.status == 200
    raise "Error retrieving Channels: (#{response.status}) #{response.body}"
  end
  channels_data = response.data
  @channels = {}
  channels_data.each do |name, properties|
    @channels[name] = API::Channel.new(@api, properties)
  end
  @channels
end

#create_application(name, data = {}) ⇒ Object



301
302
303
304
305
306
307
308
309
# File 'lib/spire/api/session.rb', line 301

def create_application(name, data = {})
  data[:name] = name
  response = request(:create_application, data)
  unless response.status == 201
    raise "Error creating Application (#{response.status}) #{response.body}"
  end
  properties = response.data
  applications[name] = API::Application.new(@api, properties)
end

#create_channel(name, options = {}) ⇒ Object



224
225
226
227
228
229
230
231
232
233
# File 'lib/spire/api/session.rb', line 224

def create_channel(name, options={})
  limit = options[:limit]
  ttl = options[:ttl]
  response = request(:create_channel, name, limit, ttl)
  unless response.status == 201
    raise "Error creating Channel: (#{response.status}) #{response.body}"
  end
  properties = response.data
  channels[name] = API::Channel.new(@api, properties)
end

#create_notification(options = {}) ⇒ Object



328
329
330
331
332
333
334
335
336
337
338
339
# File 'lib/spire/api/session.rb', line 328

def create_notification(options={})
  response = request(:create_notification, options)
  unless response.status == 201
    raise "Error creating Notification: (#{response.status}) #{response.body}"
  end
  data = response.data
  notification = API::Notification.new(@api, data) 
  if options[:name]
    notifications[data["name"]] = notification
  end
  notification
end

#create_subscription(subscription_name, channel_names, expiration = nil, device_token = nil, notification_name = nil, second_try = false) ⇒ Object



261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# File 'lib/spire/api/session.rb', line 261

def create_subscription(subscription_name, channel_names, expiration=nil, device_token=nil, notification_name=nil, second_try=false)
  channel_urls = channel_names.flatten.map { |name| self.channels[name].url rescue nil }
  if channel_urls.size != channel_urls.compact.size
    if !second_try
      self.channels!
      return create_subscription(subscription_name, channel_names, expiration, device_token, notification_name, true)
    else
      channel_urls = channel_urls.compact
    end
  end
  response = request(:create_subscription, {
    :name => subscription_name,
    :channel_urls => channel_urls,
    :expiration => expiration,
    :device_token => device_token,
    :notification_name => notification_name
  })

  unless response.status == 201
    raise "Error creating Subscription: (#{response.status}) #{response.body}"
  end
  data = response.data
  subscription = API::Subscription.new(@api, data)
  if subscription_name
    subscriptions[data["name"]] = subscription
  end
  subscription
end

#find_or_create_application(name) ⇒ Object

Creates an application on spire. Returns an Application object. Will retry on a 409.

Parameters:

  • Name (String)

    of the application to find/create



454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
# File 'lib/spire/api/session.rb', line 454

def find_or_create_application(name)
  @application_error_counts[name] ||= 0
  begin
    return create_application(name)
  # TODO custom error class for Conflict, which we can
  # then match here, instead of testing for error message
  rescue => error
    if error.message =~ /409/
      # Dear retry, I love you.  Affectionately, Matthew.
      if application = applications![name]
        return application
      else
        @application_error_counts[name] += 1
        retry unless @application_error_counts[name] >= RETRY_CREATION_LIMIT
      end
    else
      raise error
    end
  end
end

#find_or_create_channel(name) ⇒ Object

Creates a channel on spire. Returns a Channel object. Note that this will fail with a 409 if a channel with the same name exists.



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/spire/api/session.rb', line 237

def find_or_create_channel(name)
  @channel_error_counts[name] ||= 0

  begin
    return create_channel(name)
  # TODO custom error class for Conflict, which we can
  # then match here, instead of testing for error message
  rescue => error
    if error.message =~ /409/

      # Dear retry, I love you.  Affectionately, Matthew.
      if channel = channels![name]
        return channel
      else
        @channel_error_counts[name] += 1
        retry unless @channel_error_counts[name] >= RETRY_CREATION_LIMIT
      end

    else
      raise error
    end
  end
end

#find_or_create_notification(notification_name, mode) ⇒ Object



429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
# File 'lib/spire/api/session.rb', line 429

def find_or_create_notification(notification_name, mode)
  @notification_error_counts[notification_name] ||= 0
  begin
    return create_notification(
        :name => notification_name,
        :mode => mode
      )
  rescue => error
    if error.message =~ /409/
    
      if notification = notification![notification_name]
        return notification
      else
        @notification_error_counts[notification_name] += 1
        retry unless @notification_error_counts >= RETRY_CREATION_LIMIT
      end
    
    else
      raise error
    end
  end
end

#find_or_create_subscription(subscription_name, *channels) ⇒ Object



385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
# File 'lib/spire/api/session.rb', line 385

def find_or_create_subscription(subscription_name, *channels)
  @subscription_error_counts[subscription_name] ||= 0
  begin
    return create_subscription(subscription_name, channels)
  rescue => error
    if error.message =~ /409/

      if subscription = subscriptions![subscription_name]
        return subscription
      else
        @subscription_error_counts[subscription_name] += 1
        retry unless @subscription_error_counts >= RETRY_CREATION_LIMIT
      end

    else
      raise error
    end
  end
end

#get_application(name) ⇒ Object



290
291
292
293
294
295
296
297
298
299
# File 'lib/spire/api/session.rb', line 290

def get_application(name)
  response = request(:application_by_name, name)
  unless response.status == 200
    raise "Error finding application with name #{name}: (#{response.status}) #{response.body}"
  end
  properties = response.data[name]
  app = API::Application.new(@api, properties)
  @applications[name] = app if @applications.is_a?(Hash)
  app
end

#notification(name, mode = "development") ⇒ Object



423
424
425
426
427
# File 'lib/spire/api/session.rb', line 423

def notification(name, mode="development")
  Notification.new(@api,
    @notifications[name] || find_or_create_notification(name, ssl_cert)
  )
end

#notificationsObject



407
408
409
# File 'lib/spire/api/session.rb', line 407

def notifications
  @notifications ||= notifications!
end

#notifications!Object



411
412
413
414
415
416
417
418
419
420
421
# File 'lib/spire/api/session.rb', line 411

def notifications!
  response = request(:notifications)
  unless response.status == 200
    raise "Error retrieving Notifications: (#{response.status}) #{response.body}"
  end
  @notifications = {}
  response.data.each do |name, properties|
    @notifications[name] = API::Notification.new(@api, properties)
  end
  @notifications
end

#subscribe(name, *channels) ⇒ Subscription Also known as: subscription

Returns a subscription object for the given channels

Parameters:

  • subscription_name (String)

    Name for the subscription

  • channels (String)

    One or more channel names for the subscription to listen on

Returns:



378
379
380
381
382
383
# File 'lib/spire/api/session.rb', line 378

def subscribe(name, *channels)
  channels.each { |channel| self.find_or_create_channel(channel) }
  API::Subscription.new(@api,
    subscriptions[name] || find_or_create_subscription(name, *channels)
  )
end

#subscriptionsObject



358
359
360
# File 'lib/spire/api/session.rb', line 358

def subscriptions
  @subscriptions ||= subscriptions!
end

#subscriptions!Object



362
363
364
365
366
367
368
369
370
371
372
# File 'lib/spire/api/session.rb', line 362

def subscriptions!
  response = request(:subscriptions)
  unless response.status == 200
    raise "Error retrieving Subscriptions: (#{response.status}) #{response.body}"
  end
  @subscriptions = {}
  response.data.each do |name, properties|
    @subscriptions[name] = API::Subscription.new(@api, properties)
  end
  @subscriptions
end