communicator 0.2.2 → 0.2.3
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/lib/communicator.rb +12 -8
- data/lib/communicator/active_record_integration.rb +3 -6
- data/lib/communicator/exception_handler.rb +42 -0
- data/lib/communicator/inbound_message.rb +11 -9
- data/lib/communicator/server.rb +43 -29
- data/lib/communicator/tasks.rb +7 -5
- data/lib/communicator/version.rb +1 -1
- metadata +5 -4
data/lib/communicator.rb
CHANGED
@@ -10,6 +10,14 @@ module Communicator
|
|
10
10
|
|
11
11
|
# Error to be raised when no credentials were given
|
12
12
|
class MissingCredentials < StandardError; end;
|
13
|
+
|
14
|
+
autoload :Server, 'communicator/server'
|
15
|
+
autoload :Client, 'communicator/client'
|
16
|
+
autoload :ExceptionHandler, 'communicator/exception_handler'
|
17
|
+
autoload :ActiveRecordIntegration, 'communicator/active_record_integration'
|
18
|
+
autoload :OutboundMessage, 'communicator/outbound_message'
|
19
|
+
autoload :InboundMessage, 'communicator/inbound_message'
|
20
|
+
autoload :Version, 'communicator/version'
|
13
21
|
|
14
22
|
# Fake logger to be returned as Communicator.logger when Rails is unavailable
|
15
23
|
class FakeLogger
|
@@ -61,14 +69,10 @@ module Communicator
|
|
61
69
|
end
|
62
70
|
end
|
63
71
|
|
64
|
-
|
65
|
-
|
66
|
-
require 'communicator/active_record_integration'
|
67
|
-
require 'communicator/outbound_message'
|
68
|
-
require 'communicator/inbound_message'
|
69
|
-
require 'communicator/version'
|
72
|
+
# Include class methods into active record base
|
73
|
+
ActiveRecord::Base.send :extend, Communicator::ActiveRecordIntegration::ClassMethods
|
70
74
|
|
71
|
-
# Autoload config when present for rails
|
75
|
+
# Autoload config from yaml when present for rails
|
72
76
|
if defined?(Rails)
|
73
77
|
config_path = File.join(Rails.root, 'config', 'communicator.yml')
|
74
78
|
if File.exist?(config_path)
|
@@ -78,4 +82,4 @@ if defined?(Rails)
|
|
78
82
|
Communicator::Server.password = Communicator::Client.password = config[:password]
|
79
83
|
Communicator::Client.base_uri config[:base_uri]
|
80
84
|
end
|
81
|
-
end
|
85
|
+
end
|
@@ -51,14 +51,11 @@ module Communicator::ActiveRecordIntegration
|
|
51
51
|
|
52
52
|
rescue => err
|
53
53
|
Communicator.logger.warn "Failed to process message on #{self.class} ##{id}! Errors: #{self.errors.map{|k,v| "#{k}: #{v}"}.join(", ")}"
|
54
|
-
if respond_to?(:
|
55
|
-
|
54
|
+
if err.respond_to?(:context)
|
55
|
+
err.context["Validation Errors"] = "Errors: #{self.errors.map{|k,v| "#{k}: #{v}"}.join(", ")}"
|
56
|
+
err.context["JSON Input"] = input.inspect
|
56
57
|
end
|
57
58
|
raise err
|
58
59
|
end
|
59
60
|
end
|
60
61
|
end
|
61
|
-
|
62
|
-
# Include class methods into active record base
|
63
|
-
ActiveRecord::Base.send :extend, Communicator::ActiveRecordIntegration::ClassMethods
|
64
|
-
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Communicator::ExceptionHandler
|
2
|
+
class << self
|
3
|
+
def publish_and_reraise(err, subsections)
|
4
|
+
# Notify using capita/exception_notification fork, but only
|
5
|
+
# when notifications are not locked
|
6
|
+
if respond_to?(:report_exception) and not locked?
|
7
|
+
report_exception err, subsections
|
8
|
+
lock!
|
9
|
+
end
|
10
|
+
|
11
|
+
# Always re-raise!
|
12
|
+
raise err
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns the path to the lockfile, either in rails/tmp if present,
|
16
|
+
# otherwise in system-wide tmp
|
17
|
+
def lockfile
|
18
|
+
if defined?(Rails)
|
19
|
+
Rails.root.join('tmp', 'communicator_exception.lock')
|
20
|
+
else
|
21
|
+
'/tmp/communicator_exception.lock'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Checks whether mailing exceptions is currently locked
|
26
|
+
def locked?
|
27
|
+
File.exist?(lockfile)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Creates the exception notifier lockfile
|
31
|
+
def lock!
|
32
|
+
File.open(lockfile, "w+") do |f|
|
33
|
+
f.puts "Locked at #{Time.now}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Removes the exception notifier lockfile
|
38
|
+
def unlock!
|
39
|
+
File.unlink(lockfile) if locked?
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -20,10 +20,11 @@ class Communicator::InboundMessage < ActiveRecord::Base
|
|
20
20
|
inbound_msg
|
21
21
|
|
22
22
|
rescue => err
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
# Add context to exception when using capita/exception_notification fork
|
24
|
+
if err.respond_to?(:context)
|
25
|
+
err.context["Validation Errors"] = "Errors: #{inbound_msg.errors.map{|k,v| "#{k}: #{v}"}.join(", ")}"
|
26
|
+
err.context["Inbound Message"] = inbound_msg.attributes.inspect
|
27
|
+
err.context["JSON Message"] = json_message.inspect
|
27
28
|
end
|
28
29
|
|
29
30
|
raise err
|
@@ -74,11 +75,12 @@ class Communicator::InboundMessage < ActiveRecord::Base
|
|
74
75
|
rescue => err
|
75
76
|
Communicator.logger.warn "Failed to store inbound message ##{id}! Errors: #{self.errors.map{|k,v| "#{k}: #{v}"}.join(", ")}"
|
76
77
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
78
|
+
# Add context to exception when using capita/exception_notification fork
|
79
|
+
if err.respond_to?(:context)
|
80
|
+
err.context["Validation Errors"] = "Errors: #{self.errors.map{|k,v| "#{k}: #{v}"}.join(", ")}"
|
81
|
+
err.context["Inbound Message"] = self.attributes.inspect
|
82
|
+
err.context["JSON Content"] = self.message_content.inspect
|
83
|
+
end
|
82
84
|
|
83
85
|
raise err
|
84
86
|
end
|
data/lib/communicator/server.rb
CHANGED
@@ -36,41 +36,55 @@ class Communicator::Server < Sinatra::Base
|
|
36
36
|
protected!
|
37
37
|
# Require from_id attribute
|
38
38
|
return [409, "Specify from_id!"] unless params[:from_id]
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
39
|
+
|
40
|
+
begin
|
41
|
+
# from_id is irrelevant when no messages are present
|
42
|
+
params[:from_id] = nil if Communicator::OutboundMessage.count == 0
|
43
|
+
|
44
|
+
# Fetch the messages and build the json
|
45
|
+
messages = Communicator::OutboundMessage.delivery_collection(params[:from_id])
|
46
|
+
json = messages.map(&:payload).to_json
|
47
|
+
# Flag the messages as delivered
|
48
|
+
messages.each {|m| m.delivered! }
|
49
|
+
|
50
|
+
# Collect the message payloads and render them as json
|
51
|
+
[200, json]
|
52
|
+
|
53
|
+
rescue => err
|
54
|
+
Communicator::ExceptionHandler.publish_and_reraise err, "Status" => "Server failed to publish outbound messages!"
|
55
|
+
end
|
50
56
|
end
|
51
57
|
|
52
58
|
# PUSH
|
53
59
|
post '/messages.json' do
|
54
60
|
protected!
|
55
61
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
62
|
+
begin
|
63
|
+
body = request.body.read.strip
|
64
|
+
# Make sure a message body is given!
|
65
|
+
return [409, "No data given"] if body.length < 2
|
66
|
+
# Parse json
|
67
|
+
json_messages = JSON.parse(body)
|
68
|
+
|
69
|
+
# If no messages present, just return
|
70
|
+
return [202, "No data given"] unless json_messages.length > 0
|
71
|
+
|
72
|
+
# Make sure the first id does directly follow the last one present locally - but only if we already have ANY messages
|
73
|
+
# On failure, render HTTPConflicht and expected from_id
|
74
|
+
return [409, (Communicator::InboundMessage.last_id + 1).to_s] unless Communicator::InboundMessage.valid_next_id?(json_messages.first["id"])
|
75
|
+
|
76
|
+
# Everything's fine? Let's store messages!
|
77
|
+
Communicator::InboundMessage.create_from_json_collection!(json_messages)
|
78
|
+
|
79
|
+
# Unlock from exceptions after successfull PUSH
|
80
|
+
Communicator::ExceptionHandler.unlock!
|
81
|
+
|
82
|
+
202 # ACCEPTED
|
83
|
+
|
84
|
+
rescue => err
|
85
|
+
Communicator::ExceptionHandler.publish_and_reraise err, "Status" => "Server failed to receive inbound messages!"
|
86
|
+
end
|
73
87
|
end
|
74
88
|
end
|
75
89
|
|
76
|
-
require 'pp'
|
90
|
+
require 'pp'
|
data/lib/communicator/tasks.rb
CHANGED
@@ -20,16 +20,18 @@ namespace :communicator do
|
|
20
20
|
begin
|
21
21
|
Communicator::Client.push
|
22
22
|
rescue => err
|
23
|
-
|
24
|
-
raise err
|
23
|
+
Communicator::ExceptionHandler.publish_and_reraise err, "Status" => "Sync failed while trying to PUSH messages"
|
25
24
|
end
|
26
25
|
|
27
26
|
begin
|
28
27
|
Communicator::Client.pull
|
29
28
|
rescue => err
|
30
|
-
|
31
|
-
raise err
|
29
|
+
Communicator::ExceptionHandler.publish_and_reraise err, "Status" => "Sync failed while trying to PULL messages"
|
32
30
|
end
|
31
|
+
|
32
|
+
# If everything's fine, make sure exception notifications are unlocked and get
|
33
|
+
# delivered again on next occurence
|
34
|
+
Communicator::ExceptionHandler.unlock!
|
33
35
|
end
|
34
36
|
|
35
37
|
desc "Purges inbound and outbound messages - USE WITH CAUTION!!"
|
@@ -37,4 +39,4 @@ namespace :communicator do
|
|
37
39
|
Communicator::InboundMessage.delete_all
|
38
40
|
Communicator::OutboundMessage.delete_all
|
39
41
|
end
|
40
|
-
end
|
42
|
+
end
|
data/lib/communicator/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: communicator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 3
|
10
|
+
version: 0.2.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Christoph Olszowka
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-02-
|
18
|
+
date: 2011-02-22 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -198,6 +198,7 @@ files:
|
|
198
198
|
- lib/communicator.rb
|
199
199
|
- lib/communicator/active_record_integration.rb
|
200
200
|
- lib/communicator/client.rb
|
201
|
+
- lib/communicator/exception_handler.rb
|
201
202
|
- lib/communicator/inbound_message.rb
|
202
203
|
- lib/communicator/outbound_message.rb
|
203
204
|
- lib/communicator/server.rb
|