em_apn_manager 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ce5404fa96a8fb4011755d83fac888407fb0d459
4
- data.tar.gz: 2930eb22b3c1d7cd7affbafc2f938a9123ca3ae6
3
+ metadata.gz: 7488d9d6b4d3ffca37840e1efd52dd3bc555c4cb
4
+ data.tar.gz: 39053f313b6bdd6bb04469d2804c650ec0ca549f
5
5
  SHA512:
6
- metadata.gz: a1b5274c66621788d2b2991af6beff40cf4a2be3d93984c72b924af8f31bc9f0b316bfb32f7a3276b87b43431b055d09274143431e66d6b6c63adbe607397f09
7
- data.tar.gz: 560211b2323f0c76c3fedb45166761e87196d7941f67f0dfc010253324c01d265d6ec1d6495ea8c324d0795c5ecbc1d5ca2a6ad0418dd0384e3e72f1bb24e7be
6
+ metadata.gz: 4a9906727741db1583fe89b897c7876944a31ce5b0fa231c955195371e6f624ff633b3c606868aa47204a379933bf5ef6c3038952516ad2256e38a44d795786c
7
+ data.tar.gz: a0e2b04ee2a8d50f83d10931ddd6b94f9ac08051905ea1edb93a6c25a27c48ae412cf4177bf260d65908d16777f540ee24c28eaef06a630d0cf156fe040a3ca3
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- em_apn_manager (0.0.2)
4
+ em_apn_manager (0.1.0)
5
5
  em-hiredis (>= 0.2.1)
6
6
  em_apn_manager
7
7
  eventmachine (>= 1.0.0)
data/README.md CHANGED
@@ -3,24 +3,40 @@ EventMachine APN Manager
3
3
 
4
4
  EventMachine APN Connection Manager, The purpose is to support multiple cert and multiple application with one process.
5
5
 
6
- Steps to use this gem.
7
- 1. Add `gem 'em_apn_manager', git: 'git@github.com:hlxwell/em_apn_manager.git'`
8
- 2. Run `bundle exec rails g event_machine:apn_manager:install` to generate 'config/em_apn_manager.yml' file.
9
- 3. Run `bundle exec em_apn_manager -e development`
10
- 4. Put this in your code
6
+ Steps for running with *Rails*:
7
+
8
+ 1. Add `gem 'em_apn_manager', git: 'git@github.com:hlxwell/em_apn_manager.git'` to *Gemfile*.
9
+
10
+ 2. Run `bundle exec rails g event_machine:apn_manager:install` to generate `config/em_apn_manager.yml` file.
11
+
12
+ 3. Run `bundle exec em_apn_manager server -e development`.
13
+
14
+
15
+ Steps for running `Standalone`:
16
+
17
+ 1. Run `gem install em_apn_manager`
18
+
19
+ 2. Run `em_apn_manager server --redis-host 127.0.0.1 --redis-port 6379` or `em_apn_manager server --config CONFIG_FILE_PATH`
20
+
21
+ Put below line to your code for sending push notification:
22
+
11
23
  `EM::ApnManager.push_notification({
12
- cert: READ_YOUR_CERT_CONTENT,
24
+ env: CERT_ENVIRONMENT,
25
+ cert: PEM_CERT_TEXT_CONTENT,
13
26
  token: DEVICE_TOKEN,
14
27
  message: YOUR_MESSAGE
15
28
  })`
16
29
 
30
+ Running server in background:
31
+
32
+ `em_apn_manager server --daemon`
17
33
 
18
34
  Generate pem from p12
19
35
  ==================
36
+
37
+ This is how you get `p12` file:
38
+ http://docs.urbanairship.com/build/ios.html#set-up-your-application-with-apple
39
+
20
40
  You have to convert p12 format to pem format by below command line.
21
41
  `openssl pkcs12 -in cert.p12 -out cert.pem -nodes -clcerts`
22
42
 
23
-
24
- TO DOs
25
- ==================
26
- 1. Implement running `bundle exec em_apn_manager -e development` in background, support `-daemon` and `-pid_file`
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.1.0
data/bin/em_apn_manager CHANGED
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
+
2
3
  require 'em_apn_manager/cli'
3
4
 
5
+ ### When in development mode run this `ruby -Ilib ./bin/em_apn_manager`
4
6
  EM::ApnManager::CLI.start(ARGV)
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "em_apn_manager"
8
- s.version = "0.0.2"
8
+ s.version = "0.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Michael He"]
12
- s.date = "2013-07-16"
12
+ s.date = "2013-07-17"
13
13
  s.description = "EventMachine multiple APNs connections Management Solution. You can use multiple cert and connection to apple's APNs server."
14
14
  s.email = "m.he@skillupjapan.co.jp"
15
15
  s.executables = ["em_apn_manager"]
@@ -99,6 +99,16 @@ Gem::Specification.new do |s|
99
99
  s.add_development_dependency(%q<rdoc>, [">= 0"])
100
100
  s.add_development_dependency(%q<bundler>, [">= 0"])
101
101
  s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
102
+ s.add_development_dependency(%q<rspec>, ["~> 2.6.0"])
103
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
104
+ s.add_development_dependency(%q<rdoc>, [">= 0"])
105
+ s.add_development_dependency(%q<bundler>, [">= 0"])
106
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
107
+ s.add_development_dependency(%q<rspec>, ["~> 2.6.0"])
108
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
109
+ s.add_development_dependency(%q<rdoc>, [">= 0"])
110
+ s.add_development_dependency(%q<bundler>, [">= 0"])
111
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
102
112
  s.add_runtime_dependency(%q<thor>, ["~> 0.16"])
103
113
  s.add_runtime_dependency(%q<eventmachine>, [">= 1.0.0"])
104
114
  s.add_runtime_dependency(%q<yajl-ruby>, [">= 0.8.2"])
@@ -157,6 +167,16 @@ Gem::Specification.new do |s|
157
167
  s.add_dependency(%q<rdoc>, [">= 0"])
158
168
  s.add_dependency(%q<bundler>, [">= 0"])
159
169
  s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
170
+ s.add_dependency(%q<rspec>, ["~> 2.6.0"])
171
+ s.add_dependency(%q<shoulda>, [">= 0"])
172
+ s.add_dependency(%q<rdoc>, [">= 0"])
173
+ s.add_dependency(%q<bundler>, [">= 0"])
174
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
175
+ s.add_dependency(%q<rspec>, ["~> 2.6.0"])
176
+ s.add_dependency(%q<shoulda>, [">= 0"])
177
+ s.add_dependency(%q<rdoc>, [">= 0"])
178
+ s.add_dependency(%q<bundler>, [">= 0"])
179
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
160
180
  s.add_dependency(%q<thor>, ["~> 0.16"])
161
181
  s.add_dependency(%q<eventmachine>, [">= 1.0.0"])
162
182
  s.add_dependency(%q<yajl-ruby>, [">= 0.8.2"])
@@ -216,6 +236,16 @@ Gem::Specification.new do |s|
216
236
  s.add_dependency(%q<rdoc>, [">= 0"])
217
237
  s.add_dependency(%q<bundler>, [">= 0"])
218
238
  s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
239
+ s.add_dependency(%q<rspec>, ["~> 2.6.0"])
240
+ s.add_dependency(%q<shoulda>, [">= 0"])
241
+ s.add_dependency(%q<rdoc>, [">= 0"])
242
+ s.add_dependency(%q<bundler>, [">= 0"])
243
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
244
+ s.add_dependency(%q<rspec>, ["~> 2.6.0"])
245
+ s.add_dependency(%q<shoulda>, [">= 0"])
246
+ s.add_dependency(%q<rdoc>, [">= 0"])
247
+ s.add_dependency(%q<bundler>, [">= 0"])
248
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
219
249
  s.add_dependency(%q<thor>, ["~> 0.16"])
220
250
  s.add_dependency(%q<eventmachine>, [">= 1.0.0"])
221
251
  s.add_dependency(%q<yajl-ruby>, [">= 0.8.2"])
@@ -13,10 +13,11 @@ module EventMachine
13
13
  def push_notification options = {}
14
14
  # FIXME Check options
15
15
  $apn_manager_redis.publish "push-notification", {
16
+ env: options[:env],
16
17
  cert: options[:cert],
17
18
  token: options[:token],
18
19
  message: options[:message]
19
20
  }.to_json
20
21
  end
21
22
  end
22
- end
23
+ end
@@ -16,34 +16,48 @@ $apn_manager_redis = nil
16
16
  module EventMachine
17
17
  module ApnManager
18
18
  class CLI < Thor
19
- class_option :config, :aliases => ["-c"], :type => :string
20
- class_option :environment, :aliases => ["-e"], :type => :string
19
+ class_option :config, :aliases => ["-c"], :type => :string
20
+ class_option :environment, :aliases => ["-e"], :type => :string
21
+ class_option :redis, :aliases => ["-r"], :type => :string
21
22
 
23
+ ### 3 ways to specify the redis
24
+ # 1. config yml file
25
+ # 2. pass redis-url is 'redis://username:password@host:port/database'
26
+ # like `redis://test:test@localhost:6379/em_apn_manager`
27
+ #
22
28
  def initialize(args = [], opts = [], config = {})
23
29
  super(args, opts, config)
24
30
 
25
- # Read config option, or use default config yml
26
- config_path = options[:config] || File.join(".", "config", "em_apn_manager.yml")
27
- if config_path && File.exists?(config_path)
28
- EM::ApnManager.config = Thor::CoreExt::HashWithIndifferentAccess.new(YAML.load_file(config_path))
29
- else
30
- raise "No config file is specified or specified config file doesn't exist."
31
- end
31
+ redis_config = options[:redis]
32
+ if redis_config.nil?
33
+ # read the environment var.
34
+ @environment = ENV["RAILS_ENV"] || "development"
35
+ @environment = options[:environment] if %w{test development production}.include? options[:environment]
36
+
37
+ # Read config option, or use default config yml
38
+ config_path = options[:config] || File.join(".", "config", "em_apn_manager.yml")
39
+ if config_path && File.exists?(config_path)
40
+ EM::ApnManager.config = Thor::CoreExt::HashWithIndifferentAccess.new(YAML.load_file(config_path))
41
+ redis_config = EM::ApnManager.config[@environment]
42
+ end
32
43
 
33
- # read the environment var.
34
- @environment = "test"
35
- @environment = options[:environment] if %w{test development production}.include? options[:environment]
44
+ # default redis
45
+ redis_config ||= "redis://localhost:6379/em_apn_manager"
46
+ end
36
47
 
37
48
  # create redis connection
38
- $apn_manager_redis = Redis.new EM::ApnManager.config[@environment] || { host:"127.0.0.1", port:6379 }
49
+ $apn_manager_redis = Redis.new url: redis_config
39
50
  end
40
51
 
41
52
  desc "server", "Start manager server."
42
- # option :daemon, :aliases => ["-d"], :type => :boolean
43
- # option :pid_file, :aliases => ["-p"], :type => :string
53
+ option :daemon, :aliases => ["-d"], :type => :boolean
54
+ option :pid_file, :aliases => ["-p"], :type => :string
44
55
  def server
56
+ daemonize if options[:daemon]
57
+ write_pid_file(options[:pid_file]) if options[:pid_file]
58
+
45
59
  EM::ApnManager.logger.info("Starting APN Manager")
46
- EM.run { EM::ApnManager::Manager.run env: @environment }
60
+ EM.run { EM::ApnManager::Manager.run }
47
61
  end
48
62
 
49
63
  ### For Testing ##################################################
@@ -52,8 +66,9 @@ module EventMachine
52
66
  def push_test_message
53
67
  10.times do |i|
54
68
  EM::ApnManager.push_notification({
55
- cert: File.read(ENV["APN_CERT"]),
56
- token: ["0F93C49EAAF3544B5218D2BAE893608C515F69B445279AB2B17511C37046C52B","D42A6795D0C6C0E5F3CC762F905C3654D2A07E72D64CDEC1E2F74AC43C4CC440"].sample,
69
+ env: 'test',
70
+ cert: File.read(ENV["APN_CERT"]), # test cert
71
+ token: ["0F93C49EAAF3544B5218D2BAE893608C515F69B445279AB2B17511C37046C52B", "D42A6795D0C6C0E5F3CC762F905C3654D2A07E72D64CDEC1E2F74AC43C4CC440"].sample,
57
72
  message: "Hahahaha I am going to spam you. #{i}-#{rand * 100}"
58
73
  })
59
74
  end
@@ -64,6 +79,26 @@ module EventMachine
64
79
  EM::ApnManager.logger.info("Starting Mock APN Server")
65
80
  EM.run { EM.start_server("127.0.0.1", 2195, EM::ApnManager::ApnServer) }
66
81
  end
82
+
83
+ private
84
+
85
+ # Daemonize process (ruby >= 1.9 only)
86
+ # @return [void] Ruby ~>1.8
87
+ # @return [0] Ruby 1.9+ (see Process::daemon)
88
+ # @raise [Errno] on failure
89
+ def daemonize
90
+ if Process.respond_to?(:daemon)
91
+ Process.daemon(true, true)
92
+ else
93
+ Kernel.warn "Running process as daemon requires ruby >= 1.9"
94
+ end
95
+ end
96
+
97
+ # Save worker's pid to file
98
+ # @return [void]
99
+ def write_pid_file(path = nil)
100
+ File.open(path, 'w'){ |f| f << Process.pid } if path
101
+ end
67
102
  end
68
103
  end
69
104
  end
@@ -20,10 +20,10 @@ module EventMachine
20
20
  end
21
21
 
22
22
  def initialize(options = {})
23
- @cert = options[:cert] || ENV["APN_CERT"]
23
+ @cert = options[:cert]
24
24
  @port = options[:port] || PORT
25
25
  @environment = options[:env]
26
- @gateway = options[:gateway] || ENV["APN_GATEWAY"]
26
+ @gateway = options[:gateway]
27
27
  @gateway ||= case @environment
28
28
  when "test"
29
29
  TEST_GATEWAY
@@ -1,13 +1,3 @@
1
- production:
2
- host: localhost
3
- port: 6379
4
- db: YOUR_PRODUCTION_REDIS
5
- password: PASSWORD
6
-
7
- development:
8
- host: localhost
9
- port: 6379
10
-
11
- test:
12
- host: localhost
13
- port: 6379
1
+ production: redis://username:password@host:port/database
2
+ development: redis://localhost:6379/resque
3
+ test: redis://localhost:6379/resque
@@ -24,15 +24,17 @@ module EventMachine
24
24
 
25
25
  ### launch a new connect to apple when detected any pushs.
26
26
  @redis.pubsub.subscribe('push-notification') do |msg|
27
- msg_hash = Yajl::Parser.parse(msg) # might be some wrong json
27
+ msg_hash = Yajl::Parser.parse(msg) # FIXME might be some wrong json
28
+
28
29
  # save the cert to local first, since the start_tls read from file.
29
30
  cert_filename = save_cert_to_file msg_hash["cert"]
31
+
30
32
  # cert filename is a key for connection pool
31
33
  client = $connection_pool[cert_filename]
32
34
 
33
35
  ### Create client connection if doesn't exist in pool.
34
36
  if client.nil?
35
- client = EM::ApnManager::Client.new(options.merge!({cert: cert_filename}))
37
+ client = EM::ApnManager::Client.new(options.merge!({env: msg_hash["env"], cert: cert_filename}))
36
38
  # Store the connection to pool
37
39
  $connection_pool[cert_filename] = client
38
40
  end
@@ -54,8 +56,8 @@ module EventMachine
54
56
 
55
57
  private
56
58
 
59
+ # NOTICE should not put the 'certs' folder to a downloadable place.
57
60
  def save_cert_to_file cert_content
58
- # TODO, should store Rails.root/tmp/certs and this folder should be protected.
59
61
  FileUtils.mkdir_p "certs"
60
62
  filename = Base64.encode64(cert_content)[0..50]
61
63
  filename = File.join "certs", filename
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: em_apn_manager
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael He
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-16 00:00:00.000000000 Z
11
+ date: 2013-07-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: em_apn_manager
@@ -724,6 +724,146 @@ dependencies:
724
724
  - - ~>
725
725
  - !ruby/object:Gem::Version
726
726
  version: 1.8.4
727
+ - !ruby/object:Gem::Dependency
728
+ name: rspec
729
+ requirement: !ruby/object:Gem::Requirement
730
+ requirements:
731
+ - - ~>
732
+ - !ruby/object:Gem::Version
733
+ version: 2.6.0
734
+ type: :development
735
+ prerelease: false
736
+ version_requirements: !ruby/object:Gem::Requirement
737
+ requirements:
738
+ - - ~>
739
+ - !ruby/object:Gem::Version
740
+ version: 2.6.0
741
+ - !ruby/object:Gem::Dependency
742
+ name: shoulda
743
+ requirement: !ruby/object:Gem::Requirement
744
+ requirements:
745
+ - - '>='
746
+ - !ruby/object:Gem::Version
747
+ version: '0'
748
+ type: :development
749
+ prerelease: false
750
+ version_requirements: !ruby/object:Gem::Requirement
751
+ requirements:
752
+ - - '>='
753
+ - !ruby/object:Gem::Version
754
+ version: '0'
755
+ - !ruby/object:Gem::Dependency
756
+ name: rdoc
757
+ requirement: !ruby/object:Gem::Requirement
758
+ requirements:
759
+ - - '>='
760
+ - !ruby/object:Gem::Version
761
+ version: '0'
762
+ type: :development
763
+ prerelease: false
764
+ version_requirements: !ruby/object:Gem::Requirement
765
+ requirements:
766
+ - - '>='
767
+ - !ruby/object:Gem::Version
768
+ version: '0'
769
+ - !ruby/object:Gem::Dependency
770
+ name: bundler
771
+ requirement: !ruby/object:Gem::Requirement
772
+ requirements:
773
+ - - '>='
774
+ - !ruby/object:Gem::Version
775
+ version: '0'
776
+ type: :development
777
+ prerelease: false
778
+ version_requirements: !ruby/object:Gem::Requirement
779
+ requirements:
780
+ - - '>='
781
+ - !ruby/object:Gem::Version
782
+ version: '0'
783
+ - !ruby/object:Gem::Dependency
784
+ name: jeweler
785
+ requirement: !ruby/object:Gem::Requirement
786
+ requirements:
787
+ - - ~>
788
+ - !ruby/object:Gem::Version
789
+ version: 1.8.4
790
+ type: :development
791
+ prerelease: false
792
+ version_requirements: !ruby/object:Gem::Requirement
793
+ requirements:
794
+ - - ~>
795
+ - !ruby/object:Gem::Version
796
+ version: 1.8.4
797
+ - !ruby/object:Gem::Dependency
798
+ name: rspec
799
+ requirement: !ruby/object:Gem::Requirement
800
+ requirements:
801
+ - - ~>
802
+ - !ruby/object:Gem::Version
803
+ version: 2.6.0
804
+ type: :development
805
+ prerelease: false
806
+ version_requirements: !ruby/object:Gem::Requirement
807
+ requirements:
808
+ - - ~>
809
+ - !ruby/object:Gem::Version
810
+ version: 2.6.0
811
+ - !ruby/object:Gem::Dependency
812
+ name: shoulda
813
+ requirement: !ruby/object:Gem::Requirement
814
+ requirements:
815
+ - - '>='
816
+ - !ruby/object:Gem::Version
817
+ version: '0'
818
+ type: :development
819
+ prerelease: false
820
+ version_requirements: !ruby/object:Gem::Requirement
821
+ requirements:
822
+ - - '>='
823
+ - !ruby/object:Gem::Version
824
+ version: '0'
825
+ - !ruby/object:Gem::Dependency
826
+ name: rdoc
827
+ requirement: !ruby/object:Gem::Requirement
828
+ requirements:
829
+ - - '>='
830
+ - !ruby/object:Gem::Version
831
+ version: '0'
832
+ type: :development
833
+ prerelease: false
834
+ version_requirements: !ruby/object:Gem::Requirement
835
+ requirements:
836
+ - - '>='
837
+ - !ruby/object:Gem::Version
838
+ version: '0'
839
+ - !ruby/object:Gem::Dependency
840
+ name: bundler
841
+ requirement: !ruby/object:Gem::Requirement
842
+ requirements:
843
+ - - '>='
844
+ - !ruby/object:Gem::Version
845
+ version: '0'
846
+ type: :development
847
+ prerelease: false
848
+ version_requirements: !ruby/object:Gem::Requirement
849
+ requirements:
850
+ - - '>='
851
+ - !ruby/object:Gem::Version
852
+ version: '0'
853
+ - !ruby/object:Gem::Dependency
854
+ name: jeweler
855
+ requirement: !ruby/object:Gem::Requirement
856
+ requirements:
857
+ - - ~>
858
+ - !ruby/object:Gem::Version
859
+ version: 1.8.4
860
+ type: :development
861
+ prerelease: false
862
+ version_requirements: !ruby/object:Gem::Requirement
863
+ requirements:
864
+ - - ~>
865
+ - !ruby/object:Gem::Version
866
+ version: 1.8.4
727
867
  - !ruby/object:Gem::Dependency
728
868
  name: thor
729
869
  requirement: !ruby/object:Gem::Requirement