torquebox-console 0.1.2
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.
- data/Gemfile +10 -0
- data/LICENSE +13 -0
- data/README.md +18 -0
- data/Rakefile +29 -0
- data/TODO +12 -0
- data/bin/tbconsole +95 -0
- data/config/torquebox.rb +16 -0
- data/config.ru +5 -0
- data/console.rb +6 -0
- data/lib/torquebox/console/builtin.rb +44 -0
- data/lib/torquebox/console/client.rb +54 -0
- data/lib/torquebox/console/server.rb +68 -0
- data/lib/torquebox/console/version.rb +5 -0
- data/lib/torquebox-console.rb +16 -0
- data/public/ansispan.js +59 -0
- data/public/console.css +80 -0
- data/public/console.js +47 -0
- data/stomplets/torque_box_console.rb +62 -0
- data/views/index.haml +28 -0
- metadata +142 -0
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright 2012 Lance Ball
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# A Pry-based Console for TorqueBox
|
2
|
+
|
3
|
+
TorqueBox::Console allows you to connect to a ruby runtime running inside of
|
4
|
+
the TorqueBox server, giving you a Pry interface to work with.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
gem install torquebox-console
|
9
|
+
|
10
|
+
## Usage
|
11
|
+
|
12
|
+
First deploy to a TorqueBox server.
|
13
|
+
|
14
|
+
tbconsole deploy --dir=/some/path
|
15
|
+
|
16
|
+
Then you can connect with a web browser at
|
17
|
+
`http://<servername>:<portnumber>/console`, or on the command line with
|
18
|
+
`tbconsole connect`.
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require './lib/torquebox/console/version'
|
5
|
+
|
6
|
+
GEMFILE = "torquebox-console-#{TorqueBox::Console::VERSION}.gem"
|
7
|
+
|
8
|
+
task :default => :build
|
9
|
+
|
10
|
+
desc "Build the gem"
|
11
|
+
task :build do
|
12
|
+
system "gem build torquebox-console.gemspec"
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Release the gem to rubygems"
|
16
|
+
task :release => [ :build, :tag ] do
|
17
|
+
system "gem push #{GEMFILE}"
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "Build and install the gem locally"
|
21
|
+
task :install => :build do
|
22
|
+
system "gem install -l -f #{GEMFILE}"
|
23
|
+
end
|
24
|
+
|
25
|
+
task :tag do
|
26
|
+
system "git tag #{TorqueBox::Console::VERSION}"
|
27
|
+
end
|
28
|
+
|
29
|
+
|
data/TODO
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
* Destroy queues on disconnect
|
2
|
+
* Figure out how to attach to other runtimes
|
3
|
+
* multi-line input
|
4
|
+
* Add auth if necessasry
|
5
|
+
* Implement additional helper methods in Builtin, e.g. clear_cache
|
6
|
+
|
7
|
+
* [done] Document usage
|
8
|
+
* [done] Package/publish gem
|
9
|
+
* [done] Implement command line client
|
10
|
+
* [done] Make web UI auto scroll
|
11
|
+
* [done] Ensure the client unsubscribes
|
12
|
+
* [done] escape angle brackets in the html
|
data/bin/tbconsole
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
#!/usr/bin/env jruby
|
2
|
+
|
3
|
+
# Copyright 2012 Lance Ball
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
$: << File.join(File.dirname(__FILE__), '..', 'lib')
|
18
|
+
|
19
|
+
require 'thor'
|
20
|
+
require 'fileutils'
|
21
|
+
require 'torquebox-rake-support'
|
22
|
+
require 'torquebox/console/client'
|
23
|
+
|
24
|
+
class TorqueBoxConsoleCommand < Thor
|
25
|
+
|
26
|
+
DEPLOYMENT_NAME = 'torquebox-console-knob.yml'
|
27
|
+
|
28
|
+
desc "deploy --dir=<deploy_dir> [--secure=username:password[,username:password]*]",
|
29
|
+
<<-EOT
|
30
|
+
Writes the torquebox-console application to disk in the directory specified by
|
31
|
+
--dir, and deploys the app to the TorqueBox instance specified by ENV['TORQUEBOX_HOME']
|
32
|
+
(currently #{ENV['TORQUEBOX_HOME']}).
|
33
|
+
|
34
|
+
If --dir is not provided, the torquebox-console app will be written to Dir.pwd/torquebox-console
|
35
|
+
(currently #{Dir.pwd}/torquebox-console).
|
36
|
+
|
37
|
+
EOT
|
38
|
+
method_option :secure, :type => :hash, :default => nil
|
39
|
+
method_option :dir, :type => :string, :default => "#{Dir.pwd}/torquebox-console"
|
40
|
+
def deploy
|
41
|
+
check
|
42
|
+
deploy_dir = File.expand_path options[:dir]
|
43
|
+
descriptor = TorqueBox::DeployUtils.basic_deployment_descriptor( :root => deploy_dir,
|
44
|
+
:env => 'production' )
|
45
|
+
if options[:secure]
|
46
|
+
descriptor['environment']['REQUIRE_AUTHENTICATION'] = true
|
47
|
+
descriptor['auth'] = {'console' => {'domain'=>'torquebox-torquebox-console', 'credentials'=>{}}}
|
48
|
+
options[:secure].each do |user, pass|
|
49
|
+
descriptor['auth']['console']['credentials'][user] = pass
|
50
|
+
end
|
51
|
+
puts ">> Wrote user/password entries to TorqueBox::Console deployment descriptor"
|
52
|
+
else
|
53
|
+
puts ">> WARNING: deploying TorqueBox::Console with no security - use the --secure=username:password option to secure it"
|
54
|
+
end
|
55
|
+
|
56
|
+
unless File.exist?( deploy_dir )
|
57
|
+
puts ">> Creating torquebox-console app directory #{deploy_dir}."
|
58
|
+
Dir.mkdir( deploy_dir )
|
59
|
+
end
|
60
|
+
puts "Copying torquebox-console app to #{deploy_dir}"
|
61
|
+
files = Dir.glob("#{root_dir}/*") - ["#{root_dir}/bin"]
|
62
|
+
FileUtils.cp_r( files, "#{deploy_dir}/", :verbose=>true )
|
63
|
+
name, dir = TorqueBox::DeployUtils.deploy_yaml( descriptor, :name => DEPLOYMENT_NAME )
|
64
|
+
puts ">> Deployed #{deploy_dir} as #{name} to #{dir}/#{name}"
|
65
|
+
end
|
66
|
+
|
67
|
+
desc "undeploy", "Undeploys TorqueBox::Console from the TorqueBox instance specified by $TORQUEBOX_HOME"
|
68
|
+
def undeploy
|
69
|
+
check
|
70
|
+
name, dir = TorqueBox::DeployUtils.undeploy_yaml( :name => DEPLOYMENT_NAME )
|
71
|
+
|
72
|
+
puts ">> Undeployed #{name} from #{dir}" if name
|
73
|
+
end
|
74
|
+
|
75
|
+
desc "connect", "Runs the CLI console"
|
76
|
+
def connect
|
77
|
+
TorqueBox::Console::Client.connect
|
78
|
+
end
|
79
|
+
|
80
|
+
protected
|
81
|
+
def check
|
82
|
+
raise Exception.new("$TORQUEBOX_HOME must be set") unless ENV['TORQUEBOX_HOME']
|
83
|
+
end
|
84
|
+
|
85
|
+
def root_dir
|
86
|
+
_root_dir_ = File.expand_path( File.join( File.dirname( __FILE__ ), '..' ) )
|
87
|
+
if _root_dir_ =~/\.rvm/
|
88
|
+
$stderr.puts "It looks like you're using RVM for your JRuby."
|
89
|
+
$stderr.puts "TorqueBox has some trouble with load paths with an '@'."
|
90
|
+
end
|
91
|
+
_root_dir_
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
TorqueBoxConsoleCommand.start(ARGV)
|
data/config/torquebox.rb
ADDED
data/config.ru
ADDED
data/console.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# Copyright 2012 Lance Ball
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'torquebox'
|
16
|
+
|
17
|
+
module TorqueBox
|
18
|
+
module Console
|
19
|
+
module Builtin
|
20
|
+
extend TorqueBox::Injectors
|
21
|
+
class << self
|
22
|
+
def service_registry
|
23
|
+
@@service_registry ||= inject("service-registry")
|
24
|
+
end
|
25
|
+
|
26
|
+
def list_runtimes
|
27
|
+
get_runtimes.each do |runtime|
|
28
|
+
puts "Application: #{runtime[0]}"
|
29
|
+
puts "Pool: #{runtime[1]}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def get_runtimes
|
34
|
+
service_registry.service_names.to_a.map { |x| parse_pool_name(x) }.reject(&:nil?)
|
35
|
+
end
|
36
|
+
|
37
|
+
def parse_pool_name(service_name)
|
38
|
+
[$1, $3, service_name] if service_name.canonical_name =~
|
39
|
+
/"(.*)(-knob\.yml|\.knob)"\.torquebox\.core\.runtime\.pool\.([^.]+)$/
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Copyright 2012 Lance Ball
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'stomp'
|
16
|
+
require 'readline'
|
17
|
+
|
18
|
+
module TorqueBox
|
19
|
+
module Console
|
20
|
+
class Client
|
21
|
+
HEADERS = { "accept-version" => "1.1", "host" => "localhost" }
|
22
|
+
HOSTS = [{:host => "localhost", :port => 8675}]
|
23
|
+
PARAMS = { :connect_headers => HEADERS, :hosts => HOSTS, :max_reconnect_attempts => -1 }
|
24
|
+
|
25
|
+
attr_accessor :client
|
26
|
+
|
27
|
+
def initialize
|
28
|
+
@client = Stomp::Client.new( PARAMS )
|
29
|
+
rescue Stomp::Error::MaxReconnectAttempts
|
30
|
+
puts "Can't connect to TorqueBox. Are you sure the server is running?"
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.connect
|
34
|
+
Client.new.run
|
35
|
+
end
|
36
|
+
|
37
|
+
def run
|
38
|
+
if client
|
39
|
+
client.subscribe("/stomplet/console") do |msg|
|
40
|
+
!msg.headers['prompt'] && puts(msg.body)
|
41
|
+
end
|
42
|
+
# Since our messaging is async, sleep
|
43
|
+
# before displaying the prompt
|
44
|
+
sleep 0.3
|
45
|
+
while(input = Readline.readline( "TorqueBox> ", true ))
|
46
|
+
client.publish("/stomplet/console", input)
|
47
|
+
sleep 0.3 # again with the async
|
48
|
+
end
|
49
|
+
client.unsubscribe('/stomplet/console')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# Copyright 2012 Lance Ball
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'pry'
|
16
|
+
require 'torquebox-stomp'
|
17
|
+
require 'torquebox-cache'
|
18
|
+
require 'torquebox-messaging'
|
19
|
+
|
20
|
+
module TorqueBox
|
21
|
+
module Console
|
22
|
+
class Server
|
23
|
+
|
24
|
+
attr_accessor :input_queue, :output_queue, :console_id
|
25
|
+
|
26
|
+
def initialize
|
27
|
+
@cache = TorqueBox::Infinispan::Cache.new(:name=>"torquebox-console")
|
28
|
+
@console_id = @cache.increment( "console" )
|
29
|
+
|
30
|
+
input_name = "/queues/torquebox-console/#{console_id}-input"
|
31
|
+
output_name = "/queues/torquebox-console/#{console_id}-output"
|
32
|
+
|
33
|
+
@input_queue = TorqueBox::Messaging::Queue.start( input_name, :durable => false )
|
34
|
+
@output_queue = TorqueBox::Messaging::Queue.start( output_name, :durable => false )
|
35
|
+
end
|
36
|
+
|
37
|
+
def run( entry_point )
|
38
|
+
Thread.new do
|
39
|
+
Pry.config.pager = false
|
40
|
+
#Pry.config.color = false
|
41
|
+
Pry.config.prompt = proc { "TorqueBox> " }
|
42
|
+
Pry.start entry_point, :input => self, :output => self
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Pry input channel
|
47
|
+
def readline( prompt )
|
48
|
+
# First send the repl prompt to the client
|
49
|
+
output_queue.publish prompt, {:properties => {'prompt' => 'true'}}
|
50
|
+
# Then wait for input
|
51
|
+
input_queue.receive
|
52
|
+
end
|
53
|
+
|
54
|
+
# Pry output channel
|
55
|
+
def puts( output = "" )
|
56
|
+
output_queue.publish output.to_s
|
57
|
+
end
|
58
|
+
|
59
|
+
# Pry (undocumented?) requires this
|
60
|
+
def tty?
|
61
|
+
false
|
62
|
+
end
|
63
|
+
|
64
|
+
end # TorqueBox::Console::Server
|
65
|
+
end # TorqueBox::Console
|
66
|
+
end # TorqueBox
|
67
|
+
|
68
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# Copyright 2012 Lance Ball
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'torquebox/console/server'
|
16
|
+
require 'torquebox/console/builtin'
|
data/public/ansispan.js
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
var ansispan = function (str) {
|
2
|
+
Object.keys(ansispan.foregroundColors).forEach(function (ansi) {
|
3
|
+
|
4
|
+
//
|
5
|
+
// `\033[Xm` == `\033[0;Xm` sets foreground color to `X`.
|
6
|
+
//
|
7
|
+
str = str.replace(
|
8
|
+
new RegExp('\033\\[' + ansi + 'm', 'g'),
|
9
|
+
'<span style="color: ' + ansispan.foregroundColors[ansi] + '">'
|
10
|
+
).replace(
|
11
|
+
new RegExp('\033\\[0;' + ansi + 'm', 'g'),
|
12
|
+
'<span style="color: ' + ansispan.foregroundColors[ansi] + '">'
|
13
|
+
).replace(
|
14
|
+
new RegExp('\033\\[1;' + ansi + 'm', 'g'),
|
15
|
+
'<span style="color: ' + ansispan.brightForegroundColors[ansi] + '">'
|
16
|
+
);
|
17
|
+
});
|
18
|
+
//
|
19
|
+
// `\033[1m` enables bold font, `\033[22m` disables it or \033[0m` resets
|
20
|
+
//
|
21
|
+
str = str.replace(/\033\[1m/g, '<b>').replace(/\033\[22m/g, '</b>');
|
22
|
+
str = str.replace(/\033\[1m/g, '<b>').replace(/\033\[0m/g, '</b>');
|
23
|
+
|
24
|
+
//
|
25
|
+
// `\033[3m` enables italics font, `\033[23m` disables it or \033[0m resets
|
26
|
+
//
|
27
|
+
str = str.replace(/\033\[3m/g, '<i>').replace(/\033\[23m/g, '</i>');
|
28
|
+
str = str.replace(/\033\[3m/g, '<i>').replace(/\033\[0m/g, '</i>');
|
29
|
+
|
30
|
+
str = str.replace(/\033\[m/g, '</span>');
|
31
|
+
return str.replace(/\033\[39m/g, '</span>');
|
32
|
+
};
|
33
|
+
|
34
|
+
ansispan.foregroundColors = {
|
35
|
+
'30': 'black',
|
36
|
+
'31': 'red',
|
37
|
+
'32': 'green',
|
38
|
+
'33': 'yellow',
|
39
|
+
'34': '#00bbbb',
|
40
|
+
'35': 'purple',
|
41
|
+
'36': 'cyan',
|
42
|
+
'37': 'white'
|
43
|
+
};
|
44
|
+
|
45
|
+
ansispan.brightForegroundColors = {
|
46
|
+
'30': 'black',
|
47
|
+
'31': 'red',
|
48
|
+
'32': 'green',
|
49
|
+
'33': 'yellow',
|
50
|
+
'34': '#00bbbb',
|
51
|
+
'35': 'purple',
|
52
|
+
'36': 'cyan',
|
53
|
+
'37': 'white'
|
54
|
+
};
|
55
|
+
|
56
|
+
if (typeof module == "object" && typeof window == "undefined") {
|
57
|
+
module.exports = ansispan;
|
58
|
+
}
|
59
|
+
|
data/public/console.css
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
body {
|
2
|
+
font-family: 'Source Code Pro', 'Inconsolata', 'Courier' monospace;
|
3
|
+
margin: 20px;
|
4
|
+
padding: 10px;
|
5
|
+
font-size: 14px;
|
6
|
+
line-height: 140%;
|
7
|
+
}
|
8
|
+
|
9
|
+
body.dark {
|
10
|
+
background-color: #2E2E2E;
|
11
|
+
color: #eee;
|
12
|
+
}
|
13
|
+
|
14
|
+
body.dark #console input {
|
15
|
+
background-color: #2E2E2E;
|
16
|
+
color: #fff;
|
17
|
+
}
|
18
|
+
|
19
|
+
body.light {
|
20
|
+
color: #2E2E2E;
|
21
|
+
background-color: #fff;
|
22
|
+
}
|
23
|
+
|
24
|
+
body.light #console input {
|
25
|
+
color: #2E2E2E;
|
26
|
+
background-color: #fff;
|
27
|
+
}
|
28
|
+
|
29
|
+
pre code {
|
30
|
+
white-space: pre-wrap; /* css-3 should we be so lucky... */
|
31
|
+
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
|
32
|
+
white-space: -pre-wrap; /* Opera 4-6 ?? */
|
33
|
+
white-space: -o-pre-wrap; /* Opera 7 ?? */
|
34
|
+
font-family: 'Source Code Pro', 'Inconsolata', 'Courier' monospace;
|
35
|
+
}
|
36
|
+
|
37
|
+
form {
|
38
|
+
margin: 0;
|
39
|
+
padding: 0;
|
40
|
+
}
|
41
|
+
|
42
|
+
h1 {
|
43
|
+
display: inline-block;
|
44
|
+
margin: 0;
|
45
|
+
}
|
46
|
+
|
47
|
+
input {
|
48
|
+
padding: 6px;
|
49
|
+
border: none;
|
50
|
+
width: 87%;
|
51
|
+
height: 5%;
|
52
|
+
margin: 0 0 20px 0;
|
53
|
+
font-family: 'Source Code Pro', 'Inconsolata', 'Courier' monospace;
|
54
|
+
font-size: 14px; }
|
55
|
+
|
56
|
+
#controls {
|
57
|
+
margin: 20px 0;
|
58
|
+
}
|
59
|
+
|
60
|
+
#controls .button {
|
61
|
+
width: 100px;
|
62
|
+
text-align: center;
|
63
|
+
display: inline-block;
|
64
|
+
padding: 4px;
|
65
|
+
margin-right: 10px;
|
66
|
+
border: 1px solid;
|
67
|
+
cursor: pointer;
|
68
|
+
}
|
69
|
+
|
70
|
+
#console {
|
71
|
+
border: 1px solid #585858;
|
72
|
+
padding: 10px;
|
73
|
+
overflow-x: auto;
|
74
|
+
height: auto; }
|
75
|
+
|
76
|
+
#console .prompt {
|
77
|
+
display: inline;
|
78
|
+
font-weight: bold;
|
79
|
+
}
|
80
|
+
|
data/public/console.js
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
$().ready( function() {
|
2
|
+
client = Stomp.client( "ws://localhost:8675" )
|
3
|
+
|
4
|
+
var display_message = function( message ) {
|
5
|
+
elem = $("#console .content")
|
6
|
+
line = message.body
|
7
|
+
line = line.replace("<", "<")
|
8
|
+
line = line.replace(">", ">")
|
9
|
+
if (message.headers['prompt']) {
|
10
|
+
$("#console .prompt").html( line )
|
11
|
+
} else {
|
12
|
+
elem.append( ansispan(line) + "\n" )
|
13
|
+
/*elem.append( line + "\n" )*/
|
14
|
+
}
|
15
|
+
$(window).scrollTop($("body").height())
|
16
|
+
$("#console input").focus();
|
17
|
+
}
|
18
|
+
|
19
|
+
var send_message = function( message ) {
|
20
|
+
var input = $("#console input").attr( "value" ) + "\n"
|
21
|
+
$("#console .content").append( $("#console .prompt").text() )
|
22
|
+
$("#console .content").append( input )
|
23
|
+
$("#console input").attr( "value", "" )
|
24
|
+
client.send( "/stomplet/console", {}, input )
|
25
|
+
return false;
|
26
|
+
}
|
27
|
+
|
28
|
+
var toggle_theme = function() {
|
29
|
+
if ($("body").hasClass("light")) {
|
30
|
+
$("body").removeClass("light");
|
31
|
+
$("body").addClass("dark");
|
32
|
+
} else {
|
33
|
+
$("body").addClass("light");
|
34
|
+
$("body").removeClass("dark");
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
$(window).unload( function() { client.disconnect() });
|
39
|
+
|
40
|
+
$( '#input-form' ).bind( "submit", send_message );
|
41
|
+
$( '.button' ).bind( "click", toggle_theme );
|
42
|
+
|
43
|
+
client.connect( null, null, function() {
|
44
|
+
client.subscribe("/stomplet/console", display_message)
|
45
|
+
} );
|
46
|
+
} )
|
47
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Copyright 2012 Lance Ball
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require 'torquebox-stomp'
|
16
|
+
require 'torquebox-console'
|
17
|
+
|
18
|
+
class TorqueBoxConsole < TorqueBox::Stomp::JmsStomplet
|
19
|
+
|
20
|
+
def configure( options )
|
21
|
+
super
|
22
|
+
@servers = {}
|
23
|
+
end
|
24
|
+
|
25
|
+
def on_message( message, session )
|
26
|
+
server = @servers[session["console_id"]]
|
27
|
+
if server
|
28
|
+
send_to( server.input_queue, message.content_as_string )
|
29
|
+
else
|
30
|
+
logger.error("No console found for the server #{server}")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def on_subscribe( subscriber )
|
35
|
+
# Create a new server that sends/receives on the queue
|
36
|
+
server = TorqueBox::Console::Server.new
|
37
|
+
|
38
|
+
# Keep a reference to it around for a while
|
39
|
+
console_id = server.console_id
|
40
|
+
@servers[console_id] = server
|
41
|
+
|
42
|
+
# Make sure we can find the server using session
|
43
|
+
subscriber.session["console_id"] = console_id
|
44
|
+
logger.info "Running TorqueBox console #{console_id}."
|
45
|
+
|
46
|
+
# Subscribe our stomplet connection to the server's queue
|
47
|
+
subscribe_to( subscriber, server.output_queue )
|
48
|
+
server.run( TorqueBox::Console::Builtin )
|
49
|
+
end
|
50
|
+
|
51
|
+
def on_unsubscribe( subscriber )
|
52
|
+
session = subscriber.session
|
53
|
+
logger.info "Closing TorqueBox console #{session["console_id"]}"
|
54
|
+
@servers.delete( session["console_id"] )
|
55
|
+
end
|
56
|
+
|
57
|
+
def logger
|
58
|
+
@logger ||= TorqueBox::Logger.new( self )
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
data/views/index.haml
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
!!!
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%script{ :type => "text/javascript",
|
5
|
+
:src => "https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js" }
|
6
|
+
%script{ :type => "text/javascript",
|
7
|
+
:src => "stilts-stomp.js" }
|
8
|
+
%script{ :type => "text/javascript",
|
9
|
+
:src => "ansispan.js" }
|
10
|
+
%script{ :type => "text/javascript",
|
11
|
+
:src => "console.js" }
|
12
|
+
%link{ :rel => "stylesheet",
|
13
|
+
:href => "console.css",
|
14
|
+
:type => "text/css",
|
15
|
+
:media => "screen" }
|
16
|
+
%body.light
|
17
|
+
#controls
|
18
|
+
%span.button Light/Dark
|
19
|
+
%h1 TorqueBox::Console
|
20
|
+
%form#input-form
|
21
|
+
#console
|
22
|
+
%pre
|
23
|
+
%code
|
24
|
+
.content
|
25
|
+
.prompt
|
26
|
+
%input{:type=>:text, :value=>""}
|
27
|
+
#welcome{:style=>"text-align: right"}
|
28
|
+
Type any ruby statement or pry command.
|
metadata
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: torquebox-console
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.2
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Lance Ball
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2012-10-15 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: pry
|
17
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ~>
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.9.10
|
23
|
+
requirement: *id001
|
24
|
+
prerelease: false
|
25
|
+
type: :runtime
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: torquebox
|
28
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "2.0"
|
34
|
+
requirement: *id002
|
35
|
+
prerelease: false
|
36
|
+
type: :runtime
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: sinatra
|
39
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 1.3.3
|
45
|
+
requirement: *id003
|
46
|
+
prerelease: false
|
47
|
+
type: :runtime
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: haml
|
50
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 3.1.7
|
56
|
+
requirement: *id004
|
57
|
+
prerelease: false
|
58
|
+
type: :runtime
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: thor
|
61
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ~>
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 0.14.6
|
67
|
+
requirement: *id005
|
68
|
+
prerelease: false
|
69
|
+
type: :runtime
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: stomp
|
72
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.2.6
|
78
|
+
requirement: *id006
|
79
|
+
prerelease: false
|
80
|
+
type: :runtime
|
81
|
+
description: TorqueBox Console allows you to peer into the TorqueBox guts using a repl command line. You can view information about the components and applications you have running.
|
82
|
+
email: lball@redhat.com
|
83
|
+
executables:
|
84
|
+
- tbconsole
|
85
|
+
extensions:
|
86
|
+
- Rakefile
|
87
|
+
extra_rdoc_files:
|
88
|
+
- README.md
|
89
|
+
- LICENSE
|
90
|
+
- TODO
|
91
|
+
files:
|
92
|
+
- Gemfile
|
93
|
+
- LICENSE
|
94
|
+
- Rakefile
|
95
|
+
- README.md
|
96
|
+
- TODO
|
97
|
+
- config/torquebox.rb
|
98
|
+
- lib/torquebox-console.rb
|
99
|
+
- lib/torquebox/console/builtin.rb
|
100
|
+
- lib/torquebox/console/client.rb
|
101
|
+
- lib/torquebox/console/server.rb
|
102
|
+
- lib/torquebox/console/version.rb
|
103
|
+
- views/index.haml
|
104
|
+
- stomplets/torque_box_console.rb
|
105
|
+
- public/ansispan.js
|
106
|
+
- public/console.css
|
107
|
+
- public/console.js
|
108
|
+
- bin/tbconsole
|
109
|
+
- config.ru
|
110
|
+
- console.rb
|
111
|
+
homepage: http://github.com/torquebox/torquebox-console
|
112
|
+
licenses:
|
113
|
+
- AL
|
114
|
+
post_install_message:
|
115
|
+
rdoc_options: []
|
116
|
+
|
117
|
+
require_paths:
|
118
|
+
- lib
|
119
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
+
none: false
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
hash: 2
|
125
|
+
segments:
|
126
|
+
- 0
|
127
|
+
version: "0"
|
128
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: "0"
|
134
|
+
requirements: []
|
135
|
+
|
136
|
+
rubyforge_project:
|
137
|
+
rubygems_version: 1.8.24
|
138
|
+
signing_key:
|
139
|
+
specification_version: 3
|
140
|
+
summary: TorqueBox Console - A REPL commandline and information viewer for TorqueBox
|
141
|
+
test_files: []
|
142
|
+
|