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.
@@ -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