MuranoCLI 3.0.7 → 3.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/.ignore +1 -1
- data/.rubocop.yml +10 -5
- data/.trustme.sh +272 -106
- data/.trustme.vim +20 -1
- data/Gemfile +7 -5
- data/LICENSE.txt +14 -15
- data/MuranoCLI.gemspec +7 -5
- data/Rakefile +5 -5
- data/bin/murano +4 -4
- data/lib/MrMurano/Account.rb +13 -8
- data/lib/MrMurano/Business.rb +6 -7
- data/lib/MrMurano/Commander-Entry.rb +5 -5
- data/lib/MrMurano/Config-Migrate.rb +4 -4
- data/lib/MrMurano/Config.rb +27 -6
- data/lib/MrMurano/Content.rb +5 -5
- data/lib/MrMurano/Exchange-Element.rb +4 -4
- data/lib/MrMurano/Exchange.rb +4 -4
- data/lib/MrMurano/Gateway.rb +22 -11
- data/lib/MrMurano/Keystore.rb +4 -4
- data/lib/MrMurano/Logs.rb +87 -0
- data/lib/MrMurano/Mock.rb +5 -4
- data/lib/MrMurano/Passwords.rb +4 -5
- data/lib/MrMurano/ProjectFile.rb +4 -4
- data/lib/MrMurano/ReCommander.rb +4 -4
- data/lib/MrMurano/Setting.rb +5 -5
- data/lib/MrMurano/Settings-HttpService.rb +9 -6
- data/lib/MrMurano/Solution-ServiceConfig.rb +5 -5
- data/lib/MrMurano/Solution-Services.rb +76 -50
- data/lib/MrMurano/Solution-Users.rb +5 -4
- data/lib/MrMurano/Solution.rb +6 -6
- data/lib/MrMurano/SolutionId.rb +4 -4
- data/lib/MrMurano/SubCmdGroupContext.rb +4 -4
- data/lib/MrMurano/SyncAllowed.rb +4 -4
- data/lib/MrMurano/SyncRoot.rb +5 -5
- data/lib/MrMurano/SyncUpDown-Core.rb +515 -0
- data/lib/MrMurano/SyncUpDown-Item.rb +159 -0
- data/lib/MrMurano/SyncUpDown.rb +120 -688
- data/lib/MrMurano/Webservice-Cors.rb +4 -4
- data/lib/MrMurano/Webservice-Endpoint.rb +9 -6
- data/lib/MrMurano/Webservice-File.rb +5 -4
- data/lib/MrMurano/Webservice.rb +5 -5
- data/lib/MrMurano/commands/business.rb +4 -4
- data/lib/MrMurano/commands/completion.rb +6 -6
- data/lib/MrMurano/commands/config.rb +7 -5
- data/lib/MrMurano/commands/content.rb +5 -4
- data/lib/MrMurano/commands/cors.rb +4 -4
- data/lib/MrMurano/commands/devices.rb +6 -6
- data/lib/MrMurano/commands/domain.rb +4 -4
- data/lib/MrMurano/commands/exchange.rb +4 -4
- data/lib/MrMurano/commands/gb.rb +4 -4
- data/lib/MrMurano/commands/globals.rb +12 -4
- data/lib/MrMurano/commands/init.rb +5 -4
- data/lib/MrMurano/commands/keystore.rb +4 -4
- data/lib/MrMurano/commands/link.rb +4 -4
- data/lib/MrMurano/commands/login.rb +4 -4
- data/lib/MrMurano/commands/logs.rb +229 -76
- data/lib/MrMurano/commands/mock.rb +4 -4
- data/lib/MrMurano/commands/password.rb +4 -4
- data/lib/MrMurano/commands/postgresql.rb +4 -4
- data/lib/MrMurano/commands/settings.rb +4 -4
- data/lib/MrMurano/commands/show.rb +4 -4
- data/lib/MrMurano/commands/solution.rb +4 -4
- data/lib/MrMurano/commands/solution_picker.rb +4 -4
- data/lib/MrMurano/commands/status.rb +12 -4
- data/lib/MrMurano/commands/sync.rb +4 -4
- data/lib/MrMurano/commands/timeseries.rb +4 -4
- data/lib/MrMurano/commands/tsdb.rb +6 -7
- data/lib/MrMurano/commands/usage.rb +4 -4
- data/lib/MrMurano/commands.rb +4 -4
- data/lib/MrMurano/hash.rb +5 -5
- data/lib/MrMurano/http.rb +26 -22
- data/lib/MrMurano/makePretty.rb +194 -10
- data/lib/MrMurano/optparse.rb +1 -1
- data/lib/MrMurano/orderedhash.rb +1 -1
- data/lib/MrMurano/progress.rb +4 -4
- data/lib/MrMurano/verbosing.rb +6 -6
- data/lib/MrMurano/version.rb +5 -5
- data/lib/MrMurano.rb +7 -4
- data/spec/Account-Passwords_spec.rb +4 -4
- data/spec/Account_spec.rb +4 -4
- data/spec/Business_spec.rb +4 -4
- data/spec/ConfigFile_spec.rb +4 -4
- data/spec/ConfigMigrate_spec.rb +5 -4
- data/spec/Config_spec.rb +5 -4
- data/spec/Content_spec.rb +5 -4
- data/spec/GatewayBase_spec.rb +4 -4
- data/spec/GatewayDevice_spec.rb +4 -4
- data/spec/GatewayResource_spec.rb +5 -4
- data/spec/GatewaySettings_spec.rb +4 -4
- data/spec/Http_spec.rb +4 -4
- data/spec/MakePretties_spec.rb +20 -20
- data/spec/Mock_spec.rb +4 -4
- data/spec/ProjectFile_spec.rb +4 -4
- data/spec/Setting_spec.rb +4 -4
- data/spec/Solution-ServiceConfig_spec.rb +4 -4
- data/spec/Solution-ServiceEventHandler_spec.rb +5 -4
- data/spec/Solution-ServiceModules_spec.rb +5 -4
- data/spec/Solution-UsersRoles_spec.rb +5 -4
- data/spec/Solution_spec.rb +4 -4
- data/spec/SyncRoot_spec.rb +4 -4
- data/spec/SyncUpDown_spec.rb +67 -21
- data/spec/Verbosing_spec.rb +12 -10
- data/spec/Webservice-Cors_spec.rb +4 -4
- data/spec/Webservice-Endpoint_spec.rb +5 -4
- data/spec/Webservice-File_spec.rb +5 -4
- data/spec/Webservice-Setting_spec.rb +4 -4
- data/spec/_workspace.rb +4 -4
- data/spec/cmd_business_spec.rb +4 -5
- data/spec/cmd_common.rb +51 -20
- data/spec/cmd_config_spec.rb +4 -5
- data/spec/cmd_content_spec.rb +4 -5
- data/spec/cmd_cors_spec.rb +4 -5
- data/spec/cmd_device_spec.rb +5 -6
- data/spec/cmd_domain_spec.rb +4 -5
- data/spec/cmd_exchange_spec.rb +4 -5
- data/spec/cmd_help_spec.rb +4 -5
- data/spec/cmd_init_spec.rb +16 -35
- data/spec/cmd_keystore_spec.rb +4 -5
- data/spec/cmd_link_spec.rb +11 -12
- data/spec/cmd_logs_spec.rb +162 -0
- data/spec/cmd_password_spec.rb +4 -5
- data/spec/cmd_setting_application_spec.rb +4 -5
- data/spec/cmd_setting_product_spec.rb +4 -5
- data/spec/cmd_status_spec.rb +44 -81
- data/spec/cmd_syncdown_application_spec.rb +7 -10
- data/spec/cmd_syncdown_both_spec.rb +10 -25
- data/spec/cmd_syncup_spec.rb +31 -37
- data/spec/cmd_usage_spec.rb +4 -5
- data/spec/fixtures/dumped_config +1 -0
- data/spec/fixtures/websocket/logs_blather.rb +27 -0
- data/spec/fixtures/websocket/logs_faker.rb +153 -0
- data/spec/fixtures/websocket/simple_connection.rb +45 -0
- data/spec/fixtures/websocket/simple_options.rb +77 -0
- data/spec/fixtures/websocket/simple_server.rb +69 -0
- data/spec/fixtures/websocket/wss-echo.rb +48 -0
- data/spec/fixtures/websocket/wss-fake-logs.rb +20 -0
- metadata +55 -2
data/spec/cmd_usage_spec.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
|
-
#
|
1
|
+
# Copyright © 2016-2017 Exosite LLC. All Rights Reserved
|
2
|
+
# License: PROPRIETARY. See LICENSE.txt.
|
2
3
|
# frozen_string_literal: true
|
3
4
|
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# vim:tw=0:ts=2:sw=2:et:ai
|
5
|
+
# vim:tw=0:ts=2:sw=2:et:ai
|
6
|
+
# Unauthorized copying of this file is strictly prohibited.
|
7
7
|
|
8
8
|
require 'fileutils'
|
9
9
|
require 'open3'
|
10
|
-
require 'pathname'
|
11
10
|
require 'cmd_common'
|
12
11
|
|
13
12
|
RSpec.describe 'murano usage', :cmd, :needs_password do
|
data/spec/fixtures/dumped_config
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
# Copyright © 2016-2017 Exosite LLC. All Rights Reserved
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# License: PROPRIETARY. See LICENSE.txt.
|
5
|
+
# Unauthorized copying of this file is strictly prohibited.
|
6
|
+
# vim:tw=0:ts=2:sw=2:et:ai
|
7
|
+
|
8
|
+
require 'json'
|
9
|
+
|
10
|
+
require 'eventmachine'
|
11
|
+
|
12
|
+
require_relative 'simple_connection'
|
13
|
+
require_relative 'logs_faker'
|
14
|
+
|
15
|
+
class LogsBlatherConnection < SimpleWebSocket::SimpleConnection
|
16
|
+
include LogsFakerModule
|
17
|
+
def conn_on_open(event)
|
18
|
+
super(event)
|
19
|
+
_timer = EventMachine::PeriodicTimer.new(1) do
|
20
|
+
resp = JSON.generate(random_example)
|
21
|
+
@driver.text(resp)
|
22
|
+
# If we needed to stop the timer:
|
23
|
+
# _timer.cancel
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,153 @@
|
|
1
|
+
# Copyright © 2016-2017 Exosite LLC. All Rights Reserved
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# License: PROPRIETARY. See LICENSE.txt.
|
5
|
+
# Unauthorized copying of this file is strictly prohibited.
|
6
|
+
# vim:tw=0:ts=2:sw=2:et:ai
|
7
|
+
|
8
|
+
module LogsFakerModule
|
9
|
+
def initialize
|
10
|
+
super
|
11
|
+
@examples = [
|
12
|
+
example_type_script,
|
13
|
+
example_type_call,
|
14
|
+
example_type_event,
|
15
|
+
example_type_config_device_v1,
|
16
|
+
example_type_config_null,
|
17
|
+
example_type_config_newservice,
|
18
|
+
example_severity_build(0),
|
19
|
+
example_severity_build(1),
|
20
|
+
example_severity_build(2),
|
21
|
+
example_severity_build(3),
|
22
|
+
example_severity_build(4),
|
23
|
+
example_severity_build(5),
|
24
|
+
example_severity_build(6),
|
25
|
+
example_severity_build(7),
|
26
|
+
example_severity_build(8),
|
27
|
+
]
|
28
|
+
end
|
29
|
+
|
30
|
+
def random_example
|
31
|
+
@examples[Random.rand(@examples.length)]
|
32
|
+
end
|
33
|
+
|
34
|
+
# The examples below are from the Service & Script Debug Log RFC:
|
35
|
+
# https://docs.google.com/document/d/1mlLSLXJj0lMDqpblzEwfAew_G8C3e5HCtAgjyyrGaKc/edit#heading=h.nrw8qx9k0clk
|
36
|
+
|
37
|
+
def example_type_script
|
38
|
+
{
|
39
|
+
type: 'script',
|
40
|
+
timestamp: 1_474_489_282_537,
|
41
|
+
severity: 6, # info
|
42
|
+
message: 'abc from lua',
|
43
|
+
tracking_id: '<UUID>',
|
44
|
+
service: 'webservice',
|
45
|
+
event: 'request',
|
46
|
+
data: { # Type specific
|
47
|
+
endpoint: 'GET:/index',
|
48
|
+
location: 'GET:/index:123',
|
49
|
+
elapsed: 10,
|
50
|
+
},
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
def example_type_call
|
55
|
+
{
|
56
|
+
type: 'call',
|
57
|
+
timestamp: 1_474_489_282_537,
|
58
|
+
severity: 3, # error
|
59
|
+
message: 'Service Call failed with error: timeout',
|
60
|
+
tracking_id: '<UUID>',
|
61
|
+
service: 'keystore',
|
62
|
+
event: 'get', # The operation id
|
63
|
+
data: { # Type specific
|
64
|
+
request: '{..}',
|
65
|
+
response: '{..}',
|
66
|
+
code: 504,
|
67
|
+
},
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
def example_type_event
|
72
|
+
{
|
73
|
+
type: 'event',
|
74
|
+
timestamp: 1_474_489_282_537,
|
75
|
+
severity: 3, # error
|
76
|
+
message: 'Event trigger failed with: event handler not found',
|
77
|
+
tracking_id: '<UUID>',
|
78
|
+
service: 'timer',
|
79
|
+
event: 'timer',
|
80
|
+
data: { # Type specific
|
81
|
+
request: '<incoming payload>',
|
82
|
+
response: '<lua response payload>',
|
83
|
+
code: 404,
|
84
|
+
},
|
85
|
+
}
|
86
|
+
end
|
87
|
+
|
88
|
+
def example_type_config_device_v1
|
89
|
+
{
|
90
|
+
type: 'config',
|
91
|
+
timestamp: 1_474_489_282_537,
|
92
|
+
severity: 4, # warning
|
93
|
+
message: "The service 'Device' used by the solution has been deprecated. Refer to the Service documentation for more information.",
|
94
|
+
tracking_id: '<UUID>',
|
95
|
+
service: 'deviceV1',
|
96
|
+
event: nil,
|
97
|
+
data: {},
|
98
|
+
}
|
99
|
+
end
|
100
|
+
|
101
|
+
def example_type_config_null
|
102
|
+
{
|
103
|
+
type: 'config',
|
104
|
+
timestamp: 1_474_489_282_537,
|
105
|
+
severity: 5, # notice
|
106
|
+
message: 'The module ‘util’ has been updated',
|
107
|
+
tracking_id: '<UUID>',
|
108
|
+
service: nil, # if eventhandler here fill the service alias
|
109
|
+
event: nil, # if eventhandler script here fill the event
|
110
|
+
data: {
|
111
|
+
module: 'util',
|
112
|
+
code: 200,
|
113
|
+
},
|
114
|
+
}
|
115
|
+
end
|
116
|
+
|
117
|
+
def example_type_config_newservice
|
118
|
+
{
|
119
|
+
type: 'config',
|
120
|
+
timestamp: 1_474_489_282_537,
|
121
|
+
severity: 5, # notice
|
122
|
+
message: 'The service ‘newservice’ has been added to the solution',
|
123
|
+
tracking_id: '<UUID>',
|
124
|
+
service: 'newservice',
|
125
|
+
event: nil,
|
126
|
+
data: {
|
127
|
+
parameters: {},
|
128
|
+
code: 200,
|
129
|
+
},
|
130
|
+
}
|
131
|
+
end
|
132
|
+
|
133
|
+
def example_severity_build(severity)
|
134
|
+
{
|
135
|
+
type: 'config',
|
136
|
+
timestamp: 1_474_489_282_537,
|
137
|
+
severity: severity,
|
138
|
+
message: 'The service ‘newservice’ has been added to the solution',
|
139
|
+
tracking_id: '<UUID>',
|
140
|
+
service: 'websocket',
|
141
|
+
event: '/api/v1/foo/long/event/name',
|
142
|
+
data: {
|
143
|
+
parameters: {},
|
144
|
+
code: 200,
|
145
|
+
},
|
146
|
+
}
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
class LogsFaker
|
151
|
+
include LogsFakerModule
|
152
|
+
end
|
153
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Copyright © 2016-2017 Exosite LLC. All Rights Reserved
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# License: PROPRIETARY. See LICENSE.txt.
|
5
|
+
# Unauthorized copying of this file is strictly prohibited.
|
6
|
+
# vim:tw=0:ts=2:sw=2:et:ai
|
7
|
+
|
8
|
+
require 'eventmachine'
|
9
|
+
require 'websocket/driver'
|
10
|
+
|
11
|
+
module SimpleWebSocket
|
12
|
+
class SimpleConnection < EventMachine::Connection
|
13
|
+
def initialize
|
14
|
+
@driver = WebSocket::Driver.server(self)
|
15
|
+
|
16
|
+
@driver.on :connect, &method(:conn_on_open)
|
17
|
+
|
18
|
+
@driver.on :message, (lambda do |e|
|
19
|
+
@driver.text(e.data)
|
20
|
+
end)
|
21
|
+
|
22
|
+
@driver.on :close, (lambda do |_e|
|
23
|
+
close_connection_after_writing
|
24
|
+
end)
|
25
|
+
end
|
26
|
+
|
27
|
+
def receive_data(data)
|
28
|
+
@driver.parse(data)
|
29
|
+
end
|
30
|
+
|
31
|
+
def write(data)
|
32
|
+
send_data(data)
|
33
|
+
end
|
34
|
+
|
35
|
+
def conn_on_open(event)
|
36
|
+
if WebSocket::Driver.websocket?(@driver.env)
|
37
|
+
@driver.start
|
38
|
+
else
|
39
|
+
# Other HTTP requests.
|
40
|
+
warn "WARNING: unhandled request: #{event}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# Copyright © 2016-2017 Exosite LLC. All Rights Reserved
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# License: PROPRIETARY. See LICENSE.txt.
|
5
|
+
# Unauthorized copying of this file is strictly prohibited.
|
6
|
+
# vim:tw=0:ts=2:sw=2:et:ai
|
7
|
+
|
8
|
+
require 'optparse'
|
9
|
+
|
10
|
+
require_relative 'simple_server'
|
11
|
+
|
12
|
+
module SimpleWebSocket
|
13
|
+
class Options
|
14
|
+
def initialize
|
15
|
+
reset_opts
|
16
|
+
end
|
17
|
+
|
18
|
+
def reset_opts
|
19
|
+
@options = {
|
20
|
+
behave: '',
|
21
|
+
timeout: 0,
|
22
|
+
}
|
23
|
+
@options[:port] = SimpleWebSocket::Server::DEFAULT_WS_PORT
|
24
|
+
end
|
25
|
+
|
26
|
+
def setup_and_parse_opts
|
27
|
+
opt_parser = OptionParser.new do |parser|
|
28
|
+
parser.banner = "Usage: #{File.basename($PROGRAM_NAME)} [options]"
|
29
|
+
opt_setup_help(parser)
|
30
|
+
opt_setup_behavior(parser)
|
31
|
+
opt_setup_timeout(parser)
|
32
|
+
end
|
33
|
+
opt_parser.parse!
|
34
|
+
# The optparse library pulls values out of ARGV, so if we wanted to
|
35
|
+
# use positional parameters, we could inspect ARGV. But we don't.
|
36
|
+
@options
|
37
|
+
end
|
38
|
+
|
39
|
+
def opt_setup_help(parser)
|
40
|
+
parser.on('-h', '--help', 'Show this help message') do
|
41
|
+
puts parser
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def opt_setup_behavior(parser)
|
46
|
+
parser.on(
|
47
|
+
'-b',
|
48
|
+
'--behavior FLAVOR',
|
49
|
+
"[reserved] How to behave. We probably don't need this..."
|
50
|
+
) do |flavor|
|
51
|
+
@options[:behave] = flavor
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def opt_setup_port(parser)
|
56
|
+
def_port = SimpleWebSocket::Server::DEFAULT_WS_PORT
|
57
|
+
parser.on(
|
58
|
+
'-p',
|
59
|
+
'--port PORT',
|
60
|
+
"Port on which to run server. Default: #{def_port}"
|
61
|
+
) do |msecs|
|
62
|
+
@options[:timeout] = msecs.to_i / 1000.0
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def opt_setup_timeout(parser)
|
67
|
+
parser.on(
|
68
|
+
'-t',
|
69
|
+
'--timeout MSECS',
|
70
|
+
'How long to run before exiting. O to run forever.'
|
71
|
+
) do |msecs|
|
72
|
+
@options[:timeout] = msecs.to_i / 1000.0
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# Copyright © 2016-2017 Exosite LLC. All Rights Reserved
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# License: PROPRIETARY. See LICENSE.txt.
|
5
|
+
# Unauthorized copying of this file is strictly prohibited.
|
6
|
+
# vim:tw=0:ts=2:sw=2:et:ai
|
7
|
+
|
8
|
+
require 'eventmachine'
|
9
|
+
require 'faye/websocket'
|
10
|
+
require 'websocket/driver'
|
11
|
+
|
12
|
+
begin
|
13
|
+
# From RSpec.
|
14
|
+
require 'fixtures/websocket/simple_connection'
|
15
|
+
rescue LoadError
|
16
|
+
# From invocation.
|
17
|
+
require_relative 'simple_connection'
|
18
|
+
end
|
19
|
+
|
20
|
+
module SimpleWebSocket
|
21
|
+
class Server
|
22
|
+
DEFAULT_WS_PORT = 4180
|
23
|
+
|
24
|
+
attr_writer :connection
|
25
|
+
|
26
|
+
def initialize(options={}, connection=SimpleWebSocket::SimpleConnection)
|
27
|
+
@options = options
|
28
|
+
@connection = connection
|
29
|
+
end
|
30
|
+
|
31
|
+
def start_timer
|
32
|
+
return if !@options[:timeout] || @options[:timeout] <= 0
|
33
|
+
_timer = EventMachine::Timer.new(@options[:timeout]) do
|
34
|
+
EM.stop_event_loop
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def start_server
|
39
|
+
trap_interrupt
|
40
|
+
trap_termination
|
41
|
+
start_event_loop
|
42
|
+
end
|
43
|
+
|
44
|
+
def trap_interrupt
|
45
|
+
Signal.trap('INT') do
|
46
|
+
EM.stop_event_loop
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def trap_termination
|
51
|
+
Signal.trap('TERM') do
|
52
|
+
EM.stop_event_loop
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def start_event_loop
|
57
|
+
EM.run do
|
58
|
+
start_timer
|
59
|
+
EM.start_server(
|
60
|
+
'127.0.0.1',
|
61
|
+
@options[:port],
|
62
|
+
@connection
|
63
|
+
)
|
64
|
+
end
|
65
|
+
# EM event loop runs until we tell it to stop.
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Copyright © 2016-2017 Exosite LLC. All Rights Reserved
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
# License: PROPRIETARY. See LICENSE.txt.
|
6
|
+
# Unauthorized copying of this file is strictly prohibited.
|
7
|
+
# vim:tw=0:ts=2:sw=2:et:ai
|
8
|
+
|
9
|
+
require 'json'
|
10
|
+
|
11
|
+
require 'eventmachine'
|
12
|
+
|
13
|
+
require_relative 'simple_connection'
|
14
|
+
require_relative 'simple_options'
|
15
|
+
|
16
|
+
module EchoReceiver
|
17
|
+
def initialize(driver)
|
18
|
+
@driver = driver
|
19
|
+
end
|
20
|
+
|
21
|
+
def receive_data(data)
|
22
|
+
# If we don't encode correctly, websocket-driver barfs. E.g., if we
|
23
|
+
# tried to transmit "something with ‘curly quotes’", we'd get:
|
24
|
+
# `encode': "\xE2" from ASCII-8BIT to UTF-8 (Encoding::UndefinedConversionError)
|
25
|
+
msg = data.chomp.force_encoding('UTF-8')
|
26
|
+
puts "receive_data: #{msg}"
|
27
|
+
# (landonb): What does the parse method do? I don't think we care.
|
28
|
+
# @driver.parse(data)
|
29
|
+
EM.stop_event_loop if msg == 'EXIT'
|
30
|
+
@driver.text(msg)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class WSStdinPassthru < SimpleWebSocket::SimpleConnection
|
35
|
+
def conn_on_open(event)
|
36
|
+
super(event)
|
37
|
+
EM.attach $stdin, EchoReceiver, @driver
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def main
|
42
|
+
options = SimpleWebSocket::Options.new.setup_and_parse_opts
|
43
|
+
ws_svr = SimpleWebSocket::Server.new(options, WSStdinPassthru)
|
44
|
+
ws_svr.start_server
|
45
|
+
end
|
46
|
+
|
47
|
+
main
|
48
|
+
|