wonkavision 0.5.4 → 0.5.9

Sign up to get free protection for your applications and to get access to all the features.
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