eventq 2.0.0.rc1
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 +7 -0
- data/README.md +336 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/eventq/aws.rb +38 -0
- data/lib/eventq/eventq_aws/README.md +53 -0
- data/lib/eventq/eventq_aws/aws_eventq_client.rb +120 -0
- data/lib/eventq/eventq_aws/aws_queue_client.rb +64 -0
- data/lib/eventq/eventq_aws/aws_queue_manager.rb +68 -0
- data/lib/eventq/eventq_aws/aws_queue_worker.rb +168 -0
- data/lib/eventq/eventq_aws/aws_status_checker.rb +25 -0
- data/lib/eventq/eventq_aws/aws_subscription_manager.rb +65 -0
- data/lib/eventq/eventq_aws/jruby/aws_queue_worker.rb +370 -0
- data/lib/eventq/eventq_aws/sns.rb +64 -0
- data/lib/eventq/eventq_aws/sqs.rb +112 -0
- data/lib/eventq/eventq_base/configuration.rb +33 -0
- data/lib/eventq/eventq_base/event_raised_exchange.rb +7 -0
- data/lib/eventq/eventq_base/event_raised_queue.rb +7 -0
- data/lib/eventq/eventq_base/eventq_client_contract.rb +9 -0
- data/lib/eventq/eventq_base/eventq_logger.rb +28 -0
- data/lib/eventq/eventq_base/exceptions/invalid_signature_exception.rb +9 -0
- data/lib/eventq/eventq_base/exceptions/worker_thread_error.rb +10 -0
- data/lib/eventq/eventq_base/exceptions.rb +2 -0
- data/lib/eventq/eventq_base/exchange.rb +5 -0
- data/lib/eventq/eventq_base/message_args.rb +23 -0
- data/lib/eventq/eventq_base/nonce_manager.rb +57 -0
- data/lib/eventq/eventq_base/queue.rb +27 -0
- data/lib/eventq/eventq_base/queue_message.rb +31 -0
- data/lib/eventq/eventq_base/queue_worker_contract.rb +23 -0
- data/lib/eventq/eventq_base/serialization_providers/binary_serialization_provider.rb +15 -0
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj/array_writer.rb +20 -0
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj/attribute_writer.rb +24 -0
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj/class_writer.rb +20 -0
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj/date_time_writer.rb +33 -0
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj/date_writer.rb +22 -0
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj/hash_writer.rb +18 -0
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj/rational_writer.rb +20 -0
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj/serializer.rb +17 -0
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj/time_writer.rb +18 -0
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj/value_writer.rb +16 -0
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj.rb +10 -0
- data/lib/eventq/eventq_base/serialization_providers/jruby/oj_serialization_provider.rb +25 -0
- data/lib/eventq/eventq_base/serialization_providers/jruby.rb +2 -0
- data/lib/eventq/eventq_base/serialization_providers/json_serialization_provider.rb +28 -0
- data/lib/eventq/eventq_base/serialization_providers/oj_serialization_provider.rb +24 -0
- data/lib/eventq/eventq_base/serialization_providers.rb +36 -0
- data/lib/eventq/eventq_base/signature_providers/sha256_signature_provider.rb +31 -0
- data/lib/eventq/eventq_base/signature_providers.rb +44 -0
- data/lib/eventq/eventq_base/subscription_manager_contract.rb +13 -0
- data/lib/eventq/eventq_base/version.rb +3 -0
- data/lib/eventq/eventq_base/worker_id.rb +20 -0
- data/lib/eventq/eventq_rabbitmq/README.md +36 -0
- data/lib/eventq/eventq_rabbitmq/default_queue.rb +12 -0
- data/lib/eventq/eventq_rabbitmq/jruby/rabbitmq_queue_worker.rb +367 -0
- data/lib/eventq/eventq_rabbitmq/rabbitmq_eventq_client.rb +140 -0
- data/lib/eventq/eventq_rabbitmq/rabbitmq_queue_client.rb +54 -0
- data/lib/eventq/eventq_rabbitmq/rabbitmq_queue_manager.rb +104 -0
- data/lib/eventq/eventq_rabbitmq/rabbitmq_queue_worker.rb +168 -0
- data/lib/eventq/eventq_rabbitmq/rabbitmq_status_checker.rb +62 -0
- data/lib/eventq/eventq_rabbitmq/rabbitmq_subscription_manager.rb +54 -0
- data/lib/eventq/queue_worker.rb +241 -0
- data/lib/eventq/rabbitmq.rb +49 -0
- data/lib/eventq/worker_status.rb +64 -0
- data/lib/eventq.rb +25 -0
- metadata +289 -0
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'concurrent'
|
4
|
+
|
5
|
+
module EventQ
|
6
|
+
module Amazon
|
7
|
+
# Helper SNS class to handle the API calls
|
8
|
+
class SNS
|
9
|
+
@@topic_arns = Concurrent::Hash.new
|
10
|
+
|
11
|
+
attr_reader :sns
|
12
|
+
|
13
|
+
def initialize(client)
|
14
|
+
@sns = client
|
15
|
+
end
|
16
|
+
|
17
|
+
# Create a TopicArn. if one already exists, it will return a pre-existing ARN from the cache.
|
18
|
+
# Even in the event of multiple threads trying to create one with AWS, AWS is idempotent and won't create
|
19
|
+
# duplicates
|
20
|
+
def create_topic_arn(event_type)
|
21
|
+
_event_type = EventQ.create_event_type(event_type)
|
22
|
+
|
23
|
+
arn = get_topic_arn(event_type)
|
24
|
+
unless arn
|
25
|
+
response = sns.create_topic(name: aws_safe_name(_event_type))
|
26
|
+
arn = response.topic_arn
|
27
|
+
@@topic_arns[_event_type] = arn
|
28
|
+
end
|
29
|
+
|
30
|
+
arn
|
31
|
+
end
|
32
|
+
|
33
|
+
# Check if a TopicArn exists. This will check with AWS if necessary and cache the results if one is found
|
34
|
+
# @return TopicArn [String]
|
35
|
+
def get_topic_arn(event_type)
|
36
|
+
_event_type = EventQ.create_event_type(event_type)
|
37
|
+
|
38
|
+
arn = @@topic_arns[_event_type]
|
39
|
+
unless arn
|
40
|
+
response = sns.list_topics
|
41
|
+
arn = response.topics.detect { |topic| topic.topic_arn.end_with?(_event_type) }&.topic_arn
|
42
|
+
|
43
|
+
@@topic_arns[_event_type] = arn if arn
|
44
|
+
end
|
45
|
+
|
46
|
+
arn
|
47
|
+
end
|
48
|
+
|
49
|
+
def drop_topic(event_type)
|
50
|
+
topic_arn = get_topic_arn(event_type)
|
51
|
+
sns.delete_topic(topic_arn: topic_arn)
|
52
|
+
|
53
|
+
_event_type = EventQ.create_event_type(event_type)
|
54
|
+
@@topic_arns.delete(_event_type)
|
55
|
+
|
56
|
+
true
|
57
|
+
end
|
58
|
+
|
59
|
+
def aws_safe_name(name)
|
60
|
+
return name[0..79].gsub(/[^a-zA-Z\d_\-]/,'')
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EventQ
|
4
|
+
module Amazon
|
5
|
+
# Helper SQS class to handle the API calls
|
6
|
+
class SQS
|
7
|
+
@@queue_arns = Concurrent::Hash.new
|
8
|
+
@@queue_urls = Concurrent::Hash.new
|
9
|
+
|
10
|
+
attr_reader :sqs
|
11
|
+
|
12
|
+
def initialize(client)
|
13
|
+
@sqs = client
|
14
|
+
end
|
15
|
+
|
16
|
+
# Create a new queue.
|
17
|
+
def create_queue(queue, attributes = {})
|
18
|
+
_queue_name = EventQ.create_queue_name(queue.name)
|
19
|
+
|
20
|
+
url = get_queue_url(queue)
|
21
|
+
unless url
|
22
|
+
response = sqs.create_queue(
|
23
|
+
{
|
24
|
+
queue_name: aws_safe_name(_queue_name),
|
25
|
+
attributes: attributes
|
26
|
+
}
|
27
|
+
)
|
28
|
+
url = response.queue_url
|
29
|
+
@@queue_urls[_queue_name] = url
|
30
|
+
end
|
31
|
+
|
32
|
+
url
|
33
|
+
end
|
34
|
+
|
35
|
+
# Update a queue
|
36
|
+
def update_queue(queue, attributes = {})
|
37
|
+
url = get_queue_url(queue)
|
38
|
+
sqs.set_queue_attributes(
|
39
|
+
{
|
40
|
+
queue_url: url, # required
|
41
|
+
attributes: attributes
|
42
|
+
}
|
43
|
+
)
|
44
|
+
|
45
|
+
url
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns the ARN of a queue. If none exists, nil will be returned.
|
49
|
+
#
|
50
|
+
# @param queue [EventQ::Queue]
|
51
|
+
# @return ARN [String]
|
52
|
+
def get_queue_arn(queue)
|
53
|
+
_queue_name = EventQ.create_queue_name(queue.name)
|
54
|
+
|
55
|
+
arn = @@queue_arns[_queue_name]
|
56
|
+
unless arn
|
57
|
+
url = get_queue_url(queue)
|
58
|
+
if url
|
59
|
+
response = sqs.get_queue_attributes(
|
60
|
+
{
|
61
|
+
queue_url: url,
|
62
|
+
attribute_names: ['QueueArn']
|
63
|
+
}
|
64
|
+
)
|
65
|
+
arn = response.attributes['QueueArn']
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
arn
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns the URL of the queue. If none exists, nil will be returned.
|
73
|
+
#
|
74
|
+
# @param queue [EventQ::Queue]
|
75
|
+
# @return URL [String]
|
76
|
+
def get_queue_url(queue)
|
77
|
+
_queue_name = EventQ.create_queue_name(queue.name)
|
78
|
+
|
79
|
+
url = @@queue_urls[_queue_name]
|
80
|
+
unless url
|
81
|
+
begin
|
82
|
+
response= sqs.get_queue_url(
|
83
|
+
queue_name: aws_safe_name(_queue_name)
|
84
|
+
)
|
85
|
+
url = response.queue_url
|
86
|
+
rescue Aws::SQS::Errors::NonExistentQueue
|
87
|
+
# Only want to return nil for this method when not found.
|
88
|
+
end
|
89
|
+
|
90
|
+
@@queue_urls[_queue_name] = url if url
|
91
|
+
end
|
92
|
+
|
93
|
+
url
|
94
|
+
end
|
95
|
+
|
96
|
+
def drop_queue(queue)
|
97
|
+
q = get_queue_url(queue)
|
98
|
+
sqs.delete_queue(queue_url: q)
|
99
|
+
|
100
|
+
_queue_name = EventQ.create_queue_name(queue.name)
|
101
|
+
@@queue_urls.delete(_queue_name)
|
102
|
+
@@queue_arns.delete(_queue_name)
|
103
|
+
|
104
|
+
true
|
105
|
+
end
|
106
|
+
|
107
|
+
def aws_safe_name(name)
|
108
|
+
return name[0..79].gsub(/[^a-zA-Z\d_\-]/,'')
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module EventQ
|
2
|
+
class Configuration
|
3
|
+
|
4
|
+
def self.serialization_provider=(value)
|
5
|
+
@serialization_provider = value
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.serialization_provider
|
9
|
+
if RUBY_PLATFORM =~ /java/
|
10
|
+
@serialization_provider ||= EventQ::SerializationProviders::JSON_PROVIDER
|
11
|
+
else
|
12
|
+
@serialization_provider ||= EventQ::SerializationProviders::OJ_PROVIDER
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.signature_provider=(value)
|
17
|
+
@signature_provider = value
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.signature_provider
|
21
|
+
@signature_provider ||= EventQ::SignatureProviders::SHA256
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.signature_secret=(value)
|
25
|
+
@signature_secret = value
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.signature_secret
|
29
|
+
@signature_secret
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module EventQ
|
4
|
+
|
5
|
+
def self.logger
|
6
|
+
return @@logger
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.set_logger(logger)
|
10
|
+
@@logger = logger
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.log(type, message)
|
14
|
+
case type
|
15
|
+
when :info
|
16
|
+
logger.info(message)
|
17
|
+
when :debug
|
18
|
+
logger.debug(message)
|
19
|
+
when :error
|
20
|
+
logger.error(message)
|
21
|
+
end
|
22
|
+
rescue
|
23
|
+
#do nothing
|
24
|
+
end
|
25
|
+
|
26
|
+
EventQ.set_logger(Logger.new(STDOUT))
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module EventQ
|
2
|
+
class MessageArgs
|
3
|
+
attr_reader :type
|
4
|
+
attr_reader :content_type
|
5
|
+
attr_reader :retry_attempts
|
6
|
+
attr_accessor :abort
|
7
|
+
attr_accessor :drop
|
8
|
+
attr_reader :context
|
9
|
+
attr_reader :id
|
10
|
+
attr_reader :sent
|
11
|
+
|
12
|
+
def initialize(type:, retry_attempts:, context: {}, content_type:, id: nil, sent: nil)
|
13
|
+
@type = type
|
14
|
+
@retry_attempts = retry_attempts
|
15
|
+
@abort = false
|
16
|
+
@drop = false
|
17
|
+
@context = context
|
18
|
+
@content_type = content_type
|
19
|
+
@id = id
|
20
|
+
@sent = sent
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module EventQ
|
2
|
+
class NonceManager
|
3
|
+
|
4
|
+
def self.configure(server:,timeout:10000,lifespan:3600000)
|
5
|
+
@server_url = server
|
6
|
+
@timeout = timeout
|
7
|
+
@lifespan = lifespan
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.server_url
|
11
|
+
@server_url
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.timeout
|
15
|
+
@timeout
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.lifespan
|
19
|
+
@lifespan
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.is_allowed?(nonce)
|
23
|
+
if @server_url == nil
|
24
|
+
return true
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'redlock'
|
28
|
+
lock = Redlock::Client.new([ @server_url ]).lock(nonce, @timeout)
|
29
|
+
if lock == false
|
30
|
+
EventQ.log(:info, "[#{self.class}] - Message has already been processed: #{nonce}")
|
31
|
+
return false
|
32
|
+
end
|
33
|
+
|
34
|
+
return true
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.complete(nonce)
|
38
|
+
if @server_url != nil
|
39
|
+
Redis.new(url: @server_url).expire(nonce, @lifespan)
|
40
|
+
end
|
41
|
+
return true
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.failed(nonce)
|
45
|
+
if @server_url != nil
|
46
|
+
Redis.new(url: @server_url).del(nonce)
|
47
|
+
end
|
48
|
+
return true
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.reset
|
52
|
+
@server_url = nil
|
53
|
+
@timeout = nil
|
54
|
+
@lifespan = nil
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module EventQ
|
2
|
+
class Queue
|
3
|
+
attr_accessor :allow_retry
|
4
|
+
attr_accessor :allow_retry_back_off
|
5
|
+
attr_accessor :dlq
|
6
|
+
attr_accessor :max_retry_attempts
|
7
|
+
attr_accessor :max_retry_delay
|
8
|
+
attr_accessor :name
|
9
|
+
attr_accessor :max_receive_count
|
10
|
+
attr_accessor :require_signature
|
11
|
+
attr_accessor :retry_delay
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@allow_retry = false
|
15
|
+
# Default retry back off settings
|
16
|
+
@allow_retry_back_off = false
|
17
|
+
# Default max receive count is 30
|
18
|
+
@max_receive_count = 30
|
19
|
+
# Default max retry attempts is 5
|
20
|
+
@max_retry_attempts = 5
|
21
|
+
# Default require signature to false
|
22
|
+
@require_signature = false
|
23
|
+
# Default retry delay is 30 seconds
|
24
|
+
@retry_delay = 30000
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module EventQ
|
2
|
+
class QueueMessage
|
3
|
+
extend ClassKit
|
4
|
+
|
5
|
+
attr_accessor_type :id, type: String
|
6
|
+
attr_accessor_type :retry_attempts, type: Integer
|
7
|
+
attr_accessor_type :type, type: String
|
8
|
+
attr_accessor_type :content
|
9
|
+
attr_accessor_type :content_type, type: String
|
10
|
+
attr_accessor_type :created, type: Float
|
11
|
+
attr_accessor_type :signature, type: String
|
12
|
+
attr_accessor_type :context, type: Hash
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@retry_attempts = 0
|
16
|
+
@created = Time.now.to_f
|
17
|
+
@id = SecureRandom.uuid
|
18
|
+
@context = {}
|
19
|
+
end
|
20
|
+
|
21
|
+
# Creates a signature for the message
|
22
|
+
#
|
23
|
+
# @param provider [EventQ::SignatureProviders::Sha256SignatureProvider] Signature provider that implements
|
24
|
+
# a write method
|
25
|
+
def sign(provider)
|
26
|
+
return unless EventQ::Configuration.signature_secret
|
27
|
+
|
28
|
+
self.signature = provider.write(message: self, secret: EventQ::Configuration.signature_secret)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module EventQ
|
2
|
+
# Contract class for queue workers
|
3
|
+
class QueueWorkerContract
|
4
|
+
|
5
|
+
def start(queue, options = {}, &block)
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
def stop
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
def on_retry_exceeded(&block)
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
def running?
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module EventQ
|
2
|
+
module SerializationProviders
|
3
|
+
module JRuby
|
4
|
+
module Oj
|
5
|
+
class ArrayWriter < AttributeWriter
|
6
|
+
def valid?(obj)
|
7
|
+
obj.is_a?(Array)
|
8
|
+
end
|
9
|
+
def exec(obj)
|
10
|
+
array = []
|
11
|
+
obj.each do |a|
|
12
|
+
array << AttributeWriter.exec(a)
|
13
|
+
end
|
14
|
+
array
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module EventQ
|
2
|
+
module SerializationProviders
|
3
|
+
module JRuby
|
4
|
+
module Oj
|
5
|
+
class AttributeWriter
|
6
|
+
|
7
|
+
def self.exec(obj)
|
8
|
+
aw = descendants.detect { |a| a.new.valid?(obj) } || ClassWriter
|
9
|
+
aw.new.exec(obj)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.descendants
|
13
|
+
descendants = []
|
14
|
+
ObjectSpace.each_object(singleton_class) do |k|
|
15
|
+
next if k.singleton_class?
|
16
|
+
descendants.unshift k unless k == self
|
17
|
+
end
|
18
|
+
descendants
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module EventQ
|
2
|
+
module SerializationProviders
|
3
|
+
module JRuby
|
4
|
+
module Oj
|
5
|
+
class ClassWriter < AttributeWriter
|
6
|
+
def valid?(obj)
|
7
|
+
false
|
8
|
+
end
|
9
|
+
def exec(obj)
|
10
|
+
hash = { '^o': obj.class }
|
11
|
+
obj.instance_variables.each do |key|
|
12
|
+
hash[key[1..-1]] = AttributeWriter.exec(obj.instance_variable_get(key))
|
13
|
+
end
|
14
|
+
hash
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module EventQ
|
2
|
+
module SerializationProviders
|
3
|
+
module JRuby
|
4
|
+
module Oj
|
5
|
+
class DateTimeWriter < AttributeWriter
|
6
|
+
def valid?(obj)
|
7
|
+
obj.is_a?(DateTime)
|
8
|
+
end
|
9
|
+
def exec(obj)
|
10
|
+
seconds = obj.strftime('%S%N')
|
11
|
+
d = 1_000_000_000
|
12
|
+
if seconds.start_with?('0')
|
13
|
+
seconds[0] = ''
|
14
|
+
d = 100_000_000
|
15
|
+
end
|
16
|
+
|
17
|
+
{
|
18
|
+
'^O': 'DateTime',
|
19
|
+
year: obj.year,
|
20
|
+
month: obj.month,
|
21
|
+
day: obj.day,
|
22
|
+
hour: obj.hour,
|
23
|
+
min: obj.min,
|
24
|
+
sec: RationalWriter.new.exec(Rational(Integer(seconds), d)),
|
25
|
+
offset: RationalWriter.new.exec(obj.offset),
|
26
|
+
start: obj.start
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module EventQ
|
2
|
+
module SerializationProviders
|
3
|
+
module JRuby
|
4
|
+
module Oj
|
5
|
+
class DateWriter < AttributeWriter
|
6
|
+
def valid?(obj)
|
7
|
+
obj.is_a?(Date) && !obj.is_a?(DateTime)
|
8
|
+
end
|
9
|
+
def exec(obj)
|
10
|
+
{
|
11
|
+
'^O': 'Date',
|
12
|
+
year: obj.year,
|
13
|
+
month: obj.month,
|
14
|
+
day: obj.day,
|
15
|
+
start: obj.start
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module EventQ
|
2
|
+
module SerializationProviders
|
3
|
+
module JRuby
|
4
|
+
module Oj
|
5
|
+
class HashWriter < AttributeWriter
|
6
|
+
def valid?(obj)
|
7
|
+
obj.is_a?(Hash)
|
8
|
+
end
|
9
|
+
def exec(obj)
|
10
|
+
obj.each do |key, value|
|
11
|
+
obj[key] = AttributeWriter.exec(value)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module EventQ
|
2
|
+
module SerializationProviders
|
3
|
+
module JRuby
|
4
|
+
module Oj
|
5
|
+
class RationalWriter < AttributeWriter
|
6
|
+
def valid?(obj)
|
7
|
+
obj.is_a?(Rational)
|
8
|
+
end
|
9
|
+
def exec(obj)
|
10
|
+
{
|
11
|
+
'^O': 'Rational',
|
12
|
+
numerator: obj.numerator,
|
13
|
+
denominator: obj.denominator
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module EventQ
|
2
|
+
module SerializationProviders
|
3
|
+
module JRuby
|
4
|
+
module Oj
|
5
|
+
class Serializer
|
6
|
+
def dump(obj)
|
7
|
+
JSON.dump(AttributeWriter.exec(obj))
|
8
|
+
end
|
9
|
+
|
10
|
+
def load(json)
|
11
|
+
raise NotImplementedError.new("[#{self.class}] - #load method has not yet been implemented.")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|