communicator 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- require 'communicator/server'
65
- require 'communicator/client'
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?(:report_exception)
55
- report_exception err, "Validation Errors" => "Errors: #{self.errors.map{|k,v| "#{k}: #{v}"}.join(", ")}", "JSON Input" => input.inspect
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
- if respond_to?(:report_exception)
24
- report_exception err, "Validation Errors" => "Errors: #{inbound_msg.errors.map{|k,v| "#{k}: #{v}"}.join(", ")}",
25
- "Inbound Message Record" => inbound_msg.attributes.inspect,
26
- "JSON Message" => json_message.inspect
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
- if respond_to?(:report_exception)
78
- report_exception err, "Validation Errors" => "Errors: #{self.errors.map{|k,v| "#{k}: #{v}"}.join(", ")}",
79
- "Inbound Message" => self.attributes.inspect,
80
- "JSON Content" => self.message_content.inspect
81
- end
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
@@ -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
- # from_id is irrelevant when no messages are present
41
- params[:from_id] = nil if Communicator::OutboundMessage.count == 0
42
-
43
- # Fetch the messages and build the json
44
- messages = Communicator::OutboundMessage.delivery_collection(params[:from_id])
45
- json = messages.map(&:payload).to_json
46
- # Flag the messages as delivered
47
- messages.each {|m| m.delivered! }
48
- # Collect the message payloads and render them as json
49
- [200, json]
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
- body = request.body.read.strip
57
- # Make sure a message body is given!
58
- return [409, "No data given"] if body.length < 2
59
- # Parse json
60
- json_messages = JSON.parse(body)
61
-
62
- # If no messages present, just return
63
- return [202, "No data given"] unless json_messages.length > 0
64
-
65
- # Make sure the first id does directly follow the last one present locally - but only if we already have ANY messages
66
- # On failure, render HTTPConflicht and expected from_id
67
- return [409, (Communicator::InboundMessage.last_id + 1).to_s] unless Communicator::InboundMessage.valid_next_id?(json_messages.first["id"])
68
-
69
- # Everything's fine? Let's store messages!
70
- Communicator::InboundMessage.create_from_json_collection!(json_messages)
71
-
72
- 202 # ACCEPTED
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'
@@ -20,16 +20,18 @@ namespace :communicator do
20
20
  begin
21
21
  Communicator::Client.push
22
22
  rescue => err
23
- report_exception err, "Status" => "Sync failed while trying to PUSH messages"
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
- report_exception err, "Status" => "Sync failed while trying to PULL messages"
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
@@ -1,3 +1,3 @@
1
1
  module Communicator
2
- VERSION = '0.2.2'
2
+ VERSION = '0.2.3'
3
3
  end
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: 19
4
+ hash: 17
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 2
10
- version: 0.2.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-14 00:00:00 +01:00
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