rhosync 2.1.17.beta3 → 2.1.17.beta4
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.
- data/CHANGELOG +1 -0
- data/lib/rhosync/jobs/ping_job.rb +50 -29
- data/lib/rhosync/ping/android.rb +21 -20
- data/lib/rhosync/ping/apple.rb +18 -16
- data/lib/rhosync/ping/blackberry.rb +9 -9
- data/lib/rhosync/version.rb +1 -1
- data/spec/jobs/ping_job_spec.rb +36 -0
- data/spec/ping/android_spec.rb +14 -0
- data/spec/ping/apple_spec.rb +7 -0
- data/spec/ping/blackberry_spec.rb +19 -0
- metadata +5 -5
data/CHANGELOG
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
## 2.1.17 (not yet released)
|
|
2
|
+
* #29214293 - do not execute ping if the platform is not configured
|
|
2
3
|
* Refactor server middleware. Remove explicit rack dependency. Fix broken rspec examples.
|
|
3
4
|
* Fixing error with recursive loading of application.rb in ruby-1.8.7 and ree
|
|
4
5
|
* #28330213 - Implementing fast_insert/update/delete API
|
|
@@ -4,43 +4,64 @@ module Rhosync
|
|
|
4
4
|
module PingJob
|
|
5
5
|
@queue = :ping
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
# Perform a ping for all clients registered to a user
|
|
8
8
|
def self.perform(params)
|
|
9
|
-
user = User.load(params["user_id"])
|
|
10
9
|
device_pins = []
|
|
11
|
-
phone_ids
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
10
|
+
phone_ids = []
|
|
11
|
+
user_ids = params['user_id']
|
|
12
|
+
user_ids = [user_ids] unless user_ids.is_a? Array
|
|
13
|
+
errors = []
|
|
14
|
+
user_ids.each do |user|
|
|
15
|
+
user_errors = ping_by_user user, params, device_pins, phone_ids
|
|
16
|
+
errors = errors + user_errors if user_errors
|
|
17
|
+
end
|
|
18
|
+
if errors.size != 0
|
|
19
|
+
joined_err = errors.join '\n'
|
|
20
|
+
raise joined_err
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.ping_by_user(user_id, params, device_pins, phone_ids)
|
|
25
|
+
# all errors are recorded here
|
|
26
|
+
errors = []
|
|
27
|
+
user = User.load(user_id)
|
|
28
|
+
user.clients.members.each do |client_id|
|
|
29
|
+
client = Client.load(client_id,{:source_name => '*'})
|
|
30
|
+
params.merge!('device_port' => client.device_port, 'device_pin' => client.device_pin, 'phone_id' => client.phone_id)
|
|
31
|
+
send_push = false
|
|
32
|
+
if client.device_type and client.device_type.size > 0
|
|
33
|
+
if client.phone_id and client.phone_id.size > 0
|
|
34
|
+
unless phone_ids.include? client.phone_id
|
|
35
|
+
phone_ids << client.phone_id
|
|
36
|
+
send_push = true
|
|
37
|
+
end
|
|
38
|
+
elsif client.device_pin and client.device_pin.size > 0
|
|
39
|
+
unless device_pins.include? client.device_pin
|
|
40
|
+
device_pins << client.device_pin
|
|
41
|
+
send_push = true
|
|
42
|
+
end
|
|
43
|
+
else
|
|
44
|
+
log "Skipping ping for non-registered client_id '#{client_id}'..."
|
|
45
|
+
next
|
|
21
46
|
end
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
47
|
+
if send_push
|
|
48
|
+
klass = Object.const_get(camelize(client.device_type.downcase))
|
|
49
|
+
if klass
|
|
50
|
+
params['vibrate'] = params['vibrate'].to_s
|
|
51
|
+
begin
|
|
52
|
+
klass.ping(params)
|
|
53
|
+
rescue Exception => e
|
|
54
|
+
errors << e
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
else
|
|
58
|
+
log "Dropping ping request for client_id '#{client_id}' because it's already in user's device pin or phone_id list."
|
|
26
59
|
end
|
|
27
60
|
else
|
|
28
61
|
log "Skipping ping for non-registered client_id '#{client_id}'..."
|
|
29
|
-
next
|
|
30
62
|
end
|
|
31
|
-
if send_push
|
|
32
|
-
klass = Object.const_get(camelize(client.device_type.downcase))
|
|
33
|
-
if klass
|
|
34
|
-
params['vibrate'] = params['vibrate'].to_s
|
|
35
|
-
klass.ping(params)
|
|
36
|
-
end
|
|
37
|
-
else
|
|
38
|
-
log "Dropping ping request for client_id '#{client_id}' because it's already in user's device pin or phone_id list."
|
|
39
|
-
end
|
|
40
|
-
else
|
|
41
|
-
log "Skipping ping for non-registered client_id '#{client_id}'..."
|
|
42
63
|
end
|
|
43
|
-
|
|
64
|
+
errors
|
|
44
65
|
end
|
|
45
66
|
end
|
|
46
67
|
end
|
data/lib/rhosync/ping/android.rb
CHANGED
|
@@ -11,27 +11,28 @@ module Rhosync
|
|
|
11
11
|
begin
|
|
12
12
|
settings = get_config(Rhosync.base_directory)[Rhosync.environment]
|
|
13
13
|
authtoken = settings[:authtoken]
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
14
|
+
if(authtoken)
|
|
15
|
+
RestClient.post(
|
|
16
|
+
'https://android.apis.google.com/c2dm/send', c2d_message(params),
|
|
17
|
+
:authorization => "GoogleLogin auth=#{authtoken}"
|
|
18
|
+
) do |response, request, result, &block|
|
|
19
|
+
# return exceptions based on response code & body
|
|
20
|
+
case response.code
|
|
21
|
+
when 200
|
|
22
|
+
# TODO: Automate authtoken updates
|
|
23
|
+
if response[:update_client_auth]
|
|
24
|
+
raise StaleAuthToken.new(
|
|
25
|
+
"Stale auth token, please update :authtoken: in settings.yml."
|
|
26
|
+
)
|
|
27
|
+
# body will contain the exception class
|
|
28
|
+
elsif response.body =~ /^Error=(.*)$/
|
|
29
|
+
raise AndroidPingError.new("Android ping error: #{$1 || ''}")
|
|
30
|
+
else
|
|
31
|
+
response.return!(request, result, &block)
|
|
32
|
+
end
|
|
33
|
+
when 401, 403
|
|
34
|
+
raise InvalidAuthToken.new("Invalid auth token, please update :authtoken: in settings.yml.")
|
|
32
35
|
end
|
|
33
|
-
when 401, 403
|
|
34
|
-
raise InvalidAuthToken.new("Invalid auth token, please update :authtoken: in settings.yml.")
|
|
35
36
|
end
|
|
36
37
|
end
|
|
37
38
|
rescue Exception => error
|
data/lib/rhosync/ping/apple.rb
CHANGED
|
@@ -8,24 +8,26 @@ module Rhosync
|
|
|
8
8
|
cert = File.read(cert_file) if File.exists?(cert_file)
|
|
9
9
|
passphrase = settings[:iphonepassphrase]
|
|
10
10
|
host = settings[:iphoneserver]
|
|
11
|
-
port = settings[:iphoneport]
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
port = settings[:iphoneport]
|
|
12
|
+
if(cert and host and port)
|
|
13
|
+
begin
|
|
14
|
+
ssl_ctx = OpenSSL::SSL::SSLContext.new
|
|
15
|
+
ssl_ctx.key = OpenSSL::PKey::RSA.new(cert, passphrase)
|
|
16
|
+
ssl_ctx.cert = OpenSSL::X509::Certificate.new(cert)
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
socket = TCPSocket.new(host, port)
|
|
19
|
+
ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ssl_ctx)
|
|
20
|
+
ssl_socket.sync = true
|
|
21
|
+
ssl_socket.connect
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
ssl_socket.write(apn_message(params))
|
|
24
|
+
ssl_socket.close
|
|
25
|
+
socket.close
|
|
26
|
+
rescue SocketError => error
|
|
27
|
+
log "Error while sending ping: #{error}"
|
|
28
|
+
raise error
|
|
29
|
+
end
|
|
30
|
+
end
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
# Generates APNS package
|
|
@@ -7,17 +7,17 @@ module Rhosync
|
|
|
7
7
|
settings = get_config(Rhosync.base_directory)[Rhosync.environment]
|
|
8
8
|
host = settings[:mdsserver]
|
|
9
9
|
port = settings[:mdsserverport]
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
if (host and port)
|
|
11
|
+
headers = { "X-WAP-APPLICATION-ID" => "/",
|
|
12
|
+
"X-RIM-PUSH-DEST-PORT" => params['device_port'],
|
|
13
|
+
"CONTENT-TYPE" => 'multipart/related; type="application/xml"; boundary=asdlfkjiurwghasf'}
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
Net::HTTP.new(host,port).start do |http|
|
|
16
|
+
request = Net::HTTP::Post.new('/pap',headers)
|
|
17
|
+
request.body = pap_message(params)
|
|
18
|
+
http.request(request)
|
|
19
|
+
end
|
|
19
20
|
end
|
|
20
|
-
|
|
21
21
|
rescue Exception => error
|
|
22
22
|
log "Error while sending ping: #{error}"
|
|
23
23
|
raise error
|
data/lib/rhosync/version.rb
CHANGED
data/spec/jobs/ping_job_spec.rb
CHANGED
|
@@ -4,6 +4,21 @@ describe "PingJob" do
|
|
|
4
4
|
it_should_behave_like "SpecBootstrapHelper"
|
|
5
5
|
it_should_behave_like "SourceAdapterHelper"
|
|
6
6
|
|
|
7
|
+
before(:each) do
|
|
8
|
+
@u1_fields = {:login => 'testuser1'}
|
|
9
|
+
@u1 = User.create(@u1_fields)
|
|
10
|
+
@u1.password = 'testpass1'
|
|
11
|
+
@c1_fields = {
|
|
12
|
+
:device_type => 'Apple',
|
|
13
|
+
:device_pin => 'abcde',
|
|
14
|
+
:device_port => '3333',
|
|
15
|
+
:user_id => @u1.id,
|
|
16
|
+
:app_id => @a.id
|
|
17
|
+
}
|
|
18
|
+
@c1 = Client.create(@c1_fields,{:source_name => @s_fields[:name]})
|
|
19
|
+
@a.users << @u1.id
|
|
20
|
+
end
|
|
21
|
+
|
|
7
22
|
it "should perform apple ping" do
|
|
8
23
|
params = {"user_id" => @u.id, "api_token" => @api_token,
|
|
9
24
|
"sources" => [@s.name], "message" => 'hello world',
|
|
@@ -73,5 +88,26 @@ describe "PingJob" do
|
|
|
73
88
|
lambda { PingJob.perform(params) }.should_not raise_error
|
|
74
89
|
end
|
|
75
90
|
|
|
91
|
+
it "should process all pings even if some of them are failing" do
|
|
92
|
+
params = {"user_id" => [ @u.id, @u1.id], "api_token" => @api_token,
|
|
93
|
+
"sources" => [@s.name], "message" => 'hello world',
|
|
94
|
+
"vibrate" => '5', "badge" => '5', "sound" => 'hello.mp3', 'phone_id' => nil }
|
|
95
|
+
@c.phone_id = '3'
|
|
96
|
+
|
|
97
|
+
scrubbed_params = params.dup
|
|
98
|
+
scrubbed_params['vibrate'] = '5'
|
|
99
|
+
@c1.device_type = 'blackberry'
|
|
100
|
+
|
|
101
|
+
Apple.should_receive(:ping).with(params.merge!({'device_pin' => @c.device_pin, 'phone_id' => @c.phone_id, 'device_port' => @c.device_port})).and_return { raise SocketError.new("Socket failure") }
|
|
102
|
+
Blackberry.should_receive(:ping).with({'device_pin' => @c1.device_pin, 'device_port' => @c1.device_port}.merge!(scrubbed_params))
|
|
103
|
+
exception_raised = false
|
|
104
|
+
begin
|
|
105
|
+
PingJob.perform(params)
|
|
106
|
+
rescue Exception => e
|
|
107
|
+
exception_raised = true
|
|
108
|
+
end
|
|
109
|
+
exception_raised.should == true
|
|
110
|
+
end
|
|
111
|
+
|
|
76
112
|
|
|
77
113
|
end
|
data/spec/ping/android_spec.rb
CHANGED
|
@@ -13,6 +13,7 @@ describe "Ping Android" do
|
|
|
13
13
|
|
|
14
14
|
it "should ping android successfully" do
|
|
15
15
|
result = 'id=0:34234234134254%abc123\n'
|
|
16
|
+
Rhosync::Android.stub!(:get_config).and_return({:test => {:authtoken=>'test'}})
|
|
16
17
|
@response.stub!(:code).and_return(200)
|
|
17
18
|
@response.stub!(:body).and_return(result)
|
|
18
19
|
@response.stub!(:[]).and_return(false)
|
|
@@ -23,6 +24,7 @@ describe "Ping Android" do
|
|
|
23
24
|
|
|
24
25
|
it "should ping android with 503 connection error" do
|
|
25
26
|
error = 'Connection refused'
|
|
27
|
+
Rhosync::Android.stub!(:get_config).and_return({:test => {:authtoken=>'test'}})
|
|
26
28
|
@response.stub!(:body).and_return(error)
|
|
27
29
|
RestClient.stub!(:post).and_return { raise RestClient::Exception.new(@response,503) }
|
|
28
30
|
Android.should_receive(:log).twice
|
|
@@ -31,6 +33,7 @@ describe "Ping Android" do
|
|
|
31
33
|
|
|
32
34
|
it "should ping android with 200 error message" do
|
|
33
35
|
error = 'Error=QuotaExceeded'
|
|
36
|
+
Rhosync::Android.stub!(:get_config).and_return({:test => {:authtoken=>'test'}})
|
|
34
37
|
@response.stub!(:code).and_return(200)
|
|
35
38
|
@response.stub!(:body).and_return(error)
|
|
36
39
|
@response.stub!(:[]).and_return(nil)
|
|
@@ -43,6 +46,7 @@ describe "Ping Android" do
|
|
|
43
46
|
@response.stub!(:code).and_return(200)
|
|
44
47
|
@response.stub!(:body).and_return('')
|
|
45
48
|
@response.stub!(:[]).and_return({:update_client_auth => 'abc123'})
|
|
49
|
+
Rhosync::Android.stub!(:get_config).and_return({:test => {:authtoken=>'test'}})
|
|
46
50
|
RestClient.stub!(:post).and_yield(@response)
|
|
47
51
|
Android.should_receive(:log).twice
|
|
48
52
|
lambda { Android.ping(@params) }.should raise_error(
|
|
@@ -53,6 +57,7 @@ describe "Ping Android" do
|
|
|
53
57
|
it "should ping android with 401 error message" do
|
|
54
58
|
@response.stub!(:code).and_return(401)
|
|
55
59
|
@response.stub!(:body).and_return('')
|
|
60
|
+
Rhosync::Android.stub!(:get_config).and_return({:test => {:authtoken=>'test'}})
|
|
56
61
|
RestClient.stub!(:post).and_yield(@response)
|
|
57
62
|
Android.should_receive(:log).twice
|
|
58
63
|
lambda { Android.ping(@params) }.should raise_error(
|
|
@@ -80,4 +85,13 @@ describe "Ping Android" do
|
|
|
80
85
|
actual['collapse_key'] = "RAND_KEY" unless actual['collapse_key'].nil?
|
|
81
86
|
actual.should == expected
|
|
82
87
|
end
|
|
88
|
+
|
|
89
|
+
it "should do nothing if no token" do
|
|
90
|
+
Rhosync::Android.stub!(:get_config).and_return({:test => {}})
|
|
91
|
+
params = {"device_pin" => @c.device_pin,
|
|
92
|
+
"sources" => [], "message" => '', "vibrate" => '5', "sound" => 'hello.mp3'}
|
|
93
|
+
Rhosync::Android.should_receive(:get_config).once
|
|
94
|
+
RestClient.should_receive(:post).exactly(0).times
|
|
95
|
+
Android.ping(params)
|
|
96
|
+
end
|
|
83
97
|
end
|
data/spec/ping/apple_spec.rb
CHANGED
|
@@ -68,4 +68,11 @@ describe "Ping Apple" do
|
|
|
68
68
|
lambda { Apple.ping(@params) }.should raise_error(SocketError,error)
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
+
it "should do nothing if no cert or host or port" do
|
|
72
|
+
Rhosync::Apple.stub!(:get_config).and_return({:test => {:iphonecertfile=>"none"}})
|
|
73
|
+
Rhosync::Apple.should_receive(:get_config).once
|
|
74
|
+
OpenSSL::SSL::SSLContext.should_receive(:new).exactly(0).times
|
|
75
|
+
Apple.ping(@params)
|
|
76
|
+
end
|
|
77
|
+
|
|
71
78
|
end
|
|
@@ -27,10 +27,29 @@ describe "Ping Blackberry" do
|
|
|
27
27
|
it "should ping blackberry with connection error" do
|
|
28
28
|
error = 'Connection refused'
|
|
29
29
|
@http.stub!(:request).and_return { raise SocketError.new(error) }
|
|
30
|
+
Rhosync::Blackberry.stub!(:get_config).and_return({:test => {:mdsserver=>'testserver',:mdsserverport=>'testport'}})
|
|
31
|
+
Rhosync::Blackberry.should_receive(:get_config).once
|
|
30
32
|
Blackberry.should_receive(:log).once.with("Error while sending ping: #{error}")
|
|
31
33
|
lambda { Blackberry.ping(@params) }.should raise_error(SocketError,error)
|
|
32
34
|
end
|
|
33
35
|
|
|
36
|
+
it "should ping blackberry with connection error" do
|
|
37
|
+
error = 'Connection refused'
|
|
38
|
+
Rhosync::Blackberry.stub!(:get_config).and_return({:test => {:mdsserver=>'testserver',:mdsserverport=>'testport'}})
|
|
39
|
+
Rhosync::Blackberry.should_receive(:get_config).once
|
|
40
|
+
@http.stub!(:request).and_return { raise SocketError.new(error) }
|
|
41
|
+
Blackberry.should_receive(:log).once.with("Error while sending ping: #{error}")
|
|
42
|
+
lambda { Blackberry.ping(@params) }.should raise_error(SocketError,error)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "should do nothing if no host and port" do
|
|
46
|
+
error = 'Connection refused'
|
|
47
|
+
Rhosync::Blackberry.stub!(:get_config).and_return({:test => {}})
|
|
48
|
+
Rhosync::Blackberry.should_receive(:get_config).once
|
|
49
|
+
Net::HTTP.should_receive(:new).exactly(0).times
|
|
50
|
+
Blackberry.ping(@params)
|
|
51
|
+
end
|
|
52
|
+
|
|
34
53
|
it "should compute pap_message" do
|
|
35
54
|
expected = <<PAP
|
|
36
55
|
--asdlfkjiurwghasf
|
metadata
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rhosync
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
4
|
+
hash: 62196339
|
|
5
5
|
prerelease: 7
|
|
6
6
|
segments:
|
|
7
7
|
- 2
|
|
8
8
|
- 1
|
|
9
9
|
- 17
|
|
10
10
|
- beta
|
|
11
|
-
-
|
|
12
|
-
version: 2.1.17.
|
|
11
|
+
- 4
|
|
12
|
+
version: 2.1.17.beta4
|
|
13
13
|
platform: ruby
|
|
14
14
|
authors:
|
|
15
15
|
- Rhomobile
|
|
@@ -17,7 +17,7 @@ autorequire:
|
|
|
17
17
|
bindir: bin
|
|
18
18
|
cert_chain: []
|
|
19
19
|
|
|
20
|
-
date: 2012-05-
|
|
20
|
+
date: 2012-05-17 00:00:00 Z
|
|
21
21
|
dependencies:
|
|
22
22
|
- !ruby/object:Gem::Dependency
|
|
23
23
|
name: sinatra
|
|
@@ -582,7 +582,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
582
582
|
requirements: []
|
|
583
583
|
|
|
584
584
|
rubyforge_project:
|
|
585
|
-
rubygems_version: 1.8.
|
|
585
|
+
rubygems_version: 1.8.10
|
|
586
586
|
signing_key:
|
|
587
587
|
specification_version: 3
|
|
588
588
|
summary: RhoSync Synchronization Framework
|