smart_message 0.0.4 → 0.0.6
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +118 -0
- data/Gemfile.lock +1 -1
- data/README.md +299 -10
- data/docs/README.md +1 -0
- data/docs/addressing.md +364 -0
- data/docs/architecture.md +2 -0
- data/docs/examples.md +2 -0
- data/docs/getting-started.md +49 -0
- data/docs/properties.md +213 -7
- data/examples/01_point_to_point_orders.rb +27 -11
- data/examples/02_publish_subscribe_events.rb +16 -7
- data/examples/03_many_to_many_chat.rb +56 -22
- data/examples/04_redis_smart_home_iot.rb +48 -21
- data/examples/05_proc_handlers.rb +12 -5
- data/examples/06_custom_logger_example.rb +34 -13
- data/examples/07_error_handling_scenarios.rb +477 -0
- data/examples/08_entity_addressing_basic.rb +366 -0
- data/examples/08_entity_addressing_with_filtering.rb +418 -0
- data/examples/README.md +68 -0
- data/examples/tmux_chat/bot_agent.rb +4 -1
- data/examples/tmux_chat/shared_chat_system.rb +50 -22
- data/lib/smart_message/base.rb +306 -20
- data/lib/smart_message/dispatcher.rb +53 -5
- data/lib/smart_message/errors.rb +3 -0
- data/lib/smart_message/header.rb +46 -5
- data/lib/smart_message/property_descriptions.rb +5 -4
- data/lib/smart_message/property_validations.rb +141 -0
- data/lib/smart_message/transport/base.rb +3 -2
- data/lib/smart_message/transport/redis_transport.rb +2 -2
- data/lib/smart_message/version.rb +1 -1
- metadata +6 -1
@@ -0,0 +1,141 @@
|
|
1
|
+
# lib/smart_message/property_validations.rb
|
2
|
+
# encoding: utf-8
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
module SmartMessage
|
6
|
+
module PropertyValidations
|
7
|
+
def self.included(base)
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
base.class_eval do
|
10
|
+
@property_validators = {}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def property(property_name, options = {})
|
16
|
+
# Extract our custom options before passing to Hashie::Dash
|
17
|
+
# Note: Hashie's 'message' option only works with 'required', so we use 'validation_message'
|
18
|
+
validator = options.delete(:validate)
|
19
|
+
validation_message = options.delete(:validation_message)
|
20
|
+
|
21
|
+
# Call original property method first
|
22
|
+
super(property_name, options)
|
23
|
+
|
24
|
+
# Then store validator if provided
|
25
|
+
if validator
|
26
|
+
@property_validators ||= {}
|
27
|
+
@property_validators[property_name.to_sym] = {
|
28
|
+
validator: validator,
|
29
|
+
message: validation_message || "Validation failed for property '#{property_name}'"
|
30
|
+
}
|
31
|
+
|
32
|
+
# Note: We don't override setter methods since they may conflict with Hashie::Dash
|
33
|
+
# Instead, validation happens during validate! calls
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def property_validator(property_name)
|
38
|
+
@property_validators&.[](property_name.to_sym)
|
39
|
+
end
|
40
|
+
|
41
|
+
def property_validators
|
42
|
+
@property_validators&.dup || {}
|
43
|
+
end
|
44
|
+
|
45
|
+
def validated_properties
|
46
|
+
@property_validators&.keys || []
|
47
|
+
end
|
48
|
+
|
49
|
+
# Validate all properties with validators
|
50
|
+
def validate_all(instance)
|
51
|
+
validated_properties.each do |property_name|
|
52
|
+
validator_info = property_validator(property_name)
|
53
|
+
next unless validator_info
|
54
|
+
|
55
|
+
value = instance.send(property_name)
|
56
|
+
validator = validator_info[:validator]
|
57
|
+
error_message = validator_info[:message]
|
58
|
+
|
59
|
+
# Skip validation if value is nil and property is not required
|
60
|
+
next if value.nil? && !instance.class.required_properties.include?(property_name)
|
61
|
+
|
62
|
+
# Perform validation
|
63
|
+
is_valid = case validator
|
64
|
+
when Proc
|
65
|
+
instance.instance_exec(value, &validator)
|
66
|
+
when Symbol
|
67
|
+
instance.send(validator, value)
|
68
|
+
when Regexp
|
69
|
+
!!(value.to_s =~ validator)
|
70
|
+
when Class
|
71
|
+
value.is_a?(validator)
|
72
|
+
when Array
|
73
|
+
validator.include?(value)
|
74
|
+
when Range
|
75
|
+
validator.include?(value)
|
76
|
+
else
|
77
|
+
value == validator
|
78
|
+
end
|
79
|
+
|
80
|
+
unless is_valid
|
81
|
+
raise SmartMessage::Errors::ValidationError, "#{instance.class.name}##{property_name}: #{error_message}"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
true
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Instance methods
|
89
|
+
def validate!
|
90
|
+
self.class.validate_all(self)
|
91
|
+
end
|
92
|
+
|
93
|
+
def valid?
|
94
|
+
validate!
|
95
|
+
true
|
96
|
+
rescue SmartMessage::Errors::ValidationError
|
97
|
+
false
|
98
|
+
end
|
99
|
+
|
100
|
+
def validation_errors
|
101
|
+
errors = []
|
102
|
+
self.class.validated_properties.each do |property_name|
|
103
|
+
validator_info = self.class.property_validator(property_name)
|
104
|
+
next unless validator_info
|
105
|
+
|
106
|
+
value = send(property_name)
|
107
|
+
validator = validator_info[:validator]
|
108
|
+
|
109
|
+
# Skip validation if value is nil and property is not required
|
110
|
+
next if value.nil? && !self.class.required_properties.include?(property_name)
|
111
|
+
|
112
|
+
# Perform validation
|
113
|
+
is_valid = case validator
|
114
|
+
when Proc
|
115
|
+
instance_exec(value, &validator)
|
116
|
+
when Symbol
|
117
|
+
send(validator, value)
|
118
|
+
when Regexp
|
119
|
+
!!(value.to_s =~ validator)
|
120
|
+
when Class
|
121
|
+
value.is_a?(validator)
|
122
|
+
when Array
|
123
|
+
validator.include?(value)
|
124
|
+
when Range
|
125
|
+
validator.include?(value)
|
126
|
+
else
|
127
|
+
value == validator
|
128
|
+
end
|
129
|
+
|
130
|
+
unless is_valid
|
131
|
+
errors << {
|
132
|
+
property: property_name,
|
133
|
+
value: value,
|
134
|
+
message: validator_info[:message]
|
135
|
+
}
|
136
|
+
end
|
137
|
+
end
|
138
|
+
errors
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -35,8 +35,9 @@ module SmartMessage
|
|
35
35
|
# Subscribe to a message class
|
36
36
|
# @param message_class [String] The message class name
|
37
37
|
# @param process_method [String] The processing method identifier
|
38
|
-
|
39
|
-
|
38
|
+
# @param filter_options [Hash] Optional filtering criteria
|
39
|
+
def subscribe(message_class, process_method, filter_options = {})
|
40
|
+
@dispatcher.add(message_class, process_method, filter_options)
|
40
41
|
end
|
41
42
|
|
42
43
|
# Unsubscribe from a specific message class and process method
|
@@ -46,8 +46,8 @@ module SmartMessage
|
|
46
46
|
end
|
47
47
|
|
48
48
|
# Subscribe to a message class (Redis channel)
|
49
|
-
def subscribe(message_class, process_method)
|
50
|
-
super(message_class, process_method)
|
49
|
+
def subscribe(message_class, process_method, filter_options = {})
|
50
|
+
super(message_class, process_method, filter_options)
|
51
51
|
|
52
52
|
@mutex.synchronize do
|
53
53
|
@subscribed_channels.add(message_class)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smart_message
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dewayne VanHoozer
|
@@ -199,6 +199,7 @@ files:
|
|
199
199
|
- bin/console
|
200
200
|
- bin/setup
|
201
201
|
- docs/README.md
|
202
|
+
- docs/addressing.md
|
202
203
|
- docs/architecture.md
|
203
204
|
- docs/dispatcher.md
|
204
205
|
- docs/examples.md
|
@@ -218,6 +219,9 @@ files:
|
|
218
219
|
- examples/04_redis_smart_home_iot.rb
|
219
220
|
- examples/05_proc_handlers.rb
|
220
221
|
- examples/06_custom_logger_example.rb
|
222
|
+
- examples/07_error_handling_scenarios.rb
|
223
|
+
- examples/08_entity_addressing_basic.rb
|
224
|
+
- examples/08_entity_addressing_with_filtering.rb
|
221
225
|
- examples/README.md
|
222
226
|
- examples/smart_home_iot_dataflow.md
|
223
227
|
- examples/tmux_chat/README.md
|
@@ -238,6 +242,7 @@ files:
|
|
238
242
|
- lib/smart_message/logger/base.rb
|
239
243
|
- lib/smart_message/logger/default.rb
|
240
244
|
- lib/smart_message/property_descriptions.rb
|
245
|
+
- lib/smart_message/property_validations.rb
|
241
246
|
- lib/smart_message/serializer.rb
|
242
247
|
- lib/smart_message/serializer/base.rb
|
243
248
|
- lib/smart_message/serializer/json.rb
|