Admin Console

Disclaimer

This contribution relies on open-source packages. Their license restrictions apply.

USE AT YOUR OWN RISK.


Purpose

The Admin Console can be included in your ULC application to allow "ad hoc" access to your application for authorized personnel (admins). Admins may inspect any object of your live running application and call any method on that object. They may also spawn new threads, fork processes and access the operation system.

With these means, the admin can

  • debug the live system to pin down bugs
  • free blocked resources like file handles, db connections, etc. without server restart such that running user sessions are not affected
  • explore the effect of different configurations on a test server installation
  • act as if he was a piece of code on the server
all this without any connection to the server other than through application in use.

How to use

How to include the admin console in your application

The admin console only needs to be deployed on the server side. The client side (UIEngine) remains untouched.

The admin console comes as a ULCBoxPane named ConsoleBoxPane. For testing purposes, this pane is shown inside a ULCFrame. In your application you can add the ConsoleBoxPane wherever appropriate, e.g. to a dialog window.

The responsibility of ensuring that only authorized personnel can access the ConsoleBoxPane is left to the application. It may already support authentication/authorization that can be reused for this purpose or may rely on a "magic" shortcut to show the dialog. The latter is strongly discouraged for production strength applications.

How to handle the console

The console shows up like this: AdminConsole

In this example the admin was interested in the ULC Version (build number) that this application uses on the server side, possibly spotting a wrong server setup.

You insert a command in the Command Field, click Execute (or use Tab-Space, or Alt+E) and the result of evaluating your command is shown in the Result TextArea.

Your result is always an object. To see the methods of that object or its declared fields, just use the corresponding buttons.

Use the "Grash" button if your Command should be interpreted as a grash command.

The drop-down list collects a history of your commands (without duplicates). Initially it contains a few command examples that you may want to try.

In the Command Field you can enter:

  • Groovy expressions to be evaluated by the "Execute" button (for further reference see Groovy). As Groovy expressions are a superset of Java expressions, you can always write the expression as Java code when in doubt. Groovy syntax is just more convenient.
  • grash expressions to be evaluated by the "Grash" button (for further reference see Grash)
A special variable called "oui" (=Object Under Inspection) is at your hand, initially referencing the ConsoleBoxPane object.

Variables are relayed from one command invocation to the next, but any other state is not. Multiple commands can be concatenated with the ';' character.

Here is a transcript of a sample session with the Admin Console:

Command:oui <Execute>
Result :com.canoo.ulc.admin.console.ConsoleBoxPane@191f801

Command:oui <Methods> Result :[add, add, add, add, addFocusListener, addKeyListener, equals, getActionForKeyStroke, getAlignmentOf, getBackground, getClass, getClientProperty, getColumnOf, getColumns, getComponent, getComponentCount, getComponents, getConditionForKeyStroke, getCursor, getEnabler, getFont, getForeground, <...and much more ...>]

Command:oui <Show Declared Fields> Result :[COMMON_IMPORTS, binding, buttonLine, commandCombo, commandLabel, fieldsButton, goButton, methodsButton, objectUnderInspection, resultArea, resultLabel, ulcButton]

Command:ls <Grash> Result : access$0 access$1 access$2 access$3 binding buttonLine commandCombo commandLabel executeCommand fieldsButton goButton initialize methodsButton objectUnderInspection resultArea resultLabel ulcButton

Command:oui.goButton.text <Execute> Result :Execute

Command:oui.resultLabel.visible=false <Execute> Result :<"Result" label disappears from screen>

Command:oui.commandLabel.foreground=Color.blue <Execute> Result :<"Command" label changes color to blue>

Command:x='';'cmd /c dir'.execute().in.eachLine{x+=it+"n"};x <Execute> Result : Volume in drive C has no label. Volume Serial Number is 30D3-AD87

Directory of C:/eclipse/workspace/AdminConsole

03.12.04 15:10 <DIR> . 03.12.04 15:10 <DIR> .. 09.12.04 16:02 815 .classpath 03.12.04 15:14 575 .project 03.12.04 15:10 104 .ulcproperties 03.12.04 15:10 <DIR> application 09.12.04 16:02 <DIR> bin 03.12.04 15:10 <DIR> launcher 03.12.04 15:10 <DIR> resources 08.12.04 08:42 <DIR> test 3 File(s) 1'494 bytes 7 Dir(s) 39'137'243'136 bytes free

Security considerations

From the above you can guess that any user of this console can do a lot of harm to your server. So, be very careful with your authorization.

Security concerns are the reason we do not provide a live experience of this contribution like we do for most of the other ones.

Your ULC application that includes the admin console should be run under a user account that has very restricted access rights on the server machine. If your ULC Container (e.g. your ServletContainer) allows, you may also want to impose further access restrictions through the Java SecurityManager.

Resources

  • Source code - AdminConsole.zip.
  • Add Grash to your classpath which comes with a free open-source license.