wabur 0.5.0 → 0.6.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/bin/wabur +42 -17
- data/export/assets/css/wab.css +365 -1
- data/export/assets/css/wab.css.map +1 -1
- data/lib/wab/controller.rb +14 -10
- data/lib/wab/impl.rb +13 -0
- data/lib/wab/impl/bool_expr.rb +3 -0
- data/lib/wab/impl/configuration.rb +59 -43
- data/lib/wab/impl/data.rb +4 -4
- data/lib/wab/impl/exprs/and.rb +6 -5
- data/lib/wab/impl/exprs/between.rb +2 -2
- data/lib/wab/impl/exprs/eq.rb +2 -2
- data/lib/wab/impl/exprs/gt.rb +2 -2
- data/lib/wab/impl/exprs/gte.rb +2 -2
- data/lib/wab/impl/exprs/has.rb +2 -2
- data/lib/wab/impl/exprs/in.rb +2 -2
- data/lib/wab/impl/exprs/lt.rb +2 -2
- data/lib/wab/impl/exprs/lte.rb +2 -2
- data/lib/wab/impl/exprs/or.rb +6 -5
- data/lib/wab/impl/exprs/regex.rb +2 -2
- data/lib/wab/impl/handler.rb +10 -7
- data/lib/wab/impl/init.rb +135 -73
- data/lib/wab/impl/path_expr.rb +3 -0
- data/lib/wab/impl/shell.rb +10 -3
- data/lib/wab/impl/templates/wabur.conf.template +1 -2
- data/lib/wab/io/engine.rb +2 -2
- data/lib/wab/io/shell.rb +9 -3
- data/lib/wab/ui/flow.rb +3 -2
- data/lib/wab/version.rb +1 -1
- data/test/bench_io_shell.rb +2 -2
- data/test/test_io_shell.rb +2 -2
- data/test/tmp/lib/spawn.rb +44 -0
- data/test/tmp/lib/ui_controller.rb +20 -0
- metadata +6 -2
data/lib/wab/impl/exprs/regex.rb
CHANGED
@@ -14,13 +14,13 @@ module WAB
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def eval(data)
|
17
|
-
value = data.get(
|
17
|
+
value = data.get(path)
|
18
18
|
return @rx === value if value.is_a?(String)
|
19
19
|
false
|
20
20
|
end
|
21
21
|
|
22
22
|
def native()
|
23
|
-
['REGEX',
|
23
|
+
['REGEX', path, @rx.source]
|
24
24
|
end
|
25
25
|
|
26
26
|
end # Regex
|
data/lib/wab/impl/handler.rb
CHANGED
@@ -52,7 +52,7 @@ module WAB
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def log_request_with_body(caller, path, query, body)
|
55
|
-
@shell.logger.info("#{caller}
|
55
|
+
@shell.logger.info("#{caller} #{path.join('/')}#{query}\n#{body.json(@shell.indent)}")
|
56
56
|
end
|
57
57
|
|
58
58
|
# Pulls and converts the request path, query, and body. Also returns the
|
@@ -61,11 +61,13 @@ module WAB
|
|
61
61
|
path = req.path.split('/')[1..-1]
|
62
62
|
query = {}
|
63
63
|
req.query.each { |k,v| query[k.to_sym] = v }
|
64
|
-
|
64
|
+
request_body = req.body
|
65
|
+
if request_body.nil?
|
65
66
|
body = nil
|
66
67
|
else
|
67
|
-
body =
|
68
|
-
|
68
|
+
body = Data.new(
|
69
|
+
Oj.strict_load(request_body, symbol_keys: true)
|
70
|
+
)
|
69
71
|
body.detect
|
70
72
|
end
|
71
73
|
[@shell.path_controller(path), path, query, body]
|
@@ -74,10 +76,11 @@ module WAB
|
|
74
76
|
# Sends the results from a controller request.
|
75
77
|
def send_result(result, res, path, query)
|
76
78
|
result = @shell.data(result) unless result.is_a?(WAB::Data)
|
79
|
+
response_body = result.json(@shell.indent)
|
77
80
|
res.status = 200
|
78
81
|
res['Content-Type'] = 'application/json'
|
79
|
-
@shell.logger.debug("reply to #{path.join('/')}#{query}: #{
|
80
|
-
res.body =
|
82
|
+
@shell.logger.debug("reply to #{path.join('/')}#{query}: #{response_body}") if @shell.logger.debug?
|
83
|
+
res.body = response_body
|
81
84
|
end
|
82
85
|
|
83
86
|
# Sends an error from a rescued call.
|
@@ -87,7 +90,7 @@ module WAB
|
|
87
90
|
body = { code: -1, error: "#{e.class}: #{e.message}" }
|
88
91
|
body[:backtrace] = e.backtrace
|
89
92
|
res.body = @shell.data(body).json(@shell.indent)
|
90
|
-
@shell.logger.warn(
|
93
|
+
@shell.logger.warn(Impl.format_error(e))
|
91
94
|
end
|
92
95
|
|
93
96
|
end # Handler
|
data/lib/wab/impl/init.rb
CHANGED
@@ -10,99 +10,161 @@ module WAB
|
|
10
10
|
# - config/opo.conf
|
11
11
|
# - config/opo-rub.conf
|
12
12
|
# - lib/uicontroller.rb
|
13
|
+
#
|
14
|
+
# If the site option was set then all the export files are used to
|
15
|
+
# populate a site directory as well.
|
13
16
|
class Init
|
14
17
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
+
def self.setup(path, config)
|
19
|
+
self.new(path, config)
|
20
|
+
end
|
18
21
|
|
19
|
-
|
20
|
-
config_dir = "#{path}/config"
|
21
|
-
lib_dir = "#{path}/lib"
|
22
|
+
private
|
22
23
|
|
23
|
-
|
24
|
+
def initialize(path, config)
|
25
|
+
@types = config[:rest] || []
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
+
if (@types.nil? || @types.empty?) && !init_site
|
28
|
+
raise WAB::Error.new("At least one record type is required for 'new' or 'init'.")
|
29
|
+
end
|
30
|
+
check_dup_type
|
27
31
|
|
28
|
-
|
29
|
-
|
30
|
-
|
32
|
+
@verbose = config[:verbosity]
|
33
|
+
@verbose = 'INFO' == @verbose || 'DEBUG' == @verbose || Logger::INFO == @verbose || Logger::DEBUG == @verbose
|
34
|
+
@write_cnt = 0
|
35
|
+
@exist_cnt = 0
|
36
|
+
@base_len = path.length + 1
|
31
37
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
abort
|
36
|
-
end
|
38
|
+
config_dir = "#{path}/config"
|
39
|
+
lib_dir = "#{path}/lib"
|
40
|
+
init_site = config[:site]
|
37
41
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
42
|
+
FileUtils.mkdir_p([config_dir, lib_dir])
|
43
|
+
|
44
|
+
write_ui_controllers(lib_dir)
|
45
|
+
write_spawn(lib_dir)
|
46
|
+
|
47
|
+
write_wabur_conf(config_dir)
|
48
|
+
write_opo_conf(config_dir)
|
49
|
+
write_opo_rub_conf(config_dir)
|
50
|
+
|
51
|
+
copy_site(File.expand_path("#{__dir__}/../../../export"), "#{path}/site") if init_site
|
52
|
+
|
53
|
+
puts "\nSuccessfully initialized a WAB workspace at #{path}."
|
54
|
+
puts " Wrote #{@write_cnt} files." unless @write_cnt.zero?
|
55
|
+
puts " Skipped #{@exist_cnt} files that already existed" unless @exist_cnt.zero?
|
56
|
+
|
57
|
+
rescue StandardError => e
|
58
|
+
# TBD: Issue more helpful error message
|
59
|
+
puts WAB::Impl.format_error(e)
|
60
|
+
abort
|
61
|
+
end
|
62
|
+
|
63
|
+
def check_dup_type
|
64
|
+
type_map = {}
|
65
|
+
@types.each { |type|
|
66
|
+
key = type.downcase
|
67
|
+
raise DuplicateError.new(key) if type_map.has_key?(key)
|
68
|
+
type_map[key] = true
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
def write_ui_controllers(dir)
|
73
|
+
rest_flows = ''
|
74
|
+
@types.each { |type|
|
75
|
+
rest_flows << %|
|
56
76
|
add_flow(WAB::UI::RestFlow.new(shell,
|
57
77
|
{
|
58
78
|
kind: '#{type}',
|
59
79
|
}, ['$ref']))|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
80
|
+
}
|
81
|
+
write_file(dir, 'ui_controller.rb', { rest_flows: rest_flows })
|
82
|
+
end
|
83
|
+
|
84
|
+
def write_spawn(dir)
|
85
|
+
controllers = ''
|
86
|
+
@types.each { |type|
|
87
|
+
controllers << %|
|
68
88
|
shell.register_controller('#{type}', WAB::OpenController.new(shell))|
|
69
|
-
|
70
|
-
|
71
|
-
|
89
|
+
}
|
90
|
+
write_file(dir, 'spawn.rb', { controllers: controllers })
|
91
|
+
end
|
72
92
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
handler.#{
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
93
|
+
def write_wabur_conf(dir)
|
94
|
+
handlers = ''
|
95
|
+
@types.each_index { |index|
|
96
|
+
natural_index = index + 1
|
97
|
+
handlers << %|
|
98
|
+
handler.#{natural_index}.type = #{@types[index]}
|
99
|
+
handler.#{natural_index}.handler = WAB::OpenController|
|
100
|
+
}
|
101
|
+
write_file(dir, 'wabur.conf', { handlers: handlers })
|
102
|
+
end
|
103
|
+
|
104
|
+
def write_opo_conf(dir)
|
105
|
+
write_file(dir, 'opo.conf')
|
106
|
+
end
|
107
|
+
|
108
|
+
def write_opo_rub_conf(dir)
|
109
|
+
handlers = ''
|
110
|
+
@types.each_index { |index|
|
111
|
+
type = @types[index]
|
112
|
+
slug = type.downcase
|
113
|
+
handlers << %|
|
114
|
+
handler.#{slug}.path = /v1/#{type}/**
|
115
|
+
handler.#{slug}.class = WAB::OpenController
|
94
116
|
|
|
95
|
-
|
96
|
-
|
97
|
-
|
117
|
+
}
|
118
|
+
write_file(dir, 'opo-rub.conf', { handlers: handlers })
|
119
|
+
end
|
120
|
+
|
121
|
+
def copy_site(src, dest)
|
122
|
+
FileUtils.mkdir_p(dest)
|
123
|
+
Dir.foreach(src) { |filename|
|
124
|
+
next if filename.start_with?('.')
|
125
|
+
src_path = "#{src}/#{filename}"
|
126
|
+
dest_path = "#{dest}/#{filename}"
|
98
127
|
|
99
|
-
|
128
|
+
if File.directory?(src_path)
|
129
|
+
copy_site(src_path, dest_path)
|
130
|
+
elsif File.file?(src_path)
|
131
|
+
rel_path = dest_path[@base_len..-1] if @verbose
|
132
|
+
if File.exist?(dest_path)
|
133
|
+
verbose_log('exists', rel_path)
|
134
|
+
@exist_cnt += 1
|
135
|
+
next
|
136
|
+
end
|
137
|
+
out = `cp #{src_path} #{dest_path}`
|
138
|
+
@write_cnt += 1
|
139
|
+
if out.empty?
|
140
|
+
verbose_log('wrote', rel_path)
|
141
|
+
else
|
142
|
+
# the error message from the OS
|
143
|
+
puts out
|
144
|
+
end
|
145
|
+
end
|
146
|
+
}
|
147
|
+
end
|
148
|
+
|
149
|
+
def write_file(dir, filename, gsub_data=nil)
|
150
|
+
filepath = "#{dir}/#{filename}"
|
151
|
+
if File.exist?(filepath)
|
152
|
+
verbose_log('exists', filepath[@base_len..-1])
|
153
|
+
@exist_cnt += 1
|
154
|
+
else
|
100
155
|
template = File.open("#{__dir__}/templates/#{filename}.template", 'rb') { |f| f.read }
|
101
156
|
content = gsub_data.nil? ? template : template % gsub_data
|
102
|
-
File.open(
|
157
|
+
File.open(filepath, 'wb') { |f| f.write(content) }
|
158
|
+
verbose_log('wrote', filepath[@base_len..-1])
|
159
|
+
@write_cnt += 1
|
103
160
|
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def verbose_log(topic, message)
|
164
|
+
return unless @verbose
|
165
|
+
puts "#{topic.to_s.rjust(10)}: #{message}"
|
166
|
+
end
|
104
167
|
|
105
|
-
end # self
|
106
168
|
end # Init
|
107
169
|
end # Impl
|
108
170
|
end # WAB
|
data/lib/wab/impl/path_expr.rb
CHANGED
data/lib/wab/impl/shell.rb
CHANGED
@@ -58,6 +58,7 @@ module WAB
|
|
58
58
|
server = WEBrick::HTTPServer.new(Port: @http_port,
|
59
59
|
DocumentRoot: @http_dir,
|
60
60
|
MimeTypes: mime_types)
|
61
|
+
server.logger.level = 5 - @logger.level unless @logger.nil?
|
61
62
|
server.mount(@pre_path, Handler, self)
|
62
63
|
server.mount('/', ExportProxy, @http_dir) if @export_proxy
|
63
64
|
|
@@ -96,16 +97,16 @@ module WAB
|
|
96
97
|
return path_controller(path) unless path.nil? || (path.length <= @path_pos)
|
97
98
|
|
98
99
|
content = data.get(:content)
|
99
|
-
return @controllers[content.get(@type_key)] ||
|
100
|
+
return @controllers[content.get(@type_key)] || default_controller unless content.nil?
|
100
101
|
|
101
|
-
|
102
|
+
default_controller
|
102
103
|
end
|
103
104
|
|
104
105
|
# Returns the controller according to the type in the path.
|
105
106
|
#
|
106
107
|
# path: path Array such as from a URL
|
107
108
|
def path_controller(path)
|
108
|
-
@controllers[path[@path_pos]] ||
|
109
|
+
@controllers[path[@path_pos]] || default_controller
|
109
110
|
end
|
110
111
|
|
111
112
|
# Create and return a new data instance with the provided initial value.
|
@@ -123,6 +124,12 @@ module WAB
|
|
123
124
|
Data.new(value, repair)
|
124
125
|
end
|
125
126
|
|
127
|
+
private
|
128
|
+
|
129
|
+
def default_controller
|
130
|
+
@default_controller ||= @controllers[nil]
|
131
|
+
end
|
132
|
+
|
126
133
|
end # Shell
|
127
134
|
end # Impl
|
128
135
|
end # WAB
|
data/lib/wab/io/engine.rb
CHANGED
@@ -29,7 +29,7 @@ module WAB
|
|
29
29
|
begin
|
30
30
|
break unless process_msg(@queue.pop)
|
31
31
|
rescue Exception => e
|
32
|
-
$stderr.puts
|
32
|
+
$stderr.puts WAB::Impl.format_error(e)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
}
|
@@ -60,7 +60,7 @@ module WAB
|
|
60
60
|
proc_threads.each { |t| Thread.kill(t) }
|
61
61
|
Process.exit(0)
|
62
62
|
else
|
63
|
-
$stderr.puts "
|
63
|
+
$stderr.puts WAB::Impl.format_error("Invalid api value (#{api}) in message.")
|
64
64
|
end
|
65
65
|
}
|
66
66
|
end
|
data/lib/wab/io/shell.rb
CHANGED
@@ -59,16 +59,16 @@ module WAB
|
|
59
59
|
return path_controller(path) unless path.nil? || (path.length <= @path_pos)
|
60
60
|
|
61
61
|
content = data.get(:content)
|
62
|
-
return @controllers[content.get(@type_key)] ||
|
62
|
+
return @controllers[content.get(@type_key)] || default_controller unless content.nil?
|
63
63
|
|
64
|
-
|
64
|
+
default_controller
|
65
65
|
end
|
66
66
|
|
67
67
|
# Returns the controller according to the type in the path.
|
68
68
|
#
|
69
69
|
# path: path Array such as from a URL
|
70
70
|
def path_controller(path)
|
71
|
-
@controllers[path[@path_pos]] ||
|
71
|
+
@controllers[path[@path_pos]] || default_controller
|
72
72
|
end
|
73
73
|
|
74
74
|
# Create and return a new data instance with the provided initial value.
|
@@ -133,6 +133,12 @@ module WAB
|
|
133
133
|
raise NotImplementedError.new
|
134
134
|
end
|
135
135
|
|
136
|
+
private
|
137
|
+
|
138
|
+
def default_controller
|
139
|
+
@default_controller ||= @controllers[nil]
|
140
|
+
end
|
141
|
+
|
136
142
|
end # Shell
|
137
143
|
end # IO
|
138
144
|
end # WAB
|
data/lib/wab/ui/flow.rb
CHANGED
@@ -32,9 +32,10 @@ module WAB
|
|
32
32
|
# path:: array of tokens in the path.
|
33
33
|
def read(path, _query)
|
34
34
|
results = []
|
35
|
-
|
35
|
+
path_pos = @shell.path_pos
|
36
|
+
if path_pos + 2 == path.length
|
36
37
|
# Return the description of the named display.
|
37
|
-
name = path[
|
38
|
+
name = path[path_pos + 1]
|
38
39
|
display = get_display(name)
|
39
40
|
display[:entry] = true if !display.nil? && display.name == @entry
|
40
41
|
results << {id: name, data: display.spec} unless display.nil?
|
data/lib/wab/version.rb
CHANGED
data/test/bench_io_shell.rb
CHANGED
@@ -37,10 +37,10 @@ else
|
|
37
37
|
reply = nil
|
38
38
|
start = Time.now
|
39
39
|
n.times { |i|
|
40
|
-
to_w.puts(WAB::Impl::Data.new({rid: 'rid-read-id', api: 1, body: {op: 'GET', path: ['sample', '12345']}}
|
40
|
+
to_w.puts(WAB::Impl::Data.new({rid: 'rid-read-id', api: 1, body: {op: 'GET', path: ['sample', '12345']}}).json)
|
41
41
|
to_w.flush
|
42
42
|
Oj.strict_load(from_r, symbol_keys: true) { |msg| reply = msg; break }
|
43
|
-
to_w.puts(WAB::Impl::Data.new({rid: "#{i+1}", api: 4, body: {code: 0, results:[{kind: 'sample', id: 12345, num: 7}]}}
|
43
|
+
to_w.puts(WAB::Impl::Data.new({rid: "#{i+1}", api: 4, body: {code: 0, results:[{kind: 'sample', id: 12345, num: 7}]}}).json)
|
44
44
|
to_w.flush
|
45
45
|
Oj.strict_load(from_r, symbol_keys: true) { |msg| reply = msg; break }
|
46
46
|
}
|