wonkavision 0.5.4 → 0.5.9

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.
Files changed (37) hide show
  1. data/CHANGELOG.rdoc +28 -16
  2. data/Gemfile +5 -0
  3. data/LICENSE.txt +21 -21
  4. data/Rakefile +47 -47
  5. data/lib/wonkavision.rb +75 -74
  6. data/lib/wonkavision/acts_as_oompa_loompa.rb +22 -22
  7. data/lib/wonkavision/event_binding.rb +21 -21
  8. data/lib/wonkavision/event_context.rb +9 -9
  9. data/lib/wonkavision/event_coordinator.rb +75 -75
  10. data/lib/wonkavision/event_handler.rb +15 -15
  11. data/lib/wonkavision/event_namespace.rb +79 -79
  12. data/lib/wonkavision/event_path_segment.rb +35 -35
  13. data/lib/wonkavision/message_mapper.rb +30 -30
  14. data/lib/wonkavision/message_mapper/indifferent_access.rb +30 -26
  15. data/lib/wonkavision/message_mapper/map.rb +241 -153
  16. data/lib/wonkavision/persistence/mongo_mapper_adapter.rb +32 -32
  17. data/lib/wonkavision/persistence/mongoid_adapter.rb +32 -0
  18. data/lib/wonkavision/plugins.rb +30 -30
  19. data/lib/wonkavision/plugins/business_activity.rb +92 -92
  20. data/lib/wonkavision/plugins/business_activity/event_binding.rb +15 -15
  21. data/lib/wonkavision/plugins/callbacks.rb +182 -182
  22. data/lib/wonkavision/plugins/event_handling.rb +111 -111
  23. data/lib/wonkavision/plugins/timeline.rb +79 -79
  24. data/lib/wonkavision/version.rb +3 -3
  25. data/test/business_activity_test.rb +31 -31
  26. data/test/event_handler_test.rb +68 -69
  27. data/test/event_namespace_test.rb +108 -108
  28. data/test/event_path_segment_test.rb +41 -41
  29. data/test/log/test.log +817 -18354
  30. data/test/map_test.rb +315 -201
  31. data/test/message_mapper_test.rb +20 -20
  32. data/test/test_activity_models.rb +72 -72
  33. data/test/test_helper.rb +70 -63
  34. data/test/timeline_test.rb +55 -61
  35. data/test/wonkavision_test.rb +9 -9
  36. metadata +72 -12
  37. data/wonkavision.gemspec +0 -97
@@ -1,111 +1,111 @@
1
- module Wonkavision
2
- module Plugins
3
- module EventHandling
4
-
5
- def self.configure(handler,options)
6
- handler.write_inheritable_attribute :event_handler_options, {}
7
- handler.class_inheritable_reader :event_handler_options
8
-
9
- handler.write_inheritable_attribute :bindings, []
10
- handler.class_inheritable_reader :bindings
11
-
12
- handler.write_inheritable_attribute :maps, []
13
- handler.class_inheritable_reader :maps
14
-
15
- end
16
-
17
- module ClassMethods
18
- def options
19
- event_handler_options
20
- end
21
-
22
- def event_path(event_name)
23
- return event_name.to_s if Wonkavision.is_absolute_path(event_name) #don't mess with an absolute path
24
- Wonkavision.join(event_namespace,event_name)
25
- end
26
-
27
- def event_namespace(namespace=nil)
28
- return event_handler_options[:event_namespace] unless namespace
29
- event_handler_options[:event_namespace] = namespace
30
- end
31
- alias :namespace :event_namespace
32
-
33
- def map(condition = nil,&block)
34
- maps << [condition,block]
35
- end
36
-
37
- def handle(name,*args,&block)
38
- binding = create_binding(name,self,*args)
39
- binding.subscribe_to_events do |event_data,event_path|
40
- ctx = Wonkavision::EventContext.new(event_data,event_path,binding,block)
41
- handler = instantiate_handler(ctx)
42
- handler.instance_variable_set(:@wonkavision_event_context, ctx)
43
- handler.handle_event
44
- end
45
- bindings << binding
46
- binding
47
- end
48
-
49
- def instantiate_handler(event_context)
50
- self.new
51
- end
52
-
53
- def create_binding(name,handler,*args)
54
- Wonkavision::EventBinding.new(name,handler,*args)
55
- end
56
-
57
- end
58
-
59
- module InstanceMethods
60
-
61
- def handled?
62
- @wonkavision_event_handled ||= false
63
- end
64
-
65
- def handled=(handled)
66
- @wonkavision_event_handled = handled
67
- end
68
-
69
- def event_context
70
- @wonkavision_event_context
71
- end
72
-
73
- def handle_event
74
- ctx = @wonkavision_event_context
75
- ctx.data = map(ctx.data,ctx.path)
76
- handler = ctx.callback
77
-
78
- if handler && handler.respond_to?(:call) && handler.respond_to?(:arity)
79
- case handler.arity
80
- when 3 then handler.call(ctx.data,ctx.path,self)
81
- when 2 then handler.call(ctx.data,ctx.path)
82
- when 1 then handler.call (ctx.data)
83
- else instance_eval &handler
84
- end
85
- end
86
- end
87
-
88
- protected
89
- def map(data,path)
90
- self.class.maps.each do |map_def|
91
- condition = map_def[0]
92
- map_block = map_def[1]
93
- return Wonkavision::MessageMapper.execute(map_block,data) if map?(condition,data,path)
94
- end
95
- data.is_a?(Hash) ? data.dup : data
96
- end
97
-
98
- def map?(condition,data,path)
99
- return true unless condition && condition.to_s != 'all' && condition.to_s != '*'
100
- return path =~ condition if condition.is_a?(Regexp)
101
- if (condition.is_a?(Proc))
102
- return condition.call if condition.arity <= 0
103
- return condition.call(path) if condition.arity == 1
104
- return condition.call(path,data)
105
- end
106
- end
107
- end
108
-
109
- end
110
- end
111
- end
1
+ module Wonkavision
2
+ module Plugins
3
+ module EventHandling
4
+
5
+ def self.configure(handler,options)
6
+ handler.write_inheritable_attribute :event_handler_options, {}
7
+ handler.class_inheritable_reader :event_handler_options
8
+
9
+ handler.write_inheritable_attribute :bindings, []
10
+ handler.class_inheritable_reader :bindings
11
+
12
+ handler.write_inheritable_attribute :maps, []
13
+ handler.class_inheritable_reader :maps
14
+
15
+ end
16
+
17
+ module ClassMethods
18
+ def options
19
+ event_handler_options
20
+ end
21
+
22
+ def event_path(event_name)
23
+ return event_name.to_s if Wonkavision.is_absolute_path(event_name) #don't mess with an absolute path
24
+ Wonkavision.join(event_namespace,event_name)
25
+ end
26
+
27
+ def event_namespace(namespace=nil)
28
+ return event_handler_options[:event_namespace] unless namespace
29
+ event_handler_options[:event_namespace] = namespace
30
+ end
31
+ alias :namespace :event_namespace
32
+
33
+ def map(condition = nil,&block)
34
+ maps << [condition,block]
35
+ end
36
+
37
+ def handle(name,*args,&block)
38
+ binding = create_binding(name,self,*args)
39
+ binding.subscribe_to_events do |event_data,event_path|
40
+ ctx = Wonkavision::EventContext.new(event_data,event_path,binding,block)
41
+ handler = instantiate_handler(ctx)
42
+ handler.instance_variable_set(:@wonkavision_event_context, ctx)
43
+ handler.handle_event
44
+ end
45
+ bindings << binding
46
+ binding
47
+ end
48
+
49
+ def instantiate_handler(event_context)
50
+ self.new
51
+ end
52
+
53
+ def create_binding(name,handler,*args)
54
+ Wonkavision::EventBinding.new(name,handler,*args)
55
+ end
56
+
57
+ end
58
+
59
+ module InstanceMethods
60
+
61
+ def handled?
62
+ @wonkavision_event_handled ||= false
63
+ end
64
+
65
+ def handled=(handled)
66
+ @wonkavision_event_handled = handled
67
+ end
68
+
69
+ def event_context
70
+ @wonkavision_event_context
71
+ end
72
+
73
+ def handle_event
74
+ ctx = @wonkavision_event_context
75
+ ctx.data = map(ctx.data,ctx.path)
76
+ handler = ctx.callback
77
+
78
+ if handler && handler.respond_to?(:call) && handler.respond_to?(:arity)
79
+ case handler.arity
80
+ when 3 then handler.call(ctx.data,ctx.path,self)
81
+ when 2 then handler.call(ctx.data,ctx.path)
82
+ when 1 then handler.call(ctx.data)
83
+ else instance_eval &handler
84
+ end
85
+ end
86
+ end
87
+
88
+ protected
89
+ def map(data,path)
90
+ self.class.maps.each do |map_def|
91
+ condition = map_def[0]
92
+ map_block = map_def[1]
93
+ return Wonkavision::MessageMapper.execute(map_block,data) if map?(condition,data,path)
94
+ end
95
+ data.is_a?(Hash) ? data.dup : data
96
+ end
97
+
98
+ def map?(condition,data,path)
99
+ return true unless condition && condition.to_s != 'all' && condition.to_s != '*'
100
+ return path =~ condition if condition.is_a?(Regexp)
101
+ if (condition.is_a?(Proc))
102
+ return condition.call if condition.arity <= 0
103
+ return condition.call(path) if condition.arity == 1
104
+ return condition.call(path,data)
105
+ end
106
+ end
107
+ end
108
+
109
+ end
110
+ end
111
+ end
@@ -1,80 +1,80 @@
1
- module Wonkavision
2
- module Plugins
3
- module Timeline
4
- def self.all
5
- @@all ||= []
6
- end
7
-
8
- def self.configure(activity,options={})
9
- activity.ensure_wonkavision_plugin(Wonkavision::Plugins::BusinessActivity,options)
10
- activity.write_inheritable_attribute :timeline_milestones, []
11
- activity.class_inheritable_reader :timeline_milestones
12
-
13
- options = {
14
- :timeline_field => "timeline",
15
- :latest_milestone_field => "latest_milestone",
16
- :event_time_key => "event_time"
17
- }.merge(options)
18
-
19
- activity.business_activity_options.merge!(options)
20
-
21
- activity.define_document_key(activity.timeline_field,Hash,:default=>{})
22
- activity.define_document_key(activity.latest_milestone_field, String, :default=>"awaiting_first_event")
23
-
24
- Timeline.all << activity
25
- end
26
-
27
- module ClassMethods
28
-
29
- def milestone(name,*args)
30
- timeline_milestones << event(name,*args) do
31
- ctx = @wonkavision_event_context
32
- event_time = self.class.extract_event_time(ctx.data,ctx.path)
33
- prev_event_time = self[timeline_field][name]
34
- unless prev_event_time
35
- self[timeline_field][name] = event_time
36
- #If the event being processed happened earlier than a previously
37
- #recorded event, we don't want to overwrite state of the activity, as
38
- #it is already more up to date than the incoming event.
39
- latest_ms = self[latest_milestone_field]
40
- unless latest_ms &&
41
- (last_event = self[timeline_field][latest_ms]) &&
42
- last_event > event_time
43
- self.class.update_activity(self,ctx.data)
44
- self[latest_milestone_field] = name
45
- end
46
- :updated
47
- else
48
- :handled #If there was a previous event time for this milestone, we will just skip this event
49
- end
50
- end
51
- end
52
-
53
- def convert_time(time)
54
- if (time.is_a?(Hash)) && (time.keys.include?(:date) || time.keys.include?(:time))
55
- time = "#{time[:date]} #{time[:time]}".strip
56
- end
57
- time ? time.to_time : nil
58
- end
59
-
60
- def extract_event_time(event_data,event_path)
61
- convert_time(event_data.delete(event_time_key.to_s)) || Time.now.utc
62
- end
63
- end
64
-
65
- module Fields
66
- def timeline_field
67
- business_activity_options[:timeline_field]
68
- end
69
-
70
- def latest_milestone_field
71
- business_activity_options[:latest_milestone_field]
72
- end
73
-
74
- def event_time_key
75
- business_activity_options[:event_time_key]
76
- end
77
- end
78
- end
79
- end
1
+ module Wonkavision
2
+ module Plugins
3
+ module Timeline
4
+ def self.all
5
+ @@all ||= []
6
+ end
7
+
8
+ def self.configure(activity,options={})
9
+ activity.ensure_wonkavision_plugin(Wonkavision::Plugins::BusinessActivity,options)
10
+ activity.write_inheritable_attribute :timeline_milestones, []
11
+ activity.class_inheritable_reader :timeline_milestones
12
+
13
+ options = {
14
+ :timeline_field => "timeline",
15
+ :latest_milestone_field => "latest_milestone",
16
+ :event_time_key => "event_time"
17
+ }.merge(options)
18
+
19
+ activity.business_activity_options.merge!(options)
20
+
21
+ activity.define_document_key(activity.timeline_field,Hash,:default=>{})
22
+ activity.define_document_key(activity.latest_milestone_field, String, :default=>"awaiting_first_event")
23
+
24
+ Timeline.all << activity
25
+ end
26
+
27
+ module ClassMethods
28
+
29
+ def milestone(name,*args)
30
+ timeline_milestones << event(name,*args) do
31
+ ctx = @wonkavision_event_context
32
+ event_time = self.class.extract_event_time(ctx.data,ctx.path)
33
+ prev_event_time = self[timeline_field][name]
34
+ unless prev_event_time
35
+ self[timeline_field][name] = event_time
36
+ #If the event being processed happened earlier than a previously
37
+ #recorded event, we don't want to overwrite state of the activity, as
38
+ #it is already more up to date than the incoming event.
39
+ latest_ms = self[latest_milestone_field]
40
+ unless latest_ms &&
41
+ (last_event = self[timeline_field][latest_ms]) &&
42
+ last_event > event_time
43
+ self.class.update_activity(self,ctx.data)
44
+ self[latest_milestone_field] = name
45
+ end
46
+ :updated
47
+ else
48
+ :handled #If there was a previous event time for this milestone, we will just skip this event
49
+ end
50
+ end
51
+ end
52
+
53
+ def convert_time(time)
54
+ if (time.is_a?(Hash)) && (time.keys.include?(:date) || time.keys.include?(:time))
55
+ time = "#{time[:date]} #{time[:time]}".strip
56
+ end
57
+ time ? time.to_time : nil
58
+ end
59
+
60
+ def extract_event_time(event_data,event_path)
61
+ convert_time(event_data.delete(event_time_key.to_s)) || Time.now.utc
62
+ end
63
+ end
64
+
65
+ module Fields
66
+ def timeline_field
67
+ business_activity_options[:timeline_field]
68
+ end
69
+
70
+ def latest_milestone_field
71
+ business_activity_options[:latest_milestone_field]
72
+ end
73
+
74
+ def event_time_key
75
+ business_activity_options[:event_time_key]
76
+ end
77
+ end
78
+ end
79
+ end
80
80
  end
@@ -1,3 +1,3 @@
1
- module Wonkavision
2
- VERSION = '0.5.4'
3
- end
1
+ module Wonkavision
2
+ VERSION = '0.5.9'
3
+ end
@@ -1,31 +1,31 @@
1
- require "test_helper"
2
- require "test_activity_models"
3
-
4
- class BusinessActivityTest < ActiveSupport::TestCase
5
- context "TestBusinessActivity" do
6
- should "configure namespace from DSL" do
7
- assert_equal :test, TestBusinessActivity.event_namespace
8
- end
9
- should "configure correlation identifiers from DSL" do
10
- assert_equal({:event=>:test_id, :model=>:test_id}, TestBusinessActivity.correlate_by)
11
- end
12
- should "register activity with global registry" do
13
- assert_equal 1, Wonkavision::Plugins::BusinessActivity.all.length
14
- assert_equal TestBusinessActivity, Wonkavision::Plugins::BusinessActivity.all[0]
15
- end
16
-
17
- should "register correlation ids with each activity" do
18
- ids = Wonkavision::Plugins::BusinessActivity.all[0].correlation_ids
19
- assert_equal 1, ids.length
20
- assert_equal :test_id, ids[0][:event]
21
- end
22
-
23
- should "use per binding correlation ids when specified" do
24
- event = {"alt_event_id"=>"123","another_field"=>"hi there"}
25
- Wonkavision.event_coordinator.receive_event("test/evt5",event)
26
- assert activity = TestBusinessActivity.find_by_alt_model_id("123")
27
- assert_equal "hi there", activity.another_field
28
- end
29
-
30
- end
31
- end
1
+ require "test_helper"
2
+ require "test_activity_models"
3
+
4
+ class BusinessActivityTest < ActiveSupport::TestCase
5
+ context "TestBusinessActivity" do
6
+ should "configure namespace from DSL" do
7
+ assert_equal :test, TestBusinessActivity.event_namespace
8
+ end
9
+ should "configure correlation identifiers from DSL" do
10
+ assert_equal({:event=>:test_id, :model=>:test_id}, TestBusinessActivity.correlate_by)
11
+ end
12
+ should "register activity with global registry" do
13
+ assert_equal 1, Wonkavision::Plugins::BusinessActivity.all.length
14
+ assert_equal TestBusinessActivity, Wonkavision::Plugins::BusinessActivity.all[0]
15
+ end
16
+
17
+ should "register correlation ids with each activity" do
18
+ ids = Wonkavision::Plugins::BusinessActivity.all[0].correlation_ids
19
+ assert_equal 1, ids.length
20
+ assert_equal :test_id, ids[0][:event]
21
+ end
22
+
23
+ should "use per binding correlation ids when specified" do
24
+ event = {"alt_event_id"=>"123","another_field"=>"hi there"}
25
+ Wonkavision.event_coordinator.receive_event("test/evt5",event)
26
+ assert activity = TestBusinessActivity.first(:conditions=>{:alt_model_id=>"123"})
27
+ assert_equal "hi there", activity.another_field
28
+ end
29
+
30
+ end
31
+ end