rpush 2.2.0-java → 2.3.0-java

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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -0
  3. data/README.md +17 -9
  4. data/lib/generators/rpush_migration_generator.rb +1 -1
  5. data/lib/rpush.rb +4 -1
  6. data/lib/rpush/apns_feedback.rb +1 -1
  7. data/lib/rpush/cli.rb +24 -21
  8. data/lib/rpush/client/active_model/apns/app.rb +1 -1
  9. data/lib/rpush/client/active_model/apns/notification.rb +2 -2
  10. data/lib/rpush/client/active_model/wpns/notification.rb +7 -1
  11. data/lib/rpush/configuration.rb +32 -22
  12. data/lib/rpush/daemon.rb +18 -9
  13. data/lib/rpush/daemon/adm/delivery.rb +4 -1
  14. data/lib/rpush/daemon/apns/delivery.rb +3 -0
  15. data/lib/rpush/daemon/apns/feedback_receiver.rb +6 -2
  16. data/lib/rpush/daemon/app_runner.rb +11 -16
  17. data/lib/rpush/daemon/batch.rb +9 -0
  18. data/lib/rpush/daemon/delivery.rb +10 -2
  19. data/lib/rpush/daemon/delivery_error.rb +3 -3
  20. data/lib/rpush/daemon/dispatcher/apns_tcp.rb +11 -11
  21. data/lib/rpush/daemon/dispatcher/tcp.rb +2 -10
  22. data/lib/rpush/daemon/gcm/delivery.rb +13 -7
  23. data/lib/rpush/daemon/signal_handler.rb +5 -3
  24. data/lib/rpush/daemon/store/active_record.rb +14 -0
  25. data/lib/rpush/daemon/store/interface.rb +2 -1
  26. data/lib/rpush/daemon/store/redis.rb +3 -0
  27. data/lib/rpush/daemon/tcp_connection.rb +47 -17
  28. data/lib/rpush/daemon/wpns/delivery.rb +19 -10
  29. data/lib/rpush/logger.rb +30 -12
  30. data/lib/rpush/plugin.rb +44 -0
  31. data/lib/rpush/push.rb +1 -1
  32. data/lib/rpush/reflectable.rb +13 -0
  33. data/lib/rpush/{reflection.rb → reflection_collection.rb} +1 -9
  34. data/lib/rpush/reflection_public_methods.rb +9 -0
  35. data/lib/rpush/version.rb +1 -1
  36. data/lib/tasks/test.rake +6 -4
  37. data/spec/functional/adm_spec.rb +12 -0
  38. data/spec/functional/apns_spec.rb +61 -42
  39. data/spec/functional/gcm_spec.rb +9 -0
  40. data/spec/functional/retry_spec.rb +1 -1
  41. data/spec/functional/wpns_spec.rb +44 -11
  42. data/spec/spec_helper.rb +2 -0
  43. data/spec/unit/apns_feedback_spec.rb +2 -2
  44. data/spec/unit/client/active_record/apns/app_spec.rb +2 -2
  45. data/spec/unit/client/active_record/apns/notification_spec.rb +1 -2
  46. data/spec/unit/client/active_record/wpns/notification_spec.rb +9 -3
  47. data/spec/unit/configuration_spec.rb +1 -0
  48. data/spec/unit/daemon/adm/delivery_spec.rb +0 -1
  49. data/spec/unit/daemon/apns/feedback_receiver_spec.rb +0 -1
  50. data/spec/unit/daemon/app_runner_spec.rb +14 -9
  51. data/spec/unit/daemon/delivery_spec.rb +0 -1
  52. data/spec/unit/daemon/dispatcher/tcp_spec.rb +0 -7
  53. data/spec/unit/daemon/gcm/delivery_spec.rb +1 -1
  54. data/spec/unit/daemon/signal_handler_spec.rb +5 -1
  55. data/spec/unit/daemon/store/active_record_spec.rb +1 -1
  56. data/spec/unit/daemon/tcp_connection_spec.rb +18 -18
  57. data/spec/unit/daemon/wpns/delivery_spec.rb +1 -1
  58. data/spec/unit/daemon_spec.rb +10 -2
  59. data/spec/unit/logger_spec.rb +0 -1
  60. data/spec/unit/plugin_spec.rb +36 -0
  61. data/spec/unit/push_spec.rb +2 -2
  62. data/spec/unit/{daemon/reflectable_spec.rb → reflectable_spec.rb} +6 -6
  63. data/spec/unit/{reflection_spec.rb → reflection_collection_spec.rb} +4 -8
  64. metadata +34 -36
  65. data/lib/rpush/daemon/reflectable.rb +0 -11
  66. data/spec/integration/rpush_spec.rb +0 -13
  67. data/spec/integration/support/gcm_success_response.json +0 -1
  68. data/spec/support/install.sh +0 -68
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 518f5cf260390bc60e3fc71463ec9f1f774ab77e
4
- data.tar.gz: de2def70662a539c00b591cd5107da44d35b60fc
3
+ metadata.gz: 1a29805b526b4e20790e6abfde8b1f4a2e13c820
4
+ data.tar.gz: 3e4131f892b6bc9c8278670e3080e701a00b35df
5
5
  SHA512:
6
- metadata.gz: d3105561c117ba12b9c63d9dfd423db9665eac81282b64792d404f5c49d4bf6a033c0b01c29d46a84915a86ca7dedae5219feffaebfc2dd9dc3672d7406ffa6e
7
- data.tar.gz: 7a92076300c1eb790365b3c7049e403b0ea02deab720acf70c84b45e586a01582363ce49446c991e223ee3c4839250b66b2ef127a8f795878b3896d1a79aaefb
6
+ metadata.gz: d91934f23b29f4ff80bdd82efb28f86cadb534a2b464a721fae4ee2bc5b3a4929b21e6aca315880c02e5b779cc7a8acfe6bd1ac2c18de1872f94e80b62d5cd67
7
+ data.tar.gz: e34e8a465a53826bbcb40cc7e83a00bb2b2d5f00fd477fb940d3fe4101636a8094bb9947087344af1204729dc5d86e018d941f158746a0213727da4292fefd33
@@ -1,3 +1,13 @@
1
+ ## 2.3.0 (Jan 19, 2015)
2
+ * Add 'version' CLI command.
3
+ * Rpush::Wpns::Notification now supports setting the 'data' attribute.
4
+ * ActiveRecord is now directed to the configured Rpush logger (#104).
5
+ * Logs are reopened when the HUP signal is received (#95).
6
+ * Fix setting config.redis_options (#114).
7
+ * Increase frequency of TCP keepalive probes on Linux.
8
+ * APNs notifications are no longer marked as failed when a dropped connection is detected, as it's impossible to know exactly how many actually failed (if any).
9
+ * Notifications are now retried instead of being marked as failed if a TCP/HTTP connection cannot be established.
10
+
1
11
  ## 2.2.0 (Oct 7, 2014)
2
12
  * Numerous command-line fixes, sorry folks!
3
13
  * Add 'rpush push' command-line command for one-off use.
data/README.md CHANGED
@@ -61,7 +61,7 @@ app.save!
61
61
  ```ruby
62
62
  n = Rpush::Apns::Notification.new
63
63
  n.app = Rpush::Apns::App.find_by_name("ios_app")
64
- n.device_token = "..."
64
+ n.device_token = "..." # 64-character hex string
65
65
  n.alert = "hi mom!"
66
66
  n.data = { foo: :bar }
67
67
  n.save!
@@ -126,7 +126,7 @@ app.save!
126
126
  n = Rpush::Wpns::Notification.new
127
127
  n.app = Rpush::Wpns::App.find_by_name("windows_phone_app")
128
128
  n.uri = "http://..."
129
- n.alert = "..."
129
+ n.data = {title:"MyApp", body:"Hello world", param:"user_param1"}
130
130
  n.save!
131
131
  ```
132
132
 
@@ -143,16 +143,15 @@ rpush start
143
143
 
144
144
  See `rpush help` for all available commands and options.
145
145
 
146
- #### Embedded inside an existing process
146
+ #### One-off, manual
147
147
 
148
- ```ruby
149
- # Call this during startup of your application, for example, by adding it to the end of config/rpush.rb
150
- Rpush.embed
151
- ```
148
+ On the command-line:
152
149
 
153
- See [Embedding API](https://github.com/rpush/rpush/wiki/Embedding-API) for more details.
150
+ ```
151
+ rpush push
152
+ ```
154
153
 
155
- #### Manually (in a scheduler)
154
+ In your code:
156
155
 
157
156
  ```ruby
158
157
  Rpush.push
@@ -161,6 +160,15 @@ Rpush.apns_feedback
161
160
 
162
161
  See [Push API](https://github.com/rpush/rpush/wiki/Push-API) for more details.
163
162
 
163
+ #### Embedded inside an existing process
164
+
165
+ ```ruby
166
+ # Call this during startup of your application, for example, by adding it to the end of config/rpush.rb
167
+ Rpush.embed
168
+ ```
169
+
170
+ See [Embedding API](https://github.com/rpush/rpush/wiki/Embedding-API) for more details.
171
+
164
172
  ### Configuration
165
173
 
166
174
  See [Configuration](https://github.com/rpush/rpush/wiki/Configuration) for a list of options.
@@ -6,7 +6,7 @@ class RpushMigrationGenerator < Rails::Generators::Base
6
6
  @time ||= Time.now.utc
7
7
  @calls ||= -1
8
8
  @calls += 1
9
- (@time + @calls.seconds).strftime("%Y%m%d%H%M%S")
9
+ (@time + @calls.seconds).strftime('%Y%m%d%H%M%S')
10
10
  end
11
11
 
12
12
  def copy_migration
@@ -19,7 +19,10 @@ require 'rpush/deprecatable'
19
19
  require 'rpush/logger'
20
20
  require 'rpush/multi_json_helper'
21
21
  require 'rpush/configuration'
22
- require 'rpush/reflection'
22
+ require 'rpush/reflection_collection'
23
+ require 'rpush/reflection_public_methods'
24
+ require 'rpush/reflectable'
25
+ require 'rpush/plugin'
23
26
  require 'rpush/embed'
24
27
  require 'rpush/push'
25
28
  require 'rpush/apns_feedback'
@@ -1,7 +1,7 @@
1
1
  module Rpush
2
2
  def self.apns_feedback
3
3
  require 'rpush/daemon'
4
- Rpush::Daemon.initialize_store
4
+ Rpush::Daemon.common_init
5
5
 
6
6
  Rpush::Apns::App.all.each do |app|
7
7
  receiver = Rpush::Daemon::Apns::FeedbackReceiver.new(app)
@@ -1,12 +1,10 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  require 'thor'
4
- require 'term/ansicolor'
4
+ require 'ansi/code'
5
5
 
6
6
  module Rpush
7
7
  class CLI < Thor
8
- include Term::ANSIColor
9
-
10
8
  def self.detect_rails?
11
9
  ['bin/rails', 'script/rails'].any? { |path| File.exist?(path) }
12
10
  end
@@ -22,9 +20,7 @@ module Rpush
22
20
  option 'pid-file', type: :string, aliases: '-p'
23
21
  desc 'start', 'Start Rpush'
24
22
  def start
25
- underscore_option_names
26
- check_ruby_version
27
- configure_rpush
23
+ config_setup
28
24
 
29
25
  require 'rpush/daemon'
30
26
  Rpush::Daemon.start
@@ -33,9 +29,7 @@ module Rpush
33
29
  desc 'stop', 'Stop Rpush'
34
30
  option 'pid-file', type: :string, aliases: '-p'
35
31
  def stop
36
- underscore_option_names
37
- check_ruby_version
38
- configure_rpush
32
+ config_setup
39
33
  ensure_pid_file_set
40
34
 
41
35
  if File.exist?(Rpush.config.pid_file)
@@ -53,21 +47,21 @@ module Rpush
53
47
  end
54
48
  end
55
49
 
56
- puts green('✔')
50
+ puts ANSI.green { '✔' }
57
51
  else
58
52
  STDERR.puts("* Rpush isn't running? #{Rpush.config.pid_file} does not exist.")
59
53
  return
60
54
  end
61
55
  end
62
56
 
63
- desc 'init', 'Initialize Rpush into the current directory.'
57
+ desc 'init', 'Initialize Rpush into the current directory'
64
58
  option 'active-record', type: :boolean, desc: 'Install ActiveRecord migrations'
65
59
  def init
66
60
  underscore_option_names
67
61
  check_ruby_version
68
62
  require 'rails/generators'
69
63
 
70
- puts "* #{green('Installing config...')}"
64
+ puts "* " + ANSI.green { 'Installing config...' }
71
65
  $RPUSH_CONFIG_PATH = default_config_path # rubocop:disable Style/GlobalVars
72
66
  Rails::Generators.invoke('rpush_config')
73
67
 
@@ -76,7 +70,7 @@ module Rpush
76
70
  unless options.key?('active_record')
77
71
  has_answer = false
78
72
  until has_answer
79
- STDOUT.write "\n* #{green('Install ActiveRecord migrations?')} [y/n]: "
73
+ STDOUT.write "\n* #{ANSI.green { 'Install ActiveRecord migrations?' }} [y/n]: "
80
74
  STDOUT.flush
81
75
  answer = STDIN.gets.chomp.downcase
82
76
  has_answer = %w(y n).include?(answer)
@@ -87,7 +81,7 @@ module Rpush
87
81
 
88
82
  Rails::Generators.invoke('rpush_migration', ['--force']) if install_migrations
89
83
 
90
- puts "\n* #{green('Next steps:')}"
84
+ puts "\n* #{ANSI.green { 'Next steps:' }}"
91
85
  puts " - Run 'db:migrate'." if install_migrations
92
86
  puts " - Review and update your configuration in #{default_config_path}."
93
87
  puts " - Create your first app, see https://github.com/rpush/rpush for examples."
@@ -96,16 +90,25 @@ module Rpush
96
90
 
97
91
  desc 'push', 'Deliver all pending notifications and then exit'
98
92
  def push
99
- underscore_option_names
100
- check_ruby_version
101
- configure_rpush
93
+ config_setup
102
94
  Rpush.config.foreground = true
103
95
 
104
96
  Rpush.push
105
97
  end
106
98
 
99
+ desc 'version', 'Print Rpush version'
100
+ def version
101
+ puts Rpush::VERSION
102
+ end
103
+
107
104
  private
108
105
 
106
+ def config_setup
107
+ underscore_option_names
108
+ check_ruby_version
109
+ configure_rpush
110
+ end
111
+
109
112
  def configure_rpush
110
113
  load_rails_environment || load_standalone
111
114
  end
@@ -117,7 +120,7 @@ module Rpush
117
120
  ENV['RAILS_ENV'] = options['rails_env']
118
121
  load 'config/environment.rb'
119
122
  Rpush.config.update(options)
120
- puts green('✔')
123
+ puts ANSI.green { '✔' }
121
124
 
122
125
  return true
123
126
  end
@@ -127,7 +130,7 @@ module Rpush
127
130
 
128
131
  def load_standalone
129
132
  if !File.exist?(options[:config])
130
- STDERR.puts(red('ERROR: ') + "#{options[:config]} does not exist. Please run 'rpush init' to generate it or specify the --config option.")
133
+ STDERR.puts(ANSI.red { 'ERROR: ' } + "#{options[:config]} does not exist. Please run 'rpush init' to generate it or specify the --config option.")
131
134
  exit 1
132
135
  else
133
136
  load options[:config]
@@ -146,12 +149,12 @@ module Rpush
146
149
  def ensure_pid_file_set
147
150
  return unless Rpush.config.pid_file.blank?
148
151
 
149
- STDERR.puts(red('ERROR: ') + 'config.pid_file is not set.')
152
+ STDERR.puts(ANSI.red { 'ERROR: ' } + 'config.pid_file is not set.')
150
153
  exit 1
151
154
  end
152
155
 
153
156
  def check_ruby_version
154
- STDERR.puts(yellow('WARNING: ') + "You are using an old and unsupported version of Ruby.") if RUBY_VERSION <= '1.9.3' && RUBY_ENGINE == 'ruby'
157
+ STDERR.puts(ANSI.yellow { 'WARNING: ' } + "You are using an old and unsupported version of Ruby.") if RUBY_VERSION <= '1.9.3' && RUBY_ENGINE == 'ruby'
155
158
  end
156
159
 
157
160
  def underscore_option_names
@@ -25,7 +25,7 @@ module Rpush
25
25
  pkey = OpenSSL::PKey::RSA.new(certificate, password)
26
26
  result = x509 && pkey
27
27
  rescue OpenSSL::OpenSSLError
28
- errors.add :certificate, 'Certificate value must contain a certificate and a private key.'
28
+ errors.add :certificate, 'value must contain a certificate and a private key.'
29
29
  end
30
30
  end
31
31
  result
@@ -38,7 +38,7 @@ module Rpush
38
38
  self.data = (data || {}).merge(CONTENT_AVAILABLE_KEY => true)
39
39
  end
40
40
 
41
- def as_json # rubocop:disable Metrics/PerceivedComplexity
41
+ def as_json # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
42
42
  json = ActiveSupport::OrderedHash.new
43
43
 
44
44
  if data && data.key?(MDM_KEY)
@@ -64,7 +64,7 @@ module Rpush
64
64
  json
65
65
  end
66
66
 
67
- def to_binary(options = {})
67
+ def to_binary(options = {}) # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
68
68
  frame_payload = payload
69
69
  frame_id = options[:for_validation] ? 0 : id
70
70
  frame = ""
@@ -7,7 +7,13 @@ module Rpush
7
7
  base.instance_eval do
8
8
  validates :uri, presence: true
9
9
  validates :uri, format: { with: %r{https?://[\S]+} }
10
- validates :alert, presence: true
10
+ validates :data, presence: true
11
+ end
12
+ def alert=(value)
13
+ return unless value
14
+ data = self.data || {}
15
+ data['title'] = value
16
+ self.data = data
11
17
  end
12
18
  end
13
19
  end
@@ -8,37 +8,24 @@ module Rpush
8
8
  def self.configure
9
9
  if block_given?
10
10
  yield config
11
- initialize_client
11
+ config.initialize_client
12
12
  end
13
13
  end
14
14
 
15
- def self.initialize_client
16
- return if @client_initialized
17
- require "rpush/client/#{config.client}"
18
- client_module = Rpush::Client.const_get(config.client.to_s.camelize)
19
- Rpush.send(:include, client_module)
20
-
21
- [:Apns, :Gcm, :Wpns, :Adm].each do |service|
22
- Rpush.const_set(service, client_module.const_get(service))
23
- end
24
-
25
- @client_initialized = true
26
- end
15
+ CURRENT_ATTRS = [:push_poll, :feedback_poll, :embedded, :pid_file, :batch_size,
16
+ :push, :client, :logger, :log_file, :foreground, :log_level, :plugin]
17
+ DEPRECATED_ATTRS = [:log_dir]
18
+ CONFIG_ATTRS = CURRENT_ATTRS + DEPRECATED_ATTRS
27
19
 
28
- CONFIG_ATTRS = [:push_poll, :feedback_poll, :embedded, :pid_file, :batch_size,
29
- :push, :client, :logger, :log_file, :foreground, :log_level,
30
- # Deprecated
31
- :log_dir]
32
-
33
- class ConfigurationWithoutDefaults < Struct.new(*CONFIG_ATTRS)
34
- end
20
+ class ConfigurationError < StandardError; end
21
+ class ConfigurationWithoutDefaults < Struct.new(*CONFIG_ATTRS); end
35
22
 
36
23
  class Configuration < Struct.new(*CONFIG_ATTRS)
37
24
  include Deprecatable
38
25
 
39
26
  deprecated(:log_dir=, '2.3.0', 'Please use log_file instead.')
40
27
 
41
- delegate :redis_options, :redis_options=, to: :Modis
28
+ delegate :redis_options, to: '::Modis'
42
29
 
43
30
  def initialize
44
31
  super
@@ -72,19 +59,42 @@ module Rpush
72
59
  super(logger)
73
60
  end
74
61
 
62
+ def client=(client)
63
+ super
64
+ initialize_client
65
+ end
66
+
67
+ def redis_options=(options)
68
+ Modis.redis_options = options if client == :redis
69
+ end
70
+
75
71
  def set_defaults
76
72
  self.push_poll = 2
77
73
  self.feedback_poll = 60
78
74
  self.batch_size = 100
79
- self.client = :active_record
80
75
  self.logger = nil
81
76
  self.log_file = 'log/rpush.log'
82
77
  self.pid_file = 'tmp/rpush.pid'
83
78
  self.log_level = (defined?(Rails) && Rails.logger) ? Rails.logger.level : ::Logger::Severity::INFO
79
+ self.plugin = OpenStruct.new
84
80
 
85
81
  # Internal options.
86
82
  self.embedded = false
87
83
  self.push = false
88
84
  end
85
+
86
+ def initialize_client
87
+ return if @client_initialized
88
+ raise ConfigurationError, 'Rpush.config.client is not set.' unless client
89
+ require "rpush/client/#{client}"
90
+ client_module = Rpush::Client.const_get(client.to_s.camelize)
91
+ Rpush.send(:include, client_module)
92
+
93
+ [:Apns, :Gcm, :Wpns, :Adm].each do |service|
94
+ Rpush.const_set(service, client_module.const_get(service))
95
+ end
96
+
97
+ @client_initialized = true
98
+ end
89
99
  end
90
100
  end
@@ -8,7 +8,6 @@ require 'net/http/persistent'
8
8
 
9
9
  require 'rpush/daemon/errors'
10
10
  require 'rpush/daemon/constants'
11
- require 'rpush/daemon/reflectable'
12
11
  require 'rpush/daemon/loggable'
13
12
  require 'rpush/daemon/string_helpers'
14
13
  require 'rpush/daemon/interruptible_sleep'
@@ -48,17 +47,15 @@ require 'rpush/daemon/adm'
48
47
 
49
48
  module Rpush
50
49
  module Daemon
51
- extend Term::ANSIColor
52
-
53
50
  class << self
54
51
  attr_accessor :store
55
52
  end
56
53
 
57
54
  def self.start
58
55
  Process.daemon if daemonize?
59
- SignalHandler.start
60
- initialize_store
61
56
  write_pid_file
57
+ SignalHandler.start
58
+ common_init
62
59
  Synchronizer.sync
63
60
 
64
61
  # No further store connections will be made from this thread.
@@ -87,7 +84,7 @@ module Rpush
87
84
  Feeder.stop
88
85
  AppRunner.stop
89
86
  delete_pid_file
90
- puts green('✔') if Rpush.config.foreground
87
+ puts ANSI.green { '✔' } if Rpush.config.foreground
91
88
  end
92
89
  end
93
90
 
@@ -97,7 +94,14 @@ module Rpush
97
94
  @shutdown_lock
98
95
  end
99
96
 
100
- def self.initialize_store
97
+ def self.common_init
98
+ init_store
99
+ init_plugins
100
+ end
101
+
102
+ protected
103
+
104
+ def self.init_store
101
105
  return if store
102
106
  begin
103
107
  name = Rpush.config.client.to_s
@@ -110,7 +114,12 @@ module Rpush
110
114
  end
111
115
  end
112
116
 
113
- protected
117
+ def self.init_plugins
118
+ Rpush.plugins.each do |name, plugin|
119
+ plugin.init_block.call
120
+ Rpush.logger.info("[plugin:#{name}] Loaded.")
121
+ end
122
+ end
114
123
 
115
124
  def self.daemonize?
116
125
  !(Rpush.config.push || Rpush.config.foreground || Rpush.config.embedded || Rpush.jruby?)
@@ -136,7 +145,7 @@ module Rpush
136
145
  if Rpush::Daemon::AppRunner.app_ids.count == 0
137
146
  puts <<-EOS
138
147
 
139
- * #{green('Is this your first time using Rpush?')}
148
+ * #{ANSI.green { 'Is this your first time using Rpush?' }}
140
149
  You need to create an App before you can start using Rpush.
141
150
  Please refer to the documentation at https://github.com/rpush/rpush
142
151