rpush_extended 3.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (248) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +365 -0
  3. data/LICENSE +7 -0
  4. data/README.md +393 -0
  5. data/bin/rpush +4 -0
  6. data/lib/generators/rpush_config_generator.rb +7 -0
  7. data/lib/generators/rpush_migration_generator.rb +66 -0
  8. data/lib/generators/templates/add_adm.rb +23 -0
  9. data/lib/generators/templates/add_alert_is_json_to_rapns_notifications.rb +9 -0
  10. data/lib/generators/templates/add_app_to_rapns.rb +11 -0
  11. data/lib/generators/templates/add_fail_after_to_rpush_notifications.rb +9 -0
  12. data/lib/generators/templates/add_gcm.rb +117 -0
  13. data/lib/generators/templates/add_rpush.rb +402 -0
  14. data/lib/generators/templates/add_wpns.rb +16 -0
  15. data/lib/generators/templates/create_rapns_apps.rb +16 -0
  16. data/lib/generators/templates/create_rapns_feedback.rb +25 -0
  17. data/lib/generators/templates/create_rapns_notifications.rb +36 -0
  18. data/lib/generators/templates/rename_rapns_to_rpush.rb +87 -0
  19. data/lib/generators/templates/rpush.rb +135 -0
  20. data/lib/generators/templates/rpush_2_0_0_updates.rb +79 -0
  21. data/lib/generators/templates/rpush_2_1_0_updates.rb +11 -0
  22. data/lib/generators/templates/rpush_2_6_0_updates.rb +10 -0
  23. data/lib/generators/templates/rpush_2_7_0_updates.rb +12 -0
  24. data/lib/generators/templates/rpush_3_0_0_updates.rb +11 -0
  25. data/lib/generators/templates/rpush_3_0_1_updates.rb +13 -0
  26. data/lib/generators/templates/rpush_3_1_0_add_pushy.rb +9 -0
  27. data/lib/generators/templates/rpush_3_1_1_updates.rb +15 -0
  28. data/lib/generators/templates/rpush_3_2_0_add_apns_p8.rb +15 -0
  29. data/lib/generators/templates/rpush_3_2_4_updates.rb +9 -0
  30. data/lib/generators/templates/rpush_3_3_0_updates.rb +9 -0
  31. data/lib/generators/templates/rpush_3_3_1_updates.rb +11 -0
  32. data/lib/rpush/apns_feedback.rb +17 -0
  33. data/lib/rpush/cli.rb +213 -0
  34. data/lib/rpush/client/active_model/adm/app.rb +23 -0
  35. data/lib/rpush/client/active_model/adm/data_validator.rb +14 -0
  36. data/lib/rpush/client/active_model/adm/notification.rb +28 -0
  37. data/lib/rpush/client/active_model/apns/app.rb +37 -0
  38. data/lib/rpush/client/active_model/apns/binary_notification_validator.rb +16 -0
  39. data/lib/rpush/client/active_model/apns/device_token_format_validator.rb +14 -0
  40. data/lib/rpush/client/active_model/apns/notification.rb +104 -0
  41. data/lib/rpush/client/active_model/apns2/app.rb +15 -0
  42. data/lib/rpush/client/active_model/apns2/notification.rb +9 -0
  43. data/lib/rpush/client/active_model/apnsp8/app.rb +23 -0
  44. data/lib/rpush/client/active_model/apnsp8/notification.rb +9 -0
  45. data/lib/rpush/client/active_model/gcm/app.rb +19 -0
  46. data/lib/rpush/client/active_model/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +14 -0
  47. data/lib/rpush/client/active_model/gcm/notification.rb +59 -0
  48. data/lib/rpush/client/active_model/notification.rb +22 -0
  49. data/lib/rpush/client/active_model/payload_data_size_validator.rb +13 -0
  50. data/lib/rpush/client/active_model/pushy/app.rb +20 -0
  51. data/lib/rpush/client/active_model/pushy/notification.rb +31 -0
  52. data/lib/rpush/client/active_model/pushy/time_to_live_validator.rb +14 -0
  53. data/lib/rpush/client/active_model/registration_ids_count_validator.rb +13 -0
  54. data/lib/rpush/client/active_model/wns/app.rb +23 -0
  55. data/lib/rpush/client/active_model/wns/notification.rb +32 -0
  56. data/lib/rpush/client/active_model/wpns/app.rb +13 -0
  57. data/lib/rpush/client/active_model/wpns/notification.rb +28 -0
  58. data/lib/rpush/client/active_model.rb +34 -0
  59. data/lib/rpush/client/active_record/adm/app.rb +11 -0
  60. data/lib/rpush/client/active_record/adm/notification.rb +11 -0
  61. data/lib/rpush/client/active_record/apns/app.rb +11 -0
  62. data/lib/rpush/client/active_record/apns/feedback.rb +18 -0
  63. data/lib/rpush/client/active_record/apns/notification.rb +40 -0
  64. data/lib/rpush/client/active_record/apns2/app.rb +11 -0
  65. data/lib/rpush/client/active_record/apns2/notification.rb +10 -0
  66. data/lib/rpush/client/active_record/apnsp8/app.rb +11 -0
  67. data/lib/rpush/client/active_record/apnsp8/notification.rb +10 -0
  68. data/lib/rpush/client/active_record/app.rb +13 -0
  69. data/lib/rpush/client/active_record/gcm/app.rb +11 -0
  70. data/lib/rpush/client/active_record/gcm/notification.rb +11 -0
  71. data/lib/rpush/client/active_record/notification.rb +42 -0
  72. data/lib/rpush/client/active_record/pushy/app.rb +11 -0
  73. data/lib/rpush/client/active_record/pushy/notification.rb +11 -0
  74. data/lib/rpush/client/active_record/wns/app.rb +11 -0
  75. data/lib/rpush/client/active_record/wns/badge_notification.rb +15 -0
  76. data/lib/rpush/client/active_record/wns/notification.rb +11 -0
  77. data/lib/rpush/client/active_record/wns/raw_notification.rb +13 -0
  78. data/lib/rpush/client/active_record/wpns/app.rb +11 -0
  79. data/lib/rpush/client/active_record/wpns/notification.rb +11 -0
  80. data/lib/rpush/client/active_record.rb +33 -0
  81. data/lib/rpush/client/redis/adm/app.rb +14 -0
  82. data/lib/rpush/client/redis/adm/notification.rb +11 -0
  83. data/lib/rpush/client/redis/apns/app.rb +11 -0
  84. data/lib/rpush/client/redis/apns/feedback.rb +20 -0
  85. data/lib/rpush/client/redis/apns/notification.rb +11 -0
  86. data/lib/rpush/client/redis/apns2/app.rb +11 -0
  87. data/lib/rpush/client/redis/apns2/notification.rb +11 -0
  88. data/lib/rpush/client/redis/apnsp8/app.rb +11 -0
  89. data/lib/rpush/client/redis/apnsp8/notification.rb +11 -0
  90. data/lib/rpush/client/redis/app.rb +29 -0
  91. data/lib/rpush/client/redis/gcm/app.rb +11 -0
  92. data/lib/rpush/client/redis/gcm/notification.rb +11 -0
  93. data/lib/rpush/client/redis/notification.rb +74 -0
  94. data/lib/rpush/client/redis/pushy/app.rb +16 -0
  95. data/lib/rpush/client/redis/pushy/notification.rb +18 -0
  96. data/lib/rpush/client/redis/wns/app.rb +14 -0
  97. data/lib/rpush/client/redis/wns/badge_notification.rb +15 -0
  98. data/lib/rpush/client/redis/wns/notification.rb +11 -0
  99. data/lib/rpush/client/redis/wns/raw_notification.rb +11 -0
  100. data/lib/rpush/client/redis/wpns/app.rb +11 -0
  101. data/lib/rpush/client/redis/wpns/notification.rb +11 -0
  102. data/lib/rpush/client/redis.rb +56 -0
  103. data/lib/rpush/configuration.rb +115 -0
  104. data/lib/rpush/daemon/adm/delivery.rb +226 -0
  105. data/lib/rpush/daemon/adm.rb +9 -0
  106. data/lib/rpush/daemon/apns/delivery.rb +43 -0
  107. data/lib/rpush/daemon/apns/feedback_receiver.rb +90 -0
  108. data/lib/rpush/daemon/apns.rb +17 -0
  109. data/lib/rpush/daemon/apns2/delivery.rb +127 -0
  110. data/lib/rpush/daemon/apns2.rb +10 -0
  111. data/lib/rpush/daemon/apnsp8/delivery.rb +166 -0
  112. data/lib/rpush/daemon/apnsp8/token.rb +43 -0
  113. data/lib/rpush/daemon/apnsp8.rb +10 -0
  114. data/lib/rpush/daemon/app_runner.rb +190 -0
  115. data/lib/rpush/daemon/batch.rb +138 -0
  116. data/lib/rpush/daemon/constants.rb +59 -0
  117. data/lib/rpush/daemon/delivery.rb +46 -0
  118. data/lib/rpush/daemon/delivery_error.rb +27 -0
  119. data/lib/rpush/daemon/dispatcher/apns_http2.rb +51 -0
  120. data/lib/rpush/daemon/dispatcher/apns_tcp.rb +152 -0
  121. data/lib/rpush/daemon/dispatcher/apnsp8_http2.rb +33 -0
  122. data/lib/rpush/daemon/dispatcher/http.rb +21 -0
  123. data/lib/rpush/daemon/dispatcher/tcp.rb +22 -0
  124. data/lib/rpush/daemon/dispatcher_loop.rb +73 -0
  125. data/lib/rpush/daemon/errors.rb +18 -0
  126. data/lib/rpush/daemon/feeder.rb +69 -0
  127. data/lib/rpush/daemon/gcm/delivery.rb +241 -0
  128. data/lib/rpush/daemon/gcm.rb +9 -0
  129. data/lib/rpush/daemon/interruptible_sleep.rb +24 -0
  130. data/lib/rpush/daemon/loggable.rb +33 -0
  131. data/lib/rpush/daemon/proc_title.rb +17 -0
  132. data/lib/rpush/daemon/pushy/delivery.rb +90 -0
  133. data/lib/rpush/daemon/pushy.rb +9 -0
  134. data/lib/rpush/daemon/queue_payload.rb +12 -0
  135. data/lib/rpush/daemon/retry_header_parser.rb +23 -0
  136. data/lib/rpush/daemon/retryable_error.rb +22 -0
  137. data/lib/rpush/daemon/ring_buffer.rb +16 -0
  138. data/lib/rpush/daemon/rpc/client.rb +27 -0
  139. data/lib/rpush/daemon/rpc/server.rb +82 -0
  140. data/lib/rpush/daemon/rpc.rb +9 -0
  141. data/lib/rpush/daemon/service_config_methods.rb +51 -0
  142. data/lib/rpush/daemon/signal_handler.rb +75 -0
  143. data/lib/rpush/daemon/store/active_record/reconnectable.rb +80 -0
  144. data/lib/rpush/daemon/store/active_record.rb +214 -0
  145. data/lib/rpush/daemon/store/interface.rb +20 -0
  146. data/lib/rpush/daemon/store/redis.rb +166 -0
  147. data/lib/rpush/daemon/string_helpers.rb +15 -0
  148. data/lib/rpush/daemon/synchronizer.rb +62 -0
  149. data/lib/rpush/daemon/tcp_connection.rb +190 -0
  150. data/lib/rpush/daemon/wns/badge_request.rb +32 -0
  151. data/lib/rpush/daemon/wns/delivery.rb +178 -0
  152. data/lib/rpush/daemon/wns/post_request.rb +33 -0
  153. data/lib/rpush/daemon/wns/raw_request.rb +22 -0
  154. data/lib/rpush/daemon/wns/toast_request.rb +54 -0
  155. data/lib/rpush/daemon/wns.rb +9 -0
  156. data/lib/rpush/daemon/wpns/delivery.rb +132 -0
  157. data/lib/rpush/daemon/wpns.rb +9 -0
  158. data/lib/rpush/daemon.rb +179 -0
  159. data/lib/rpush/deprecatable.rb +24 -0
  160. data/lib/rpush/deprecation.rb +26 -0
  161. data/lib/rpush/embed.rb +41 -0
  162. data/lib/rpush/logger.rb +92 -0
  163. data/lib/rpush/multi_json_helper.rb +16 -0
  164. data/lib/rpush/plugin.rb +44 -0
  165. data/lib/rpush/push.rb +11 -0
  166. data/lib/rpush/reflectable.rb +13 -0
  167. data/lib/rpush/reflection_collection.rb +44 -0
  168. data/lib/rpush/reflection_public_methods.rb +11 -0
  169. data/lib/rpush/version.rb +14 -0
  170. data/lib/rpush.rb +43 -0
  171. data/lib/tasks/quality.rake +35 -0
  172. data/lib/tasks/test.rake +69 -0
  173. data/spec/.rubocop.yml +4 -0
  174. data/spec/functional/adm_spec.rb +50 -0
  175. data/spec/functional/apns2_spec.rb +232 -0
  176. data/spec/functional/apns_spec.rb +162 -0
  177. data/spec/functional/cli_spec.rb +36 -0
  178. data/spec/functional/embed_spec.rb +49 -0
  179. data/spec/functional/gcm_spec.rb +46 -0
  180. data/spec/functional/new_app_spec.rb +44 -0
  181. data/spec/functional/pushy_spec.rb +22 -0
  182. data/spec/functional/retry_spec.rb +42 -0
  183. data/spec/functional/synchronization_spec.rb +97 -0
  184. data/spec/functional/wpns_spec.rb +71 -0
  185. data/spec/functional_spec_helper.rb +32 -0
  186. data/spec/spec_helper.rb +69 -0
  187. data/spec/support/active_record_setup.rb +73 -0
  188. data/spec/support/cert_with_password.pem +90 -0
  189. data/spec/support/cert_without_password.pem +59 -0
  190. data/spec/support/config/database.yml +44 -0
  191. data/spec/support/simplecov_helper.rb +24 -0
  192. data/spec/support/simplecov_quality_formatter.rb +12 -0
  193. data/spec/tmp/.gitkeep +0 -0
  194. data/spec/unit/apns_feedback_spec.rb +28 -0
  195. data/spec/unit/client/active_record/adm/app_spec.rb +58 -0
  196. data/spec/unit/client/active_record/adm/notification_spec.rb +43 -0
  197. data/spec/unit/client/active_record/apns/app_spec.rb +29 -0
  198. data/spec/unit/client/active_record/apns/feedback_spec.rb +9 -0
  199. data/spec/unit/client/active_record/apns/notification_spec.rb +324 -0
  200. data/spec/unit/client/active_record/app_spec.rb +30 -0
  201. data/spec/unit/client/active_record/gcm/app_spec.rb +4 -0
  202. data/spec/unit/client/active_record/gcm/notification_spec.rb +67 -0
  203. data/spec/unit/client/active_record/notification_spec.rb +21 -0
  204. data/spec/unit/client/active_record/pushy/app_spec.rb +17 -0
  205. data/spec/unit/client/active_record/pushy/notification_spec.rb +65 -0
  206. data/spec/unit/client/active_record/wns/badge_notification_spec.rb +15 -0
  207. data/spec/unit/client/active_record/wns/raw_notification_spec.rb +26 -0
  208. data/spec/unit/client/active_record/wpns/app_spec.rb +4 -0
  209. data/spec/unit/client/active_record/wpns/notification_spec.rb +21 -0
  210. data/spec/unit/configuration_spec.rb +46 -0
  211. data/spec/unit/daemon/adm/delivery_spec.rb +253 -0
  212. data/spec/unit/daemon/apns/certificate_expired_error_spec.rb +11 -0
  213. data/spec/unit/daemon/apns/delivery_spec.rb +108 -0
  214. data/spec/unit/daemon/apns/feedback_receiver_spec.rb +119 -0
  215. data/spec/unit/daemon/app_runner_spec.rb +188 -0
  216. data/spec/unit/daemon/batch_spec.rb +169 -0
  217. data/spec/unit/daemon/delivery_error_spec.rb +13 -0
  218. data/spec/unit/daemon/delivery_spec.rb +51 -0
  219. data/spec/unit/daemon/dispatcher/http_spec.rb +34 -0
  220. data/spec/unit/daemon/dispatcher/tcp_spec.rb +32 -0
  221. data/spec/unit/daemon/dispatcher_loop_spec.rb +53 -0
  222. data/spec/unit/daemon/feeder_spec.rb +96 -0
  223. data/spec/unit/daemon/gcm/delivery_spec.rb +387 -0
  224. data/spec/unit/daemon/proc_title_spec.rb +11 -0
  225. data/spec/unit/daemon/pushy/delivery_spec.rb +159 -0
  226. data/spec/unit/daemon/retryable_error_spec.rb +14 -0
  227. data/spec/unit/daemon/service_config_methods_spec.rb +36 -0
  228. data/spec/unit/daemon/signal_handler_spec.rb +99 -0
  229. data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +165 -0
  230. data/spec/unit/daemon/store/active_record_spec.rb +357 -0
  231. data/spec/unit/daemon/store/redis_spec.rb +365 -0
  232. data/spec/unit/daemon/tcp_connection_spec.rb +292 -0
  233. data/spec/unit/daemon/wns/delivery_spec.rb +176 -0
  234. data/spec/unit/daemon/wns/post_request_spec.rb +117 -0
  235. data/spec/unit/daemon/wpns/delivery_spec.rb +167 -0
  236. data/spec/unit/daemon_spec.rb +138 -0
  237. data/spec/unit/deprecatable_spec.rb +32 -0
  238. data/spec/unit/deprecation_spec.rb +15 -0
  239. data/spec/unit/embed_spec.rb +47 -0
  240. data/spec/unit/logger_spec.rb +127 -0
  241. data/spec/unit/notification_shared.rb +53 -0
  242. data/spec/unit/plugin_spec.rb +36 -0
  243. data/spec/unit/push_spec.rb +34 -0
  244. data/spec/unit/reflectable_spec.rb +27 -0
  245. data/spec/unit/reflection_collection_spec.rb +26 -0
  246. data/spec/unit/rpush_spec.rb +8 -0
  247. data/spec/unit_spec_helper.rb +26 -0
  248. metadata +709 -0
@@ -0,0 +1,41 @@
1
+ module Rpush
2
+ def self.embed
3
+ require 'rpush/daemon'
4
+
5
+ if @embed_thread
6
+ STDERR.puts 'Rpush.embed can only be run once inside this process.'
7
+ end
8
+
9
+ Rpush.config.embedded = true
10
+ Rpush.config.foreground = true
11
+ Kernel.at_exit { shutdown }
12
+ @embed_thread = Thread.new { Rpush::Daemon.start }
13
+ end
14
+
15
+ def self.shutdown
16
+ return unless Rpush.config.embedded
17
+ Rpush::Daemon.shutdown
18
+ @embed_thread.join if @embed_thread
19
+ rescue StandardError => e
20
+ STDERR.puts(e.message)
21
+ STDERR.puts(e.backtrace.join("\n"))
22
+ ensure
23
+ @embed_thread = nil
24
+ end
25
+
26
+ def self.sync
27
+ return unless Rpush.config.embedded
28
+ Rpush::Daemon::Synchronizer.sync
29
+ end
30
+
31
+ def self.status
32
+ return unless Rpush.config.embedded
33
+ status = Rpush::Daemon::AppRunner.status
34
+ Rpush.logger.info(JSON.pretty_generate(status))
35
+ status
36
+ end
37
+
38
+ def self.debug
39
+ status
40
+ end
41
+ end
@@ -0,0 +1,92 @@
1
+ module Rpush
2
+ class Logger
3
+ attr_reader :internal_logger
4
+
5
+ def initialize
6
+ @internal_logger = Rpush.config.logger || setup_logger(open_logfile)
7
+ @internal_logger.level = Rpush.config.log_level
8
+ rescue SystemCallError => e
9
+ @internal_logger = nil
10
+ error(e)
11
+ error('Logging disabled.')
12
+ end
13
+
14
+ def debug(msg, inline = false)
15
+ log(:debug, msg, inline)
16
+ end
17
+
18
+ def info(msg, inline = false)
19
+ log(:info, msg, inline)
20
+ end
21
+
22
+ def error(msg, inline = false)
23
+ log(:error, msg, inline, 'ERROR', STDERR)
24
+ end
25
+
26
+ def warn(msg, inline = false)
27
+ log(:warn, msg, inline, 'WARNING', STDERR)
28
+ end
29
+
30
+ def reopen
31
+ if Rpush.config.logger
32
+ Rpush.config.logger.reopen if Rpush.config.logger.respond_to?(:reopen)
33
+ else
34
+ @internal_logger.close
35
+ @internal_logger = setup_logger(open_logfile)
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def open_logfile
42
+ FileUtils.mkdir_p(File.dirname(Rpush.config.log_file))
43
+ log = File.open(Rpush.config.log_file, 'a')
44
+ log.sync = true
45
+ log
46
+ end
47
+
48
+ def setup_logger(log)
49
+ if ActiveSupport.const_defined?('BufferedLogger')
50
+ logger = ActiveSupport::BufferedLogger.new(log)
51
+ logger.auto_flushing = auto_flushing
52
+ logger
53
+ else
54
+ ActiveSupport::Logger.new(log)
55
+ end
56
+ end
57
+
58
+ def auto_flushing
59
+ if defined?(Rails) && Rails.logger.respond_to?(:auto_flushing)
60
+ Rails.logger.auto_flushing
61
+ else
62
+ true
63
+ end
64
+ end
65
+
66
+ def log(where, msg, inline = false, prefix = nil, io = STDOUT)
67
+ if msg.is_a?(Exception)
68
+ formatted_backtrace = msg.backtrace.join("\n")
69
+ msg = "#{msg.class.name}, #{msg.message}\n#{formatted_backtrace}"
70
+ end
71
+
72
+ formatted_msg = "[#{Time.now.to_s(:db)}] "
73
+ formatted_msg << '[rpush] ' if Rpush.config.embedded
74
+ formatted_msg << "[#{prefix}] " if prefix
75
+ formatted_msg << msg
76
+
77
+ log_foreground(io, formatted_msg, inline)
78
+ @internal_logger.send(where, formatted_msg) if @internal_logger
79
+ end
80
+
81
+ def log_foreground(io, formatted_msg, inline)
82
+ return unless io == STDERR || Rpush.config.foreground
83
+
84
+ if inline
85
+ io.write(formatted_msg)
86
+ io.flush
87
+ else
88
+ io.puts(formatted_msg)
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,16 @@
1
+ module Rpush
2
+ module MultiJsonHelper
3
+ def multi_json_load(string, options = {})
4
+ # Calling load on multi_json less than v1.3.0 attempts to load a file from disk.
5
+ if Gem.loaded_specs['multi_json'].version >= Gem::Version.create('1.3.0')
6
+ MultiJson.load(string, options)
7
+ else
8
+ MultiJson.decode(string, options)
9
+ end
10
+ end
11
+
12
+ def multi_json_dump(string, options = {})
13
+ MultiJson.respond_to?(:dump) ? MultiJson.dump(string, options) : MultiJson.encode(string, options)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,44 @@
1
+ module Rpush
2
+ def self.plugin(name)
3
+ plugins[name] ||= Rpush::Plugin.new(name)
4
+ plugins[name]
5
+ end
6
+
7
+ def self.plugins
8
+ @plugins ||= {}
9
+ end
10
+
11
+ class Plugin
12
+ attr_reader :name, :config, :init_block
13
+ attr_accessor :url, :description
14
+
15
+ def initialize(name)
16
+ @name = name
17
+ @url = nil
18
+ @description = nil
19
+ @config = OpenStruct.new
20
+ @reflection_collection = Rpush::ReflectionCollection.new
21
+ @init_block = -> {}
22
+ end
23
+
24
+ def reflect
25
+ yield(@reflection_collection)
26
+ return if Rpush.reflection_stack.include?(@reflection_collection)
27
+ Rpush.reflection_stack << @reflection_collection
28
+ end
29
+
30
+ def configure
31
+ yield(@config)
32
+ Rpush.config.plugin.send("#{@name}=", @config)
33
+ end
34
+
35
+ def init(&block)
36
+ @init_block = block
37
+ end
38
+
39
+ def unload
40
+ Rpush.reflection_stack.delete(@reflection_collection)
41
+ Rpush.config.plugin.send("#{name}=", nil)
42
+ end
43
+ end
44
+ end
data/lib/rpush/push.rb ADDED
@@ -0,0 +1,11 @@
1
+ module Rpush
2
+ def self.push
3
+ require 'rpush/daemon'
4
+
5
+ Rpush.config.push = true
6
+ Rpush::Daemon.common_init
7
+ Rpush::Daemon::Synchronizer.sync
8
+ Rpush::Daemon::Feeder.start(true) # non-blocking
9
+ Rpush::Daemon::AppRunner.stop
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ module Rpush
2
+ module Reflectable
3
+ def reflect(name, *args)
4
+ Rpush.reflection_stack.each do |reflection_collection|
5
+ begin
6
+ reflection_collection.__dispatch(name, *args)
7
+ rescue StandardError => e
8
+ Rpush.logger.error(e)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,44 @@
1
+ module Rpush
2
+ class ReflectionCollection
3
+ class NoSuchReflectionError < StandardError; end
4
+
5
+ REFLECTIONS = [
6
+ :apns_feedback, :notification_enqueued, :notification_delivered,
7
+ :notification_failed, :notification_will_retry, :gcm_delivered_to_recipient,
8
+ :gcm_failed_to_recipient, :gcm_canonical_id, :gcm_invalid_registration_id,
9
+ :error, :adm_canonical_id, :adm_failed_to_recipient, :wns_invalid_channel,
10
+ :tcp_connection_lost, :ssl_certificate_will_expire, :ssl_certificate_revoked,
11
+ :notification_id_will_retry, :notification_id_failed
12
+ ]
13
+
14
+ DEPRECATIONS = {}
15
+
16
+ REFLECTIONS.each do |reflection|
17
+ class_eval(<<-RUBY, __FILE__, __LINE__)
18
+ def #{reflection}(*args, &blk)
19
+ raise "block required" unless block_given?
20
+ @reflections[:#{reflection}] = blk
21
+ end
22
+ RUBY
23
+ end
24
+
25
+ def initialize
26
+ @reflections = {}
27
+ end
28
+
29
+ def __dispatch(reflection, *args)
30
+ blk = @reflections[reflection]
31
+
32
+ if blk
33
+ blk.call(*args)
34
+
35
+ if DEPRECATIONS.key?(reflection)
36
+ replacement, removal_version = DEPRECATIONS[reflection]
37
+ Rpush::Deprecation.warn("#{reflection} is deprecated and will be removed in version #{removal_version}. Use #{replacement} instead.")
38
+ end
39
+ elsif !REFLECTIONS.include?(reflection)
40
+ raise NoSuchReflectionError, reflection
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,11 @@
1
+ module Rpush
2
+ @reflection_stack ||= [ReflectionCollection.new]
3
+
4
+ class << self
5
+ attr_reader :reflection_stack
6
+ end
7
+
8
+ def self.reflect
9
+ yield reflection_stack[0] if block_given?
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ module Rpush
2
+ module VERSION
3
+ MAJOR = 3
4
+ MINOR = 2
5
+ TINY = 5
6
+ PRE = nil
7
+
8
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".").freeze
9
+
10
+ def self.to_s
11
+ STRING
12
+ end
13
+ end
14
+ end
data/lib/rpush.rb ADDED
@@ -0,0 +1,43 @@
1
+ require 'logger'
2
+ require 'multi_json'
3
+ require 'active_support/all'
4
+ require 'net-http2'
5
+ require 'jwt'
6
+
7
+ require 'rails'
8
+
9
+ require 'rpush/version'
10
+ require 'rpush/cli'
11
+ require 'rpush/deprecation'
12
+ require 'rpush/deprecatable'
13
+ require 'rpush/logger'
14
+ require 'rpush/multi_json_helper'
15
+ require 'rpush/configuration'
16
+ require 'rpush/reflection_collection'
17
+ require 'rpush/reflection_public_methods'
18
+ require 'rpush/reflectable'
19
+ require 'rpush/plugin'
20
+ require 'rpush/embed'
21
+ require 'rpush/push'
22
+ require 'rpush/apns_feedback'
23
+
24
+ module Rpush
25
+ def self.jruby?
26
+ defined? JRUBY_VERSION
27
+ end
28
+
29
+ def self.logger
30
+ @logger ||= Logger.new
31
+ end
32
+
33
+ def self.root
34
+ require 'rails'
35
+ Rails.root || Dir.pwd
36
+ rescue LoadError
37
+ Dir.pwd
38
+ end
39
+
40
+ class << self
41
+ attr_writer :logger
42
+ end
43
+ end
@@ -0,0 +1,35 @@
1
+ begin
2
+ require 'cane/rake_task'
3
+
4
+ desc 'Run cane to check quality metrics'
5
+ Cane::RakeTask.new(:cane_quality) do |cane|
6
+ cane.add_threshold 'coverage/covered_percent', :>=, 80
7
+ cane.no_style = false
8
+ cane.style_measure = 1000
9
+ cane.no_doc = true
10
+ cane.abc_max = 22
11
+ end
12
+
13
+ namespace :spec do
14
+ task cane: %w(spec cane_quality)
15
+ end
16
+ rescue LoadError
17
+ warn "cane not available."
18
+
19
+ namespace :spec do
20
+ task cane: ['spec']
21
+ end
22
+ end
23
+
24
+ begin
25
+ require 'rubocop/rake_task'
26
+ t = RuboCop::RakeTask.new
27
+ t.options << '-D'
28
+ rescue LoadError
29
+ warn 'rubocop not available.'
30
+ task rubocop: ['spec']
31
+ end
32
+
33
+ namespace :spec do
34
+ task quality: %w(cane rubocop)
35
+ end
@@ -0,0 +1,69 @@
1
+ require 'fileutils'
2
+
3
+ def cmd(str, clean_env = true)
4
+ puts "* #{str}"
5
+ retval = clean_env ? Bundler.with_clean_env { `#{str}` } : `#{str}`
6
+ puts retval.strip
7
+ retval
8
+ end
9
+
10
+ def add_ruby_dot_files
11
+ cmd("echo '#{RUBY_ENGINE}-#{RUBY_VERSION}' > .ruby-version")
12
+ cmd("echo 'rpush_test' > .ruby-gemset")
13
+ end
14
+
15
+ desc 'Build Rails app bundled with Rpush'
16
+ task :build_rails do
17
+ rpush_root = Dir.pwd
18
+ path = '/tmp/rpush/rails_test'
19
+ cmd("rm -rf #{path}")
20
+ FileUtils.mkdir_p(path)
21
+ pwd = Dir.pwd
22
+
23
+ cmd("bundle exec rails --version", false)
24
+ cmd("bundle exec rails new #{path} --skip-bundle", false)
25
+
26
+ begin
27
+ Dir.chdir(path)
28
+ add_ruby_dot_files
29
+ cmd('echo "gem \'rake\'" >> Gemfile')
30
+ cmd('echo "gem \'pg\'" >> Gemfile')
31
+ cmd("echo \"gem 'rpush', path: '#{rpush_root}'\" >> Gemfile")
32
+
33
+ File.open('config/database.yml', 'w') do |fd|
34
+ fd.write(<<-YML)
35
+ development:
36
+ adapter: postgresql
37
+ database: rpush_rails_test
38
+ pool: 5
39
+ timeout: 5000
40
+ YML
41
+ end
42
+ ensure
43
+ Dir.chdir(pwd)
44
+ end
45
+
46
+ puts "Built into #{path}"
47
+ end
48
+
49
+ desc 'Build blank app bundled with Rpush'
50
+ task :build_standalone do
51
+ rpush_root = Dir.pwd
52
+ path = '/tmp/rpush/standalone_test'
53
+ cmd("rm -rf #{path}")
54
+ FileUtils.mkdir_p(path)
55
+ pwd = Dir.pwd
56
+
57
+ begin
58
+ Dir.chdir(path)
59
+ add_ruby_dot_files
60
+ cmd('echo "source \'https://rubygems.org\'" >> Gemfile')
61
+ cmd('echo "gem \'rake\'" >> Gemfile')
62
+ cmd('echo "gem \'rpush-redis\'" >> Gemfile')
63
+ cmd("echo \"gem 'rpush', path: '#{rpush_root}'\" >> Gemfile")
64
+ ensure
65
+ Dir.chdir(pwd)
66
+ end
67
+
68
+ puts "Built into #{path}"
69
+ end
data/spec/.rubocop.yml ADDED
@@ -0,0 +1,4 @@
1
+ inherit_from: ../.rubocop.yml
2
+
3
+ RescueModifier:
4
+ Enabled: false
@@ -0,0 +1,50 @@
1
+ require 'functional_spec_helper'
2
+
3
+ describe 'ADM' do
4
+ let(:app) { Rpush::Adm::App.new }
5
+ let(:notification) { Rpush::Adm::Notification.new }
6
+ let(:response) { double(Net::HTTPResponse, code: 200) }
7
+ let(:http) { double(Net::HTTP::Persistent, request: response, shutdown: nil) }
8
+ let(:delivered_ids) { [] }
9
+ let(:failed_ids) { [] }
10
+ let(:retry_ids) { [] }
11
+
12
+ before do
13
+ app.name = 'test'
14
+ app.client_id = 'abc'
15
+ app.client_secret = '123'
16
+ app.save!
17
+
18
+ notification.app = app
19
+ notification.registration_ids = ['foo']
20
+ notification.data = { message: 'test' }
21
+ notification.save!
22
+
23
+ allow(Net::HTTP::Persistent).to receive_messages(new: http)
24
+ end
25
+
26
+ it 'delivers a notification successfully' do
27
+ allow(response).to receive_messages(body: JSON.dump(registrationID: notification.registration_ids.first.to_s))
28
+
29
+ expect do
30
+ Rpush.push
31
+ notification.reload
32
+ end.to change(notification, :delivered).to(true)
33
+ end
34
+
35
+ it 'fails to deliver a notification successfully' do
36
+ allow(response).to receive_messages(code: 400, body: JSON.dump(reason: 'error', registrationID: notification.registration_ids.first.to_s))
37
+ Rpush.push
38
+ notification.reload
39
+ expect(notification.delivered).to eq(false)
40
+ end
41
+
42
+ it 'retries notification that fail due to a SocketError' do
43
+ expect(http).to receive(:request).and_raise(SocketError.new)
44
+ expect(notification.deliver_after).to be_nil
45
+ expect do
46
+ Rpush.push
47
+ notification.reload
48
+ end.to change(notification, :deliver_after).to(kind_of(Time))
49
+ end
50
+ end