hawkei 1.0.0
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/.gitignore +4 -0
- data/.rspec +1 -0
- data/.rubocop.yml +48 -0
- data/.ruby-version +1 -0
- data/.tool-versions +1 -0
- data/.travis.yml +11 -0
- data/Gemfile +12 -0
- data/LICENCE +21 -0
- data/Makefile +9 -0
- data/README.md +17 -0
- data/Rakefile +4 -0
- data/hawkei.gemspec +28 -0
- data/lib/hawkei/api_operation/delete.rb +38 -0
- data/lib/hawkei/api_operation/save.rb +57 -0
- data/lib/hawkei/api_resource.rb +130 -0
- data/lib/hawkei/batch.rb +18 -0
- data/lib/hawkei/config.rb +123 -0
- data/lib/hawkei/errors.rb +41 -0
- data/lib/hawkei/formated_logger.rb +45 -0
- data/lib/hawkei/hawkei_object.rb +179 -0
- data/lib/hawkei/library_name.rb +3 -0
- data/lib/hawkei/message.rb +79 -0
- data/lib/hawkei/plugins/rack/middleware.rb +139 -0
- data/lib/hawkei/plugins/rails/data.rb +19 -0
- data/lib/hawkei/plugins/rails/middleware_data.rb +28 -0
- data/lib/hawkei/plugins/rails/railtie.rb +23 -0
- data/lib/hawkei/plugins/sidekiq/client_middleware.rb +19 -0
- data/lib/hawkei/plugins/sidekiq/load.rb +14 -0
- data/lib/hawkei/plugins/sidekiq/server_middleware.rb +48 -0
- data/lib/hawkei/plugins.rb +17 -0
- data/lib/hawkei/processor/async.rb +50 -0
- data/lib/hawkei/processor/batch.rb +84 -0
- data/lib/hawkei/processor/worker.rb +113 -0
- data/lib/hawkei/request.rb +134 -0
- data/lib/hawkei/store.rb +49 -0
- data/lib/hawkei/util.rb +180 -0
- data/lib/hawkei/version.rb +3 -0
- data/lib/hawkei/watcher.rb +15 -0
- data/lib/hawkei.rb +170 -0
- data/spec/lib/hawkei/api_resource_spec.rb +109 -0
- data/spec/lib/hawkei/batch_spec.rb +14 -0
- data/spec/lib/hawkei/config_spec.rb +36 -0
- data/spec/lib/hawkei/formated_logger_spec.rb +99 -0
- data/spec/lib/hawkei/hawkei_object_spec.rb +123 -0
- data/spec/lib/hawkei/message_spec.rb +178 -0
- data/spec/lib/hawkei/plugins/rack/middleware_spec.rb +88 -0
- data/spec/lib/hawkei/plugins/rails/data_spec.rb +22 -0
- data/spec/lib/hawkei/plugins/rails/middleware_data_spec.rb +46 -0
- data/spec/lib/hawkei/plugins/sidekiq/client_middleware_spec.rb +15 -0
- data/spec/lib/hawkei/plugins/sidekiq/server_middleware_spec.rb +58 -0
- data/spec/lib/hawkei/processor/async_spec.rb +36 -0
- data/spec/lib/hawkei/processor/batch_spec.rb +51 -0
- data/spec/lib/hawkei/processor/worker_spec.rb +100 -0
- data/spec/lib/hawkei/store_spec.rb +82 -0
- data/spec/lib/hawkei/util_spec.rb +132 -0
- data/spec/lib/hawkei/watcher_spec.rb +25 -0
- data/spec/lib/hawkei_spec.rb +175 -0
- data/spec/spec_helper.rb +33 -0
- data/spec/support/rack_app.rb +12 -0
- metadata +206 -0
@@ -0,0 +1,113 @@
|
|
1
|
+
module Hawkei
|
2
|
+
module Processor
|
3
|
+
class Worker
|
4
|
+
|
5
|
+
FLUSH_INTERVAL_SECONDS = 3
|
6
|
+
|
7
|
+
FLUSH_MESSAGE = Object.new
|
8
|
+
SHUTDOWN_MESSAGE = Object.new
|
9
|
+
|
10
|
+
def initialize(queue, state)
|
11
|
+
@queue = queue
|
12
|
+
@state = state
|
13
|
+
|
14
|
+
@batch = Batch.new
|
15
|
+
@promises = Concurrent::Array.new
|
16
|
+
|
17
|
+
@timer = Concurrent::TimerTask.new(execution_interval: FLUSH_INTERVAL_SECONDS) { @queue << FLUSH_MESSAGE }
|
18
|
+
@timer.execute
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
while thread_active?
|
23
|
+
message = @queue.pop
|
24
|
+
|
25
|
+
add_message_to_batch(message)
|
26
|
+
end
|
27
|
+
|
28
|
+
shutdown_worker
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
##
|
34
|
+
# Add the message to a batch
|
35
|
+
#
|
36
|
+
# - Add message to a batch if it's not a flush message
|
37
|
+
# - flush batch if flush message is receive or batch is full
|
38
|
+
def add_message_to_batch(message)
|
39
|
+
@batch << message if message != FLUSH_MESSAGE
|
40
|
+
flush if message == FLUSH_MESSAGE || @batch.full?
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Shutdown the worker
|
45
|
+
#
|
46
|
+
# - Close the timer
|
47
|
+
# - Retreive the last messages
|
48
|
+
# - Wait for all the request to be completed
|
49
|
+
#
|
50
|
+
# rubocop:disable Lint/HandleExceptions
|
51
|
+
def shutdown_worker
|
52
|
+
@timer.shutdown
|
53
|
+
|
54
|
+
begin
|
55
|
+
until (message = @queue.pop(true)).nil?
|
56
|
+
add_message_to_batch(message)
|
57
|
+
end
|
58
|
+
rescue ThreadError => _
|
59
|
+
end
|
60
|
+
|
61
|
+
flush
|
62
|
+
|
63
|
+
@promises.each do |promise|
|
64
|
+
promise.wait if promise && !promise.fulfilled?
|
65
|
+
end
|
66
|
+
end
|
67
|
+
# rubocop:enable Lint/HandleExceptions
|
68
|
+
|
69
|
+
def flush
|
70
|
+
return if @batch.empty?
|
71
|
+
|
72
|
+
send_batch(@batch)
|
73
|
+
@batch = Batch.new
|
74
|
+
end
|
75
|
+
|
76
|
+
# rubocop:disable Metrics/AbcSize
|
77
|
+
def send_batch(batch)
|
78
|
+
promise =
|
79
|
+
Concurrent::Promise
|
80
|
+
.new { Hawkei::Batch.create(Message.base.merge(data: batch.messages)) }
|
81
|
+
.on_success { @promises.delete(promise) }
|
82
|
+
.rescue do |error|
|
83
|
+
batch.update_retry
|
84
|
+
|
85
|
+
if error.is_a?(Hawkei::RequestError) && [401, 404].include?(error.http_status)
|
86
|
+
return logger.error(error.message)
|
87
|
+
end
|
88
|
+
|
89
|
+
if thread_active? && batch.can_retry?
|
90
|
+
Concurrent::ScheduledTask.new(batch.next_retry) { send_batch(batch) }.execute
|
91
|
+
else
|
92
|
+
@promises.delete(promise)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
promise.execute
|
97
|
+
@promises << promise
|
98
|
+
rescue Concurrent::RejectedExecutionError => _
|
99
|
+
logger.error('Impossible to start a thread in closing application')
|
100
|
+
end
|
101
|
+
# rubocop:enable Metrics/AbcSize
|
102
|
+
|
103
|
+
def thread_active?
|
104
|
+
@state.true?
|
105
|
+
end
|
106
|
+
|
107
|
+
def logger
|
108
|
+
Hawkei.configurations.logger
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
module Hawkei
|
2
|
+
##
|
3
|
+
# == Hawkei \Request
|
4
|
+
#
|
5
|
+
# Build request
|
6
|
+
class Request
|
7
|
+
class << self
|
8
|
+
|
9
|
+
def execute(params = {})
|
10
|
+
klass = new(params)
|
11
|
+
|
12
|
+
if params[:method] == :post
|
13
|
+
klass.post
|
14
|
+
elsif params[:method] == :put
|
15
|
+
klass.put
|
16
|
+
elsif params[:method] == :delete
|
17
|
+
klass.delete
|
18
|
+
elsif params[:method] == :get
|
19
|
+
klass.get
|
20
|
+
else
|
21
|
+
raise Hawkei::UnknownRequestMethod, "#{params[:method]} haven't been implemented"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def post(params = {})
|
26
|
+
new(params).post
|
27
|
+
end
|
28
|
+
|
29
|
+
def put(params = {})
|
30
|
+
new(params).put
|
31
|
+
end
|
32
|
+
|
33
|
+
def get(params = {})
|
34
|
+
new(params).get
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete(params = {})
|
38
|
+
new(params).delete
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
attr_reader :params, :http, :request
|
43
|
+
|
44
|
+
def initialize(params = {})
|
45
|
+
@params = params
|
46
|
+
@http = Net::HTTP.new(uri.host, uri.port, uri_proxy.host, uri_proxy.port)
|
47
|
+
|
48
|
+
setup_ssl if params[:use_ssl]
|
49
|
+
end
|
50
|
+
|
51
|
+
def post
|
52
|
+
@request = Net::HTTP::Post.new(uri.path)
|
53
|
+
|
54
|
+
set_header
|
55
|
+
request.body = params[:payload]
|
56
|
+
|
57
|
+
handle_request
|
58
|
+
end
|
59
|
+
|
60
|
+
def put
|
61
|
+
@request = Net::HTTP::Put.new(uri.path)
|
62
|
+
|
63
|
+
set_header
|
64
|
+
request.body = params[:payload]
|
65
|
+
|
66
|
+
handle_request
|
67
|
+
end
|
68
|
+
|
69
|
+
def get
|
70
|
+
@request = Net::HTTP::Get.new(uri)
|
71
|
+
|
72
|
+
set_header
|
73
|
+
|
74
|
+
handle_request
|
75
|
+
end
|
76
|
+
|
77
|
+
def delete
|
78
|
+
@request = Net::HTTP::Delete.new(uri.path)
|
79
|
+
|
80
|
+
set_header
|
81
|
+
request.body = params[:payload]
|
82
|
+
|
83
|
+
handle_request
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def handle_request
|
89
|
+
response = http.request(request)
|
90
|
+
|
91
|
+
case [response.code_type]
|
92
|
+
when [Net::HTTPOK], [Net::HTTPCreated], [Net::HTTPAccepted]
|
93
|
+
response
|
94
|
+
when [Net::HTTPUnauthorized]
|
95
|
+
raise RequestError.new(response, message: 'Unauthorized, please check your api key')
|
96
|
+
when [Net::HTTPNotFound]
|
97
|
+
raise RequestError.new(response, message: 'Requested Resource not found')
|
98
|
+
when [Net::HTTPRequestTimeOut]
|
99
|
+
raise RequestError.new(response, message: 'Server timeout, verify status of the server')
|
100
|
+
when [Net::HTTPInternalServerError]
|
101
|
+
raise RequestError.new(response, message: 'Server Error, please check with Hawkei')
|
102
|
+
else
|
103
|
+
raise RequestError, response
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def set_header
|
108
|
+
params[:headers].each do |(type, value)|
|
109
|
+
formated_type = type.to_s.split(/_/).map(&:capitalize).join('-')
|
110
|
+
request[formated_type] = value
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def setup_ssl
|
115
|
+
http.use_ssl = true
|
116
|
+
http.ca_file = params[:ca_file]
|
117
|
+
http.verify_mode = params[:verify_mode]
|
118
|
+
end
|
119
|
+
|
120
|
+
def uri
|
121
|
+
@uri ||= URI(params[:url])
|
122
|
+
end
|
123
|
+
|
124
|
+
def uri_proxy
|
125
|
+
@uri_proxy ||=
|
126
|
+
if params[:proxy]
|
127
|
+
URI(params[:proxy])
|
128
|
+
else
|
129
|
+
OpenStruct.new
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
end
|
data/lib/hawkei/store.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
module Hawkei
|
2
|
+
##
|
3
|
+
# == Hawkei \Store
|
4
|
+
#
|
5
|
+
# Store environment data
|
6
|
+
#
|
7
|
+
class Store
|
8
|
+
class << self
|
9
|
+
|
10
|
+
def store
|
11
|
+
Thread.current[:request_store] ||= {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def clear!
|
15
|
+
Thread.current[:request_store] = {}
|
16
|
+
end
|
17
|
+
|
18
|
+
def load_from_hash(object = {})
|
19
|
+
clear!
|
20
|
+
bulk_set(Util.deep_symbolize_key(object)) if object.is_a?(Hash)
|
21
|
+
end
|
22
|
+
|
23
|
+
def get(key)
|
24
|
+
store[key]
|
25
|
+
end
|
26
|
+
alias [] get
|
27
|
+
|
28
|
+
def set(key, value)
|
29
|
+
store[key] = value
|
30
|
+
end
|
31
|
+
alias []= set
|
32
|
+
|
33
|
+
def bulk_set(attributes = {})
|
34
|
+
attributes.each do |(key, value)|
|
35
|
+
set(key, value)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def exist?(key)
|
40
|
+
store.key?(key)
|
41
|
+
end
|
42
|
+
|
43
|
+
def delete(key, &block)
|
44
|
+
store.delete(key, &block)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/hawkei/util.rb
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
module Hawkei
|
2
|
+
module Util
|
3
|
+
class << self
|
4
|
+
|
5
|
+
DATE_FORMAT = '%Y/%m/%d'.freeze
|
6
|
+
OBFUSCATED = '[HIDDEN]'.freeze
|
7
|
+
DEFAULT_OBJECT_DEF = %w[id name].freeze
|
8
|
+
|
9
|
+
##
|
10
|
+
# Remove keys from a Hash
|
11
|
+
#
|
12
|
+
# @param [Hash] to be excepted
|
13
|
+
# @param [List[String]] to be excepted
|
14
|
+
#
|
15
|
+
# @return [Hash]
|
16
|
+
def except_keys(hash, *keys)
|
17
|
+
hash.dup.delete_if { |(key, _value)| keys.include?(key) }
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# Convert string to camelize
|
22
|
+
#
|
23
|
+
# @param [String]
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
# camelize('my_model') => 'MyModel'
|
27
|
+
def camelize(string)
|
28
|
+
string.split('_').map(&:capitalize).join
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Remove nil value from hash
|
33
|
+
#
|
34
|
+
# @return [Hash]
|
35
|
+
def compact(hash)
|
36
|
+
hash.reject { |_, value| value.nil? }
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Remove nil value from hash recursively
|
41
|
+
#
|
42
|
+
# @return [Hash]
|
43
|
+
def deep_compact(object)
|
44
|
+
object.each_with_object({}) do |(key, value), result|
|
45
|
+
if value.is_a?(Hash)
|
46
|
+
value = deep_compact(value)
|
47
|
+
result[key] = value if !value.nil? && !value.empty?
|
48
|
+
else
|
49
|
+
result[key] = value unless value.nil?
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Encodes a hash of parameters in a way that's suitable for use as query
|
56
|
+
# parameters in a URI or as form parameters in a request body. This mainly
|
57
|
+
# involves escaping special characters from parameter keys and values (e.g.
|
58
|
+
# `&`).
|
59
|
+
def encode_parameters(params = {})
|
60
|
+
params.map { |k, v| "#{url_encode(k)}=#{url_encode(v)}" }.join('&')
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Encodes a string in a way that makes it suitable for use in a set of
|
65
|
+
# query parameters in a URI or in a set of form parameters in a request
|
66
|
+
# body.
|
67
|
+
def url_encode(key)
|
68
|
+
CGI.escape(key.to_s).gsub('%5B', '[').gsub('%5D', ']')
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
# Convert string to underscore
|
73
|
+
#
|
74
|
+
# @param [String]
|
75
|
+
#
|
76
|
+
# @example
|
77
|
+
# underscore('MyModel') => 'my_model'
|
78
|
+
def underscore(string)
|
79
|
+
string
|
80
|
+
.gsub(/::/, '/')
|
81
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
82
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
83
|
+
.tr('-', '_')
|
84
|
+
.downcase
|
85
|
+
end
|
86
|
+
|
87
|
+
##
|
88
|
+
# Deep convert hash to underscore case keys
|
89
|
+
#
|
90
|
+
# @param [Hash] hash to transform
|
91
|
+
#
|
92
|
+
# @return [Hash] transformed
|
93
|
+
def deep_underscore_key(hash_object)
|
94
|
+
deep_transform_keys_in_object(hash_object) do |key|
|
95
|
+
begin
|
96
|
+
underscore(key).to_sym
|
97
|
+
rescue StandardError => _e
|
98
|
+
key
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
##
|
104
|
+
# Deep convert hash to string keys
|
105
|
+
#
|
106
|
+
# @param [Hash] hash to transform
|
107
|
+
#
|
108
|
+
# @return [Hash] transformed
|
109
|
+
def deep_stringify_key(hash_object)
|
110
|
+
deep_transform_keys_in_object(hash_object) do |key|
|
111
|
+
begin
|
112
|
+
key.to_s
|
113
|
+
rescue StandardError => _e
|
114
|
+
key
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
##
|
120
|
+
# Deep convert hash to symbol keys
|
121
|
+
#
|
122
|
+
# @param [Hash] hash to transform
|
123
|
+
#
|
124
|
+
# @return [Hash] transformed
|
125
|
+
def deep_symbolize_key(hash_object)
|
126
|
+
deep_transform_keys_in_object(hash_object) do |key|
|
127
|
+
begin
|
128
|
+
key.to_sym
|
129
|
+
rescue StandardError => _e
|
130
|
+
key
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
##
|
136
|
+
# Deep remove key from hash
|
137
|
+
#
|
138
|
+
# @param [Hash] hash to obfuscate
|
139
|
+
#
|
140
|
+
# @return [Hash] hash obfuscated
|
141
|
+
def deep_obfuscate_value(object, fields, obfuscate_name = OBFUSCATED)
|
142
|
+
case object
|
143
|
+
when Hash
|
144
|
+
object.each_with_object({}) do |(key, value), result|
|
145
|
+
result[key] = fields.include?(key.to_s) ? obfuscate_name : deep_obfuscate_value(value, fields)
|
146
|
+
end
|
147
|
+
when Array
|
148
|
+
object.map { |e| deep_obfuscate_value(e, fields) }
|
149
|
+
else
|
150
|
+
object
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
##
|
155
|
+
# Parse JSON without raise
|
156
|
+
#
|
157
|
+
def safe_json_parse(data)
|
158
|
+
JSON.parse(data.to_s)
|
159
|
+
rescue JSON::ParserError
|
160
|
+
{}
|
161
|
+
end
|
162
|
+
|
163
|
+
private
|
164
|
+
|
165
|
+
def deep_transform_keys_in_object(object, &block)
|
166
|
+
case object
|
167
|
+
when Hash
|
168
|
+
object.each_with_object({}) do |(key, value), result|
|
169
|
+
result[yield(key)] = deep_transform_keys_in_object(value, &block)
|
170
|
+
end
|
171
|
+
when Array
|
172
|
+
object.map { |e| deep_transform_keys_in_object(e, &block) }
|
173
|
+
else
|
174
|
+
object
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Hawkei
|
2
|
+
##
|
3
|
+
# == Hawkei \Watcher
|
4
|
+
#
|
5
|
+
# Create and update groups
|
6
|
+
#
|
7
|
+
# @example: Usage
|
8
|
+
#
|
9
|
+
# request = Hawkei::Watcher.create(template_flow: 'My Hawkei', expected_times: 42) #=> #<Hawkei::Response...>
|
10
|
+
#
|
11
|
+
class Watcher < APIResource
|
12
|
+
include Hawkei::APIOperation::Save
|
13
|
+
include Hawkei::APIOperation::Delete
|
14
|
+
end
|
15
|
+
end
|
data/lib/hawkei.rb
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
# Lib
|
2
|
+
require 'securerandom'
|
3
|
+
require 'net/http'
|
4
|
+
require 'ostruct'
|
5
|
+
require 'json'
|
6
|
+
require 'time'
|
7
|
+
require 'cgi'
|
8
|
+
require 'logger'
|
9
|
+
require 'concurrent'
|
10
|
+
|
11
|
+
# Base
|
12
|
+
require 'hawkei/version'
|
13
|
+
require 'hawkei/formated_logger'
|
14
|
+
require 'hawkei/library_name'
|
15
|
+
require 'hawkei/util'
|
16
|
+
require 'hawkei/config'
|
17
|
+
require 'hawkei/errors'
|
18
|
+
require 'hawkei/hawkei_object'
|
19
|
+
require 'hawkei/request'
|
20
|
+
require 'hawkei/api_resource'
|
21
|
+
require 'hawkei/store'
|
22
|
+
require 'hawkei/message'
|
23
|
+
|
24
|
+
# Processor
|
25
|
+
require 'hawkei/processor/async'
|
26
|
+
require 'hawkei/processor/worker'
|
27
|
+
require 'hawkei/processor/batch'
|
28
|
+
|
29
|
+
# Operations
|
30
|
+
require 'hawkei/api_operation/save'
|
31
|
+
require 'hawkei/api_operation/delete'
|
32
|
+
|
33
|
+
# Resources
|
34
|
+
require 'hawkei/watcher'
|
35
|
+
require 'hawkei/batch'
|
36
|
+
|
37
|
+
# Plugins
|
38
|
+
require 'hawkei/plugins'
|
39
|
+
|
40
|
+
##
|
41
|
+
# Implementation of the Hawkei
|
42
|
+
module Hawkei
|
43
|
+
class << self
|
44
|
+
|
45
|
+
TRACK_EVENTS_CREATE = 'track_events:create'.freeze
|
46
|
+
IDENTIFY_EVENTS_CREATE = 'identify_events:create'.freeze
|
47
|
+
GROUP_EVENTS_CREATE = 'group_events:create'.freeze
|
48
|
+
WATCHERS_CREATE_ACTION = 'watchers:create'.freeze
|
49
|
+
|
50
|
+
##
|
51
|
+
# @return [Hawkei::Config] configurations
|
52
|
+
attr_reader :configurations
|
53
|
+
|
54
|
+
##
|
55
|
+
# Configures the Hawkei API
|
56
|
+
#
|
57
|
+
# @example Default configuration
|
58
|
+
# Hawkei.configure do |config|
|
59
|
+
# config.api_key = 'acc_xx'
|
60
|
+
# config.space_name = 'Hawkei'
|
61
|
+
# config.environment_name = 'production'
|
62
|
+
# end
|
63
|
+
def configure
|
64
|
+
yield @configurations = Hawkei::Config.new
|
65
|
+
|
66
|
+
Hawkei.configurations.valid!
|
67
|
+
end
|
68
|
+
|
69
|
+
##
|
70
|
+
# Send a track event to the server
|
71
|
+
#
|
72
|
+
# @param [String] event name
|
73
|
+
# @param [Hash] payload to be send
|
74
|
+
# @param [Hash] options for the request
|
75
|
+
#
|
76
|
+
# @return [Boolean] status of the request
|
77
|
+
def track(name, payload = {}, options = {})
|
78
|
+
return true unless configurations.enabled
|
79
|
+
|
80
|
+
payload[:name] = name
|
81
|
+
Hawkei::Plugins::Rails::Data.store_data if defined?(Hawkei::Plugins::Rails::Data)
|
82
|
+
|
83
|
+
payload = Message.extended.merge(payload)
|
84
|
+
|
85
|
+
processor.enqueue(
|
86
|
+
action: TRACK_EVENTS_CREATE,
|
87
|
+
payload: payload,
|
88
|
+
options: options.select { |k, _v| %i[space_name environment_name].include?(k) },
|
89
|
+
)
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# Send an identify event to the server
|
94
|
+
#
|
95
|
+
# @param [String] user id from your database
|
96
|
+
# @param [Hash] payload to be send
|
97
|
+
# @param [Hash] options for the request
|
98
|
+
#
|
99
|
+
# @return [Boolean] status of the request
|
100
|
+
def identify(user_id, payload = {}, options = {})
|
101
|
+
return true unless configurations.enabled
|
102
|
+
|
103
|
+
payload[:user_id] = user_id
|
104
|
+
Hawkei::Plugins::Rails::Data.store_data if defined?(Hawkei::Plugins::Rails::Data)
|
105
|
+
|
106
|
+
payload = Message.extended.merge(payload)
|
107
|
+
|
108
|
+
processor.enqueue(
|
109
|
+
action: IDENTIFY_EVENTS_CREATE,
|
110
|
+
payload: payload,
|
111
|
+
options: options.select { |k, _v| %i[space_name environment_name].include?(k) },
|
112
|
+
)
|
113
|
+
end
|
114
|
+
|
115
|
+
##
|
116
|
+
# Send a create/update for a group
|
117
|
+
#
|
118
|
+
# @param [String] group id from your database
|
119
|
+
# @param [Hash] payload to be send
|
120
|
+
# @param [Hash] options for the request
|
121
|
+
#
|
122
|
+
# @return [Boolean] status of the request
|
123
|
+
def group(group_id, payload = {}, options = {})
|
124
|
+
return true unless configurations.enabled
|
125
|
+
|
126
|
+
payload = Message.base.merge(payload)
|
127
|
+
payload[:group_id] = group_id
|
128
|
+
|
129
|
+
processor.enqueue(
|
130
|
+
action: GROUP_EVENTS_CREATE,
|
131
|
+
payload: payload,
|
132
|
+
options: options.select { |k, _v| %i[space_name environment_name].include?(k) },
|
133
|
+
)
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# Send a create a watcher
|
138
|
+
#
|
139
|
+
# @param [String|Integer] template hawkei name or id
|
140
|
+
# @param [Hash] payload to be send
|
141
|
+
# @param [Hash] options for the request
|
142
|
+
#
|
143
|
+
# @return [Boolean|Watcher] status of the request
|
144
|
+
def watch(flow, payload = {}, options = {})
|
145
|
+
return true unless configurations.enabled
|
146
|
+
|
147
|
+
payload[:template_flow] = flow
|
148
|
+
payload = Message.base.merge(payload)
|
149
|
+
|
150
|
+
payload.delete(:session_tracker_id) if payload.delete(:without_session)
|
151
|
+
|
152
|
+
if options[:sync]
|
153
|
+
Watcher.create(payload, options)
|
154
|
+
else
|
155
|
+
processor.enqueue(
|
156
|
+
action: WATCHERS_CREATE_ACTION,
|
157
|
+
payload: payload,
|
158
|
+
options: options.select { |k, _v| %i[space_name environment_name].include?(k) },
|
159
|
+
)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
private
|
164
|
+
|
165
|
+
def processor
|
166
|
+
@processor ||= Processor::Async.new
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
end
|