1 22 package org.jboss.console.twiddle; 23 24 import gnu.getopt.Getopt; 25 import gnu.getopt.LongOpt; 26 27 import java.io.File ; 28 import java.io.InputStream ; 29 import java.io.PrintWriter ; 30 import java.net.MalformedURLException ; 31 import java.net.URL ; 32 import java.util.ArrayList ; 33 import java.util.HashMap ; 34 import java.util.Iterator ; 35 import java.util.List ; 36 import java.util.Map ; 37 import java.util.Properties ; 38 39 import javax.management.MBeanServerConnection ; 40 import javax.naming.Context ; 41 import javax.naming.InitialContext ; 42 import javax.naming.NamingException ; 43 44 import org.jboss.console.twiddle.command.Command; 45 import org.jboss.console.twiddle.command.CommandContext; 46 import org.jboss.console.twiddle.command.CommandException; 47 import org.jboss.console.twiddle.command.NoSuchCommandException; 48 import org.jboss.jmx.adaptor.rmi.RMIAdaptor; 49 import org.jboss.logging.Logger; 50 import org.jboss.security.SecurityAssociation; 51 import org.jboss.security.SimplePrincipal; 52 import org.jboss.util.Strings; 53 54 62 public class Twiddle 63 { 64 public static final String PROGRAM_NAME = System.getProperty("program.name", "twiddle"); 65 public static final String CMD_PROPERTIES = "/org/jboss/console/twiddle/commands.properties"; 66 public static final String DEFAULT_JNDI_NAME = "jmx/invoker/RMIAdaptor"; 67 private static final Logger log = Logger.getLogger(Twiddle.class); 68 private static Twiddle twiddle = new Twiddle(new PrintWriter (System.out, true), 70 new PrintWriter (System.err, true)); 71 private static String commandName; 72 private static String [] commandArgs; 73 private static boolean commandHelp; 74 private static URL cmdProps; 75 76 private List commandProtoList = new ArrayList (); 77 private Map commandProtoMap = new HashMap (); 78 private PrintWriter out; 79 private PrintWriter err; 80 private String serverURL; 81 private String adapterName; 82 private boolean quiet; 83 private MBeanServerConnection server; 84 85 public Twiddle(final PrintWriter out, final PrintWriter err) 86 { 87 this.out = out; 88 this.err = err; 89 } 90 91 public void setServerURL(final String url) 92 { 93 this.serverURL = url; 94 } 95 96 public void setAdapterName(final String name) 97 { 98 this.adapterName = name; 99 } 100 101 public void setQuiet(final boolean flag) 102 { 103 this.quiet = flag; 104 } 105 106 public void addCommandPrototype(final Command proto) 107 { 108 String name = proto.getName(); 109 110 log.debug("Adding command '" + name + "'; proto: " + proto); 111 112 commandProtoList.add(proto); 113 commandProtoMap.put(name, proto); 114 } 115 116 private CommandContext createCommandContext() 117 { 118 return new CommandContext() 119 { 120 public boolean isQuiet() 121 { 122 return quiet; 123 } 124 125 public PrintWriter getWriter() 126 { 127 return out; 128 } 129 130 public PrintWriter getErrorWriter() 131 { 132 return err; 133 } 134 135 public MBeanServerConnection getServer() 136 { 137 try 138 { 139 connect(); 140 } 141 catch (Exception e) 142 { 143 throw new org.jboss.util.NestedRuntimeException(e); 144 } 145 146 return server; 147 } 148 }; 149 } 150 151 public Command createCommand(final String name) 152 throws NoSuchCommandException, Exception 153 { 154 158 Command proto = (Command) commandProtoMap.get(name); 159 if (proto == null) 160 { 161 throw new NoSuchCommandException(name); 162 } 163 164 Command command = (Command) proto.clone(); 165 command.setCommandContext(createCommandContext()); 166 167 return command; 168 } 169 170 private int getMaxCommandNameLength() 171 { 172 int max = 0; 173 174 Iterator iter = commandProtoList.iterator(); 175 while (iter.hasNext()) 176 { 177 Command command = (Command) iter.next(); 178 String name = command.getName(); 179 if (name.length() > max) 180 { 181 max = name.length(); 182 } 183 } 184 185 return max; 186 } 187 188 public void displayCommandList() 189 { 190 if( commandProtoList.size() == 0 ) 191 { 192 try 193 { 194 loadCommands(); 195 } 196 catch(Exception e) 197 { 198 System.err.println("Failed to load commnads from: "+cmdProps); 199 e.printStackTrace(); 200 } 201 } 202 Iterator iter = commandProtoList.iterator(); 203 204 out.println(PROGRAM_NAME + " commands: "); 205 206 int maxNameLength = getMaxCommandNameLength(); 207 log.debug("max command name length: " + maxNameLength); 208 209 while (iter.hasNext()) 210 { 211 Command proto = (Command) iter.next(); 212 String name = proto.getName(); 213 String desc = proto.getDescription(); 214 215 out.print(" "); 216 out.print(name); 217 218 out.print(Strings.pad(" ", maxNameLength - name.length())); 220 out.print(" "); 221 222 out.println(desc); 223 } 224 225 out.flush(); 226 } 227 228 private MBeanServerConnection createMBeanServerConnection() 229 throws NamingException 230 { 231 InitialContext ctx; 232 233 if (serverURL == null) 234 { 235 ctx = new InitialContext (); 236 } 237 else 238 { 239 Properties props = new Properties (System.getProperties()); 240 props.put(Context.PROVIDER_URL, serverURL); 241 ctx = new InitialContext (props); 242 } 243 244 if (adapterName == null) 246 { 247 adapterName = DEFAULT_JNDI_NAME; 248 } 249 250 Object obj = ctx.lookup(adapterName); 251 ctx.close(); 252 253 if (!(obj instanceof RMIAdaptor)) 254 { 255 throw new ClassCastException 256 ("Object not of type: RMIAdaptorImpl, but: " + 257 (obj == null ? "not found" : obj.getClass().getName())); 258 } 259 260 return (MBeanServerConnection ) obj; 261 } 262 263 private void connect() 264 throws NamingException 265 { 266 if (server == null) 267 { 268 server = createMBeanServerConnection(); 269 } 270 } 271 272 public static void main(final String [] args) 273 { 274 Command command = null; 275 276 try 277 { 278 initProtocolHandlers(); 280 281 processArguments(args); 283 loadCommands(); 284 285 if (commandName == null) 287 { 288 displayHelp(); 290 } 291 else 292 { 293 command = twiddle.createCommand(commandName); 294 295 if (commandHelp) 296 { 297 System.out.println("Help for command: '" + command.getName() + "'"); 298 System.out.println(); 299 300 command.displayHelp(); 301 } 302 else 303 { 304 command.execute(commandArgs); 306 } 307 } 308 309 System.exit(0); 310 } 311 catch (CommandException e) 312 { 313 log.error("Command failure", e); 314 System.err.println(); 315 316 if (e instanceof NoSuchCommandException) 317 { 318 twiddle.displayCommandList(); 319 } 320 else 321 { 322 323 if (command != null) 324 { 325 System.err.println("Help for command: '" + command.getName() + "'"); 326 System.err.println(); 327 328 command.displayHelp(); 329 } 330 } 331 System.exit(1); 332 } 333 catch (Exception e) 334 { 335 log.error("Exec failed", e); 336 System.exit(1); 337 } 338 } 339 340 private static void initProtocolHandlers() 341 { 342 String handlerPkgs = System.getProperty("java.protocol.handler.pkgs"); 344 if (handlerPkgs != null) 345 { 346 handlerPkgs += "|org.jboss.net.protocol"; 347 } 348 else 349 { 350 handlerPkgs = "org.jboss.net.protocol"; 351 } 352 System.setProperty("java.protocol.handler.pkgs", handlerPkgs); 353 } 354 355 private static void loadCommands() throws Exception 356 { 357 if( cmdProps == null ) 359 cmdProps = Twiddle.class.getResource(CMD_PROPERTIES); 360 if (cmdProps == null) 361 throw new IllegalStateException ("Failed to find: " + CMD_PROPERTIES); 362 InputStream input = cmdProps.openStream(); 363 log.debug("command proto type properties: " + cmdProps); 364 Properties props = new Properties (); 365 props.load(input); 366 input.close(); 367 368 Iterator iter = props.keySet().iterator(); 369 while (iter.hasNext()) 370 { 371 String name = (String ) iter.next(); 372 String typeName = props.getProperty(name); 373 Class type = Class.forName(typeName); 374 375 twiddle.addCommandPrototype((Command) type.newInstance()); 376 } 377 } 378 379 private static void displayHelp() 380 { 381 java.io.PrintStream out = System.out; 382 383 out.println("A JMX client to 'twiddle' with a remote JBoss server."); 384 out.println(); 385 out.println("usage: " + PROGRAM_NAME + " [options] <command> [command_arguments]"); 386 out.println(); 387 out.println("options:"); 388 out.println(" -h, --help Show this help message"); 389 out.println(" --help-commands Show a list of commands"); 390 out.println(" -H=<command> Show command specific help"); 391 out.println(" -c=command.properties Specify the command.properties file to use"); 392 out.println(" -D<name>[=<value>] Set a system property"); 393 out.println(" -- Stop processing options"); 394 out.println(" -s, --server=<url> The JNDI URL of the remote server"); 395 out.println(" -a, --adapter=<name> The JNDI name of the RMI adapter to use"); 396 out.println(" -u, --user=<name> Specify the username for authentication"); 397 out.println(" -p, --password=<name> Specify the password for authentication"); 398 out.println(" -q, --quiet Be somewhat more quiet"); 399 out.flush(); 400 } 401 402 private static void processArguments(final String [] args) throws Exception 403 { 404 for(int a = 0; a < args.length; a ++) 405 { 406 log.debug("args["+a+"]="+args[a]); 407 } 408 String sopts = "-:hH:u:p:c:D:s:a:q"; 409 LongOpt[] lopts = 410 { 411 new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'), 412 new LongOpt("help-commands", LongOpt.NO_ARGUMENT, null, 0x1000), 413 new LongOpt("server", LongOpt.REQUIRED_ARGUMENT, null, 's'), 414 new LongOpt("adapter", LongOpt.REQUIRED_ARGUMENT, null, 'a'), 415 new LongOpt("quiet", LongOpt.NO_ARGUMENT, null, 'q'), 416 new LongOpt("user", LongOpt.REQUIRED_ARGUMENT, null, 'u'), 417 new LongOpt("password", LongOpt.REQUIRED_ARGUMENT, null, 'p'), 418 }; 419 420 Getopt getopt = new Getopt(PROGRAM_NAME, args, sopts, lopts); 421 int code; 422 423 PROCESS_ARGUMENTS: 424 425 while ((code = getopt.getopt()) != -1) 426 { 427 switch (code) 428 { 429 case ':': 430 case '?': 431 System.exit(1); 433 break; 435 case 1: 437 { 438 commandName = getopt.getOptarg(); 440 log.debug("Command name: " + commandName); 441 442 int i = getopt.getOptind(); 444 445 if (args.length > i) 446 { 447 commandArgs = new String [args.length - i]; 448 System.arraycopy(args, i, commandArgs, 0, args.length - i); 449 } 450 else 451 { 452 commandArgs = new String [0]; 453 } 454 log.debug("Command arguments: " + Strings.join(commandArgs, ",")); 456 457 break PROCESS_ARGUMENTS; 459 } 460 461 case 'h': 463 displayHelp(); 464 System.exit(0); 465 break; 467 case 'H': 469 commandName = getopt.getOptarg(); 470 commandHelp = true; 471 break PROCESS_ARGUMENTS; 472 473 case 0x1000: 475 twiddle.displayCommandList(); 476 System.exit(0); 477 break; 479 case 'c': 480 String props = getopt.getOptarg(); 482 try 483 { 484 cmdProps = new URL (props); 485 } 486 catch (MalformedURLException e) 487 { 488 log.debug("Failed to use cmd props as url", e); 489 File path = new File (props); 490 if( path.exists() == false ) 491 { 492 String msg = "Failed to locate command props: " + props 493 + " as URL or file"; 494 throw new IllegalArgumentException (msg); 495 } 496 cmdProps = path.toURL(); 497 } 498 break; 499 case 'D': 501 { 502 String arg = getopt.getOptarg(); 503 String name, value; 504 int i = arg.indexOf("="); 505 if (i == -1) 506 { 507 name = arg; 508 value = "true"; 509 } 510 else 511 { 512 name = arg.substring(0, i); 513 value = arg.substring(i + 1, arg.length()); 514 } 515 System.setProperty(name, value); 516 break; 517 } 518 519 case 's': 521 twiddle.setServerURL(getopt.getOptarg()); 522 break; 523 524 case 'a': 526 twiddle.setAdapterName(getopt.getOptarg()); 527 break; 528 case 'u': 529 String username = getopt.getOptarg(); 530 SecurityAssociation.setPrincipal(new SimplePrincipal(username)); 531 break; 532 case 'p': 533 String password = getopt.getOptarg(); 534 SecurityAssociation.setCredential(password); 535 break; 536 537 case 'q': 539 twiddle.setQuiet(true); 540 break; 541 } 542 } 543 } 544 } 545 | Popular Tags |