2
* This program is free software; you can redistribute it and/or modify
3
* it under the terms of the GNU General Public License as published by
4
* the Free Software Foundation; either version 2 of the License, or
5
* (at your option) any later version.
6
* This program is distributed in the hope that it will be useful,
7
* but WITHOUT ANY WARRANTY; without even the implied warranty of
8
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9
* GNU General Public License for more details.
10
* You should have received a copy of the GNU General Public License
11
* along with this program; if not, write to the Free Software
12
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
package games.strategy.engine.lobby.server.headless;
17
import games.strategy.debug.Console;
18
import games.strategy.engine.lobby.server.LobbyServer;
19
import games.strategy.engine.lobby.server.ui.DBExplorerPanel;
20
import games.strategy.engine.lobby.server.userDB.Database;
21
import games.strategy.net.IConnectionChangeListener;
22
import games.strategy.net.INode;
24
import java.io.BufferedReader;
25
import java.io.IOException;
26
import java.io.InputStream;
27
import java.io.InputStreamReader;
28
import java.io.PrintStream;
29
import java.sql.Connection;
30
import java.sql.ResultSet;
31
import java.sql.SQLException;
32
import java.sql.Statement;
33
import java.util.Date;
34
import java.util.Formatter;
35
import java.util.concurrent.atomic.AtomicInteger;
38
* Headless admin console for the lobby.
40
* Reads commands from stdin, and writes responses to stdout.
42
* @author Sean Bridges
46
public class HeadlessLobbyConsole
48
private final LobbyServer server;
49
private final PrintStream out;
50
private final BufferedReader in;
52
@SuppressWarnings("deprecation")
53
private final String startDate = new Date().toGMTString();
54
private final AtomicInteger totalLogins = new AtomicInteger();
55
private final AtomicInteger currentConnections = new AtomicInteger();
56
private volatile int maxConcurrentLogins = 0;
59
public HeadlessLobbyConsole(LobbyServer server, InputStream in, PrintStream out)
62
this.in = new BufferedReader(new InputStreamReader(in));
65
server.getMessenger().addConnectionChangeListener(new IConnectionChangeListener()
68
public void connectionAdded(INode to)
70
currentConnections.incrementAndGet();
71
totalLogins.incrementAndGet();
73
//not strictly thread safe, but good enough
74
maxConcurrentLogins = Math.max(maxConcurrentLogins, currentConnections.get());
77
public void connectionRemoved(INode to)
79
currentConnections.decrementAndGet();
87
Thread t = new Thread(new Runnable()
96
}, "Headless console eval print loop");
100
private void printEvalLoop()
110
String command = in.readLine();
111
process(command.trim());
116
t.printStackTrace(out);
124
private void process(String command)
126
if(command.equals("")) {
129
final String noun = command.split("\\s")[0];
130
if(noun.equals("help")) {
132
} else if(noun.equals("status")) {
134
} else if(noun.equals("sql")) {
135
executeSql(command.substring("sql".length(), command.length()).trim());
136
} else if(noun.equals("quit")) {
138
} else if(noun.equals("backup")) {
140
} else if(noun.equals("memory")) {
142
} else if(noun.equals("threads")) {
146
out.println("unrecognized command:" + command);
153
private void threads()
155
out.println(Console.getThreadDumps());
159
private void memory()
161
out.println(Console.getMemory());
164
private void backup()
171
out.println("Are you sure? (y/n)");
174
if(in.readLine().toLowerCase().startsWith("y")) {
177
} catch (IOException e)
183
private void executeSql(String sql)
185
Connection con = Database.getConnection();
189
Statement ps = con.createStatement();
191
if(DBExplorerPanel.isNotQuery(sql ))
193
int rs = ps.executeUpdate(sql);
194
out.println("Update count:" + rs);
198
ResultSet rs = ps.executeQuery(sql);
204
catch(SQLException sqle)
206
sqle.printStackTrace();
207
out.println(sqle.getMessage());
214
} catch (SQLException e)
216
// TODO Auto-generated catch block
222
private void print(ResultSet rs)
226
Formatter f = new Formatter(out);
227
String itemFormat = "%20s ";
228
f.format(itemFormat, "Count");
230
int count = rs.getMetaData().getColumnCount();
232
for(int i =1; i <= count; i++)
234
String columnName = rs.getMetaData().getColumnName(i);
235
f.format(itemFormat, columnName);
239
for(int i =0; i < count; i++) {
240
f.format(itemFormat, "-----------");
247
f.format(itemFormat, row++);
248
for(int i =1; i <= count; i++)
250
f.format(itemFormat, rs.getString(i));
255
} catch(SQLException e) {
256
e.printStackTrace(out);
260
private void showStatus()
263
int port = server.getMessenger().getServerNode().getPort();
269
"total logins:%s\n" +
270
"current connections:%s\n" +
271
"max concurrent connections:%s\n",
275
currentConnections.get(),
282
private void showHelp()
284
out.println("available commands:\n" +
285
" backup - backup the database \n" +
286
" help - show this message\n" +
287
" memory - show memory usage\n" +
288
" status - show status information\n" +
289
" sql {sql} - execute a sql command and print the results\n" +
290
" threads - get thread dumps\n" +