sidekiq-bus 0.8.2 → 0.9.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 +4 -4
- data/CHANGELOG.md +5 -0
- data/lib/sidekiq-bus.rb +1 -0
- data/lib/sidekiq_bus/server.rb +139 -0
- data/lib/sidekiq_bus/server/views/bus.erb +202 -0
- data/lib/sidekiq_bus/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f2be4d5e020e0a15769b9b1afcf3f7ed36d1d6b
|
4
|
+
data.tar.gz: 9f1d638cf9f47eb1afa87bb21b8141d2baa27f10
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f9783a99bf3c8b0c6fb2df111362d77507d8d245112ec66707e82ee4c172bb78cc28f5e32026adbbb3ca4e1c0f11fc15c27f67cbd79d32545e40b1bb48a424b
|
7
|
+
data.tar.gz: 66b88100b6068b47ce2f28080eeb4eca7ce5ef669cef9bd71cf195893c43c88a976ccf4040cf0e08d14a45031f4195725079e6da29f1cc5e14a6b03eec3dfb1f
|
data/CHANGELOG.md
CHANGED
data/lib/sidekiq-bus.rb
CHANGED
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'sidekiq/web'
|
2
|
+
|
3
|
+
module SidekiqBus
|
4
|
+
module Server
|
5
|
+
def self.registered(app)
|
6
|
+
app.get('/bus') do
|
7
|
+
# you can define @instance_variables for passing into template
|
8
|
+
# Sidekiq uses erb for its templates so you should do it aswell
|
9
|
+
erb File.read(File.join(File.dirname(__FILE__), "server/views/bus.erb"))
|
10
|
+
end
|
11
|
+
|
12
|
+
app.post '/bus/unsubscribe' do
|
13
|
+
bus_app = ::QueueBus::Application.new(params[:name]).unsubscribe
|
14
|
+
redirect "#{root_path}bus"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Helpers
|
19
|
+
class << self
|
20
|
+
def parse_query(query_string)
|
21
|
+
has_open_brace = query_string.include?("{")
|
22
|
+
has_close_brace = query_string.include?("}")
|
23
|
+
has_multiple_lines = query_string.include?("\n")
|
24
|
+
has_colon = query_string.include?(":")
|
25
|
+
has_comma = query_string.include?(",")
|
26
|
+
has_quote = query_string.include?("\"")
|
27
|
+
|
28
|
+
exception = nil
|
29
|
+
|
30
|
+
# first let's see if it parses
|
31
|
+
begin
|
32
|
+
query_attributes = JSON.parse(query_string)
|
33
|
+
raise "Not a JSON Object" unless query_attributes.is_a?(Hash)
|
34
|
+
rescue Exception => e
|
35
|
+
exception = e
|
36
|
+
end
|
37
|
+
return query_attributes unless exception
|
38
|
+
|
39
|
+
if query_attributes
|
40
|
+
# it parsed but it's something else
|
41
|
+
if query_attributes.is_a?(Array) && query_attributes.length == 1
|
42
|
+
# maybe it's the thing from the queue
|
43
|
+
json_string = query_attributes.first
|
44
|
+
fixed = JSON.parse(json_string) rescue nil
|
45
|
+
return fixed if fixed
|
46
|
+
end
|
47
|
+
|
48
|
+
# something else?
|
49
|
+
raise exception
|
50
|
+
end
|
51
|
+
|
52
|
+
if !has_open_brace && !has_close_brace
|
53
|
+
# maybe they just forgot the braces
|
54
|
+
fixed = JSON.parse("{ #{query_string} }") rescue nil
|
55
|
+
return fixed if fixed
|
56
|
+
end
|
57
|
+
|
58
|
+
if !has_open_brace
|
59
|
+
# maybe they just forgot the braces
|
60
|
+
fixed = JSON.parse("{ #{query_string}") rescue nil
|
61
|
+
return fixed if fixed
|
62
|
+
end
|
63
|
+
|
64
|
+
if !has_close_brace
|
65
|
+
# maybe they just forgot the braces
|
66
|
+
fixed = JSON.parse("#{query_string} }") rescue nil
|
67
|
+
return fixed if fixed
|
68
|
+
end
|
69
|
+
|
70
|
+
if !has_multiple_lines && !has_colon && !has_open_brace && !has_close_brace
|
71
|
+
# we say they just put a bus_event type here, so help them out
|
72
|
+
return {"bus_event_type" => query_string, "more_here" => true}
|
73
|
+
end
|
74
|
+
|
75
|
+
if has_colon && !has_quote
|
76
|
+
# maybe it's some search syntax like this: field: value other: true, etc
|
77
|
+
# maybe use something like this later: https://github.com/dxwcyber/search-query-parser
|
78
|
+
|
79
|
+
# quote all the strings, (simply) tries to avoid integers
|
80
|
+
test_query = query_string.gsub(/([a-zA-z]\w*)/,'"\0"')
|
81
|
+
if !has_comma
|
82
|
+
test_query.gsub!("\n", ",\n")
|
83
|
+
end
|
84
|
+
if !has_open_brace && !has_close_brace
|
85
|
+
test_query = "{ #{test_query} }"
|
86
|
+
end
|
87
|
+
|
88
|
+
fixed = JSON.parse(test_query) rescue nil
|
89
|
+
return fixed if fixed
|
90
|
+
end
|
91
|
+
|
92
|
+
if has_open_brace && has_close_brace
|
93
|
+
# maybe the whole thing is a hash output from a hash.inspect log
|
94
|
+
ruby_hash_text = query_string.clone
|
95
|
+
# https://stackoverflow.com/questions/1667630/how-do-i-convert-a-string-object-into-a-hash-object
|
96
|
+
# Transform object string symbols to quoted strings
|
97
|
+
ruby_hash_text.gsub!(/([{,]\s*):([^>\s]+)\s*=>/, '\1"\2"=>')
|
98
|
+
# Transform object string numbers to quoted strings
|
99
|
+
ruby_hash_text.gsub!(/([{,]\s*)([0-9]+\.?[0-9]*)\s*=>/, '\1"\2"=>')
|
100
|
+
# Transform object value symbols to quotes strings
|
101
|
+
ruby_hash_text.gsub!(/([{,]\s*)(".+?"|[0-9]+\.?[0-9]*)\s*=>\s*:([^,}\s]+\s*)/, '\1\2=>"\3"')
|
102
|
+
# Transform array value symbols to quotes strings
|
103
|
+
ruby_hash_text.gsub!(/([\[,]\s*):([^,\]\s]+)/, '\1"\2"')
|
104
|
+
# fix up nil situation
|
105
|
+
ruby_hash_text.gsub!(/=>nil/, '=>null')
|
106
|
+
# Transform object string object value delimiter to colon delimiter
|
107
|
+
ruby_hash_text.gsub!(/([{,]\s*)(".+?"|[0-9]+\.?[0-9]*)\s*=>/, '\1\2:')
|
108
|
+
fixed = JSON.parse(ruby_hash_text) rescue nil
|
109
|
+
return fixed if fixed
|
110
|
+
end
|
111
|
+
|
112
|
+
raise exception
|
113
|
+
end
|
114
|
+
|
115
|
+
def sort_query(query_attributes)
|
116
|
+
query_attributes.each do |key, value|
|
117
|
+
if value.is_a?(Hash)
|
118
|
+
query_attributes[key] = sort_query(value)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
query_attributes.sort_by { |key| key }.to_h
|
122
|
+
end
|
123
|
+
|
124
|
+
def query_subscriptions(app, query_attributes)
|
125
|
+
# TODO: all of this can move to method in queue-bus to replace event_display_tuples
|
126
|
+
if query_attributes
|
127
|
+
subscriptions = app.subscription_matches(query_attributes)
|
128
|
+
else
|
129
|
+
subscriptions = app.send(:subscriptions).all
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
Sidekiq::Web.register SidekiqBus::Server
|
138
|
+
Sidekiq::Web.locales << File.expand_path(File.dirname(__FILE__) + "/web/locales")
|
139
|
+
Sidekiq::Web.tabs['Bus'] = 'bus'
|
@@ -0,0 +1,202 @@
|
|
1
|
+
|
2
|
+
<script LANGUAGE="JavaScript">
|
3
|
+
<!--
|
4
|
+
function confirmSubmit()
|
5
|
+
{
|
6
|
+
var agree=confirm("Are you sure you wish to continue?");
|
7
|
+
if (agree)
|
8
|
+
return true ;
|
9
|
+
else
|
10
|
+
return false ;
|
11
|
+
}
|
12
|
+
|
13
|
+
function setSample() {
|
14
|
+
var text = document.getElementById("query_attributes").textContent;
|
15
|
+
var textArea = document.getElementById('querytext');
|
16
|
+
textArea.value = text;
|
17
|
+
return false;
|
18
|
+
}
|
19
|
+
// -->
|
20
|
+
</script>
|
21
|
+
|
22
|
+
<%
|
23
|
+
app_hash = {}
|
24
|
+
class_hash = {}
|
25
|
+
event_hash = {}
|
26
|
+
query_string = params[:query].to_s.strip
|
27
|
+
|
28
|
+
query_attributes = nil
|
29
|
+
query_error = nil
|
30
|
+
if query_string.length > 0
|
31
|
+
begin
|
32
|
+
query_attributes = ::SidekiqBus::Server::Helpers.parse_query(query_string)
|
33
|
+
raise "Not a JSON Object" unless query_attributes.is_a?(Hash)
|
34
|
+
rescue Exception => e
|
35
|
+
query_attributes = nil
|
36
|
+
query_error = e.message
|
37
|
+
end
|
38
|
+
|
39
|
+
if query_attributes
|
40
|
+
# sort keys for display
|
41
|
+
query_attributes = ::SidekiqBus::Server::Helpers.sort_query(query_attributes)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# collect each differently
|
46
|
+
::QueueBus::Application.all.each do |app|
|
47
|
+
app_key = app.app_key
|
48
|
+
|
49
|
+
subscriptions = ::SidekiqBus::Server::Helpers.query_subscriptions(app, query_attributes)
|
50
|
+
subscriptions.each do |sub|
|
51
|
+
class_name = sub.class_name
|
52
|
+
queue = sub.queue_name
|
53
|
+
filters = sub.matcher.filters
|
54
|
+
sub_key = sub.key
|
55
|
+
|
56
|
+
if filters["bus_event_type"]
|
57
|
+
event = filters["bus_event_type"]
|
58
|
+
else
|
59
|
+
event = "see filter"
|
60
|
+
end
|
61
|
+
|
62
|
+
app_hash[app_key] ||= []
|
63
|
+
app_hash[app_key] << [sub_key, event, class_name, queue, filters]
|
64
|
+
|
65
|
+
class_hash[class_name] ||= []
|
66
|
+
class_hash[class_name] << [app_key, sub_key, event, queue, filters]
|
67
|
+
|
68
|
+
event_hash[event] ||= []
|
69
|
+
event_hash[event] << [app_key, sub_key, class_name, queue, filters]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# sort each list item by secondary label
|
74
|
+
class_hash.each do |_, array|
|
75
|
+
array.sort!{ |a,b| a.first <=> b.first }
|
76
|
+
end
|
77
|
+
event_hash.each do |_, array|
|
78
|
+
array.sort!{ |a,b| a.first <=> b.first }
|
79
|
+
end
|
80
|
+
|
81
|
+
# helper to display either
|
82
|
+
def display_row(name, val, button=nil, first=false)
|
83
|
+
form = ""
|
84
|
+
if button
|
85
|
+
text, url = button
|
86
|
+
form = "<form method='POST' action='#{url}' style='float:left; padding:0 5px 0 0;margin:0;'>#{csrf_tag}<input type='submit' name='' value='#{h(text)}' style='padding:0;margin:0;' onclick=\"return confirmSubmit();\"/><input type='hidden' name='name' value='#{h(name)}' /></form>"
|
87
|
+
end
|
88
|
+
|
89
|
+
if !val
|
90
|
+
out = "<td> </td><td> </td>"
|
91
|
+
else
|
92
|
+
one, two, three, queue, filters = val
|
93
|
+
out = "<td>#{h(one)}</td><td>#{h(two)}</td><td>#{h(three)}</td><td><a href='#{"queues/#{queue}"}'>#{h(queue)}</a></td>"
|
94
|
+
out << "<td>#{h(::QueueBus::Util.encode(filters).gsub(/\"bus_special_value_(\w+)\"/){ "(#{$1})" }).gsub(" ", " ").gsub('","', '", "')}</td>"
|
95
|
+
end
|
96
|
+
|
97
|
+
if first
|
98
|
+
"<tr><td>#{h(name)}#{form}</td>#{out}</tr>\n"
|
99
|
+
else
|
100
|
+
"<tr><td> </td>#{out}</tr>\n"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def output_hash(hash, action=nil)
|
105
|
+
out = ""
|
106
|
+
hash.keys.sort.each do |item|
|
107
|
+
display = hash[item]
|
108
|
+
first = display.shift
|
109
|
+
out << display_row(item, first, action, true)
|
110
|
+
display.each do |val|
|
111
|
+
out << display_row(item, val, action)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
out
|
115
|
+
end
|
116
|
+
%>
|
117
|
+
|
118
|
+
<h1 class='wi'>Sample Event</h1>
|
119
|
+
<p class='intro'>Enter JSON of an event to see applicable subscriptions.</p>
|
120
|
+
<div style="text-align: center;width:700px;">
|
121
|
+
-<form method="GET" action="<%= "bus" %>" style="float:none;padding:0;margin:0;">
|
122
|
+
<textarea id="querytext" name="query" style="padding: 10px;height:150px;width:700px;font-size:14px;font-family:monospace"><%=
|
123
|
+
h(query_string)
|
124
|
+
%></textarea>
|
125
|
+
<br/>
|
126
|
+
<button onclick="window.location.href = '<%= "bus" %>'; return false;">Clear</button>
|
127
|
+
<input type="submit" name="" value="Filter results to this event"/>
|
128
|
+
</form>
|
129
|
+
</div>
|
130
|
+
|
131
|
+
<% if query_error %>
|
132
|
+
<blockquote><pre style="text-align:left;font-family:monospace;margin:5px 0 5px 0;padding:10px;background:#f2dede;color:#a94442;"><code><%=
|
133
|
+
h(query_error.strip)
|
134
|
+
%></code></pre></blockquote>
|
135
|
+
<% end %>
|
136
|
+
<% if query_attributes %>
|
137
|
+
<blockquote><pre style="text-align:left;font-family:monospace;margin:5px 0 5px 0;padding:10px;background:#dff0d8;color:#3c763d;"><code id="query_attributes"><%=
|
138
|
+
h(JSON.pretty_generate(query_attributes).strip)
|
139
|
+
%></code></pre></blockquote>
|
140
|
+
<div style="text-align:right;">
|
141
|
+
<button onclick="return setSample();">Set Sample</button>
|
142
|
+
</div>
|
143
|
+
<% end %>
|
144
|
+
|
145
|
+
<hr/>
|
146
|
+
|
147
|
+
<h1 class='wi'>Applications</h1>
|
148
|
+
<p class='intro'>The apps below have registered the given classes and queues.</p>
|
149
|
+
<table class='table-striped table-bordered'>
|
150
|
+
<thead class="thead-dark">
|
151
|
+
<tr>
|
152
|
+
<th>App Key</th>
|
153
|
+
<th>Subscription Key</th>
|
154
|
+
<th>Event Type</th>
|
155
|
+
<th>Class Name</th>
|
156
|
+
<th>Queue</th>
|
157
|
+
<th>Filters</th>
|
158
|
+
</tr>
|
159
|
+
</thead>
|
160
|
+
|
161
|
+
<%= output_hash(app_hash, query_attributes ? false : ["Unsubscribe", "bus/unsubscribe"]) %>
|
162
|
+
</table>
|
163
|
+
|
164
|
+
<p> </p>
|
165
|
+
|
166
|
+
<h1 class='wi'>Events</h1>
|
167
|
+
<p class='intro'>The events below have been registered by the given applications and queues.</p>
|
168
|
+
|
169
|
+
<table class='table-striped table-bordered'>
|
170
|
+
<thead class="thead-dark">
|
171
|
+
<tr>
|
172
|
+
<th>Event Type</th>
|
173
|
+
<th>App Key</th>
|
174
|
+
<th>Subscription Key</th>
|
175
|
+
<th>Class Name</th>
|
176
|
+
<th>Queue</th>
|
177
|
+
<th>Filters</th>
|
178
|
+
</tr>
|
179
|
+
</thead>
|
180
|
+
<%= output_hash(event_hash, false) %>
|
181
|
+
</table>
|
182
|
+
|
183
|
+
|
184
|
+
|
185
|
+
<p> </p>
|
186
|
+
|
187
|
+
<h1 class='wi'>Classes</h1>
|
188
|
+
<p class='intro'>The classes below have been registered by the given applications and queues.</p>
|
189
|
+
<table class='table-striped table-bordered'>
|
190
|
+
<thead class="thead-dark">
|
191
|
+
<tr>
|
192
|
+
<th>Class Name</th>
|
193
|
+
<th>App Key</th>
|
194
|
+
<th>Subscription Key</th>
|
195
|
+
<th>Event Type</th>
|
196
|
+
<th>Queue</th>
|
197
|
+
<th>Filters</th>
|
198
|
+
</tr>
|
199
|
+
</thead>
|
200
|
+
<%= output_hash(class_hash, false) %>
|
201
|
+
</table>
|
202
|
+
|
data/lib/sidekiq_bus/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq-bus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Leonard
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-12-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: queue-bus
|
@@ -184,6 +184,8 @@ files:
|
|
184
184
|
- lib/sidekiq-bus.rb
|
185
185
|
- lib/sidekiq_bus/adapter.rb
|
186
186
|
- lib/sidekiq_bus/middleware/retry.rb
|
187
|
+
- lib/sidekiq_bus/server.rb
|
188
|
+
- lib/sidekiq_bus/server/views/bus.erb
|
187
189
|
- lib/sidekiq_bus/tasks.rb
|
188
190
|
- lib/sidekiq_bus/version.rb
|
189
191
|
- sidekiq-bus.gemspec
|