torquebox-console 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|