1 17 18 package org.apache.geronimo.deployment.cli; 19 20 import java.io.BufferedInputStream ; 21 import java.io.File ; 22 import java.io.FileInputStream ; 23 import java.io.IOException ; 24 import java.io.InputStream ; 25 import java.io.PrintWriter ; 26 import java.io.Serializable ; 27 import java.io.FileNotFoundException ; 28 import java.util.LinkedHashMap ; 29 import java.util.List ; 30 import java.util.Map ; 31 import java.util.Properties ; 32 import java.util.jar.JarFile ; 33 34 import javax.enterprise.deploy.shared.factories.DeploymentFactoryManager ; 35 import javax.enterprise.deploy.spi.DeploymentManager ; 36 import javax.enterprise.deploy.spi.exceptions.DeploymentManagerCreationException ; 37 import javax.enterprise.deploy.spi.factories.DeploymentFactory ; 38 39 import org.apache.geronimo.common.DeploymentException; 40 import org.apache.geronimo.deployment.plugin.factories.AuthenticationFailedException; 41 import org.apache.geronimo.deployment.plugin.factories.DeploymentFactoryImpl; 42 import org.apache.geronimo.deployment.plugin.jmx.JMXDeploymentManager; 43 import org.apache.geronimo.deployment.plugin.jmx.LocalDeploymentManager; 44 import org.apache.geronimo.util.SimpleEncryption; 45 import org.apache.geronimo.kernel.Kernel; 46 import org.apache.geronimo.kernel.config.ConfigurationManager; 47 import org.apache.geronimo.kernel.config.ConfigurationUtil; 48 import org.apache.geronimo.system.main.LocalServer; 49 50 56 public class ServerConnection { 57 private final static Map OPTION_HELP = new LinkedHashMap (9); 58 59 static { 60 OPTION_HELP.put("--uri", "A URI to contact the server. If not specified, the deployer defaults to " + 61 "operating on a Geronimo server running on the standard port on localhost.\n" + 62 "A URI to connect to Geronimo (including optional host and port parameters) has the form: " + 63 "deployer:geronimo:jmx[://host[:port]] (though you could also just use --host and --port instead)."); 64 OPTION_HELP.put("--host", "The host name of a Geronimo server to deploy to. This option is " + 65 "not compatible with --uri, but is often used with --port."); 66 OPTION_HELP.put("--port", "The RMI listen port of a Geronimo server to deploy to. This option is " + 67 "not compatible with --uri, but is often used with --host. The default port is 1099."); 68 OPTION_HELP.put("--driver", "If you want to use this tool with a server other than Geronimo, " + 69 "then you must provide the path to its driver JAR. Currently, manifest " + 70 "Class-Path entries in that JAR are ignored."); 71 OPTION_HELP.put("--user", "If the deployment operation requires authentication, then you can " + 72 "specify the username to use to connect. If no password is specified, the " + 73 "deployer will attempt to connect to the server with no password, and if " + 74 "that fails, will prompt you for a password."); 75 OPTION_HELP.put("--password", "Specifies a password to use to authenticate to the server."); 76 OPTION_HELP.put("--syserr", "Enables error logging to syserr. Disabled by default."); 77 OPTION_HELP.put("--verbose", "Enables verbose execution mode. Disabled by default."); 78 OPTION_HELP.put("--offline", "Deploy offline to a local server, using whatever deployers are available in the local server"); 79 } 80 81 public static Map getOptionHelp() { 82 return OPTION_HELP; 83 } 84 85 95 public static boolean isGeneralOption(List args, String option) { 96 if (OPTION_HELP.containsKey(option) || option.equals("--url")) { 97 return true; 98 } 99 if (args.size() == 0) { 100 return false; 101 } 102 String last = (String ) args.get(args.size() - 1); 103 return last.equals("--uri") || last.equals("--url") || last.equals("--driver") || last.equals("--user") || 104 last.equals("--password") || last.equals("--host") || last.equals("--port"); 105 } 106 107 private final static String DEFAULT_URI = "deployer:geronimo:jmx"; 108 109 private DeploymentManager manager; 110 private PrintWriter out; 111 private InputStream in; 112 private SavedAuthentication auth; 113 private boolean logToSysErr; 114 private boolean verboseMessages; 115 116 public ServerConnection(String [] args, PrintWriter out, InputStream in) throws DeploymentException { 117 String uri = null, driver = null, user = null, password = null, host = null; 118 Integer port = null; 119 this.out = out; 120 this.in = in; 121 boolean offline = false; 122 for (int i = 0; i < args.length; i++) { 123 String arg = args[i]; 124 if (arg.equals("--uri") || arg.equals("--url")) { 125 if (uri != null) { 126 throw new DeploymentSyntaxException("Cannot specify more than one URI"); 127 } else if (i >= args.length - 1) { 128 throw new DeploymentSyntaxException("Must specify a URI (e.g. --uri deployer:...)"); 129 } 130 if (host != null || port != null) { 131 throw new DeploymentSyntaxException("Cannot specify a URI as well as a host/port"); 132 } 133 uri = args[++i]; 134 } else if (arg.equals("--host")) { 135 if (host != null) { 136 throw new DeploymentSyntaxException("Cannot specify more than one host"); 137 } else if (i >= args.length - 1) { 138 throw new DeploymentSyntaxException("Must specify a hostname (e.g. --host localhost)"); 139 } 140 if (uri != null) { 141 throw new DeploymentSyntaxException("Cannot specify a URI as well as a host/port"); 142 } 143 host = args[++i]; 144 } else if (arg.equals("--port")) { 145 if (port != null) { 146 throw new DeploymentSyntaxException("Cannot specify more than one port"); 147 } else if (i >= args.length - 1) { 148 throw new DeploymentSyntaxException("Must specify a port (e.g. --port 1099)"); 149 } 150 if (uri != null) { 151 throw new DeploymentSyntaxException("Cannot specify a URI as well as a host/port"); 152 } 153 try { 154 port = new Integer (args[++i]); 155 } catch (NumberFormatException e) { 156 throw new DeploymentSyntaxException("Port must be a number (" + e.getMessage() + ")"); 157 } 158 } else if (arg.equals("--driver")) { 159 if (driver != null) { 160 throw new DeploymentSyntaxException("Cannot specify more than one driver"); 161 } else if (i >= args.length - 1) { 162 throw new DeploymentSyntaxException("Must specify a driver JAR (--driver jarfile)"); 163 } 164 driver = args[++i]; 165 } else if (arg.equals("--offline")) { 166 offline = true; 168 } else if (arg.equals("--user")) { 169 if (user != null) { 170 throw new DeploymentSyntaxException("Cannot specify more than one user name"); 171 } else if (i >= args.length - 1) { 172 throw new DeploymentSyntaxException("Must specify a username (--user username)"); 173 } 174 user = args[++i]; 175 } else if (arg.equals("--password")) { 176 if (password != null) { 177 throw new DeploymentSyntaxException("Cannot specify more than one password"); 178 } else if (i >= args.length - 1) { 179 throw new DeploymentSyntaxException("Must specify a password (--password password)"); 180 } 181 password = args[++i]; 182 } else if (arg.equals("--verbose")) { 183 verboseMessages = true; 184 } else if (arg.equals("--syserr")) { 185 logToSysErr = true; 186 } else { 187 throw new DeploymentException("Invalid option " + arg); 188 } 189 } 190 if ((driver != null) && uri == null) { 191 throw new DeploymentSyntaxException("A custom driver requires a custom URI"); 192 } 193 if (host != null || port != null) { 194 uri = DEFAULT_URI + "://" + (host == null ? "" : host) + (port == null ? "" : ":" + port); 195 } 196 if (offline) { 197 LocalServer localServer; 198 try { 199 localServer = new LocalServer("org.apache.geronimo.configs/j2ee-system//car", "var/config/offline-deployer-list"); 200 } catch (Exception e) { 201 throw new DeploymentException("Could not start local server", e); 202 } 203 Kernel kernel = localServer.getKernel(); 204 ConfigurationManager configurationManager = ConfigurationUtil.getConfigurationManager(kernel); 205 configurationManager.setOnline(false); 206 207 manager = new LocalDeploymentManager(localServer.getKernel()); 208 } else { 209 tryToConnect(uri, driver, user, password, true); 210 } 211 if (manager == null) { 212 throw new DeploymentException("Unexpected error; connection failed."); 213 } 214 } 215 216 public void close() throws DeploymentException { 217 if (manager != null) { 218 manager.release(); 219 } 220 } 221 222 Serializable getAuthentication() { 223 return auth; 224 } 225 226 String getServerURI() { 227 return auth.uri; 228 } 229 230 private void tryToConnect(String argURI, String driver, String user, String password, boolean authPrompt) throws DeploymentException { 231 DeploymentFactoryManager mgr = DeploymentFactoryManager.getInstance(); 232 if (driver != null) { 233 loadDriver(driver, mgr); 234 } else { 235 mgr.registerDeploymentFactory(new DeploymentFactoryImpl()); 236 } 237 String useURI = argURI == null ? DEFAULT_URI : argURI; 238 239 if (authPrompt && user == null && password == null) { 240 InputStream in; 241 in = ServerConnection.class.getResourceAsStream("/.geronimo-deployer"); 243 if (in == null) { 245 File authFile = new File (System.getProperty("user.home"), ".geronimo-deployer"); 246 if (authFile.exists() && authFile.canRead()) { 247 try { 248 in = new BufferedInputStream (new FileInputStream (authFile)); 249 } catch (FileNotFoundException e) { 250 } 252 } 253 } 254 if (in != null) { 255 try { 256 Properties props = new Properties (); 257 props.load(in); 258 String encryped = props.getProperty("login." + useURI); 259 if (encryped != null) { 260 if (encryped.startsWith("{Standard}")) { 261 SavedAuthentication auth = (SavedAuthentication) SimpleEncryption.decrypt(encryped.substring(10)); 262 if (auth.uri.equals(useURI)) { 263 user = auth.user; 264 password = new String (auth.password); 265 } 266 } else if (encryped.startsWith("{Plain}")) { 267 int pos = encryped.indexOf("/"); 268 user = encryped.substring(7, pos); 269 password = encryped.substring(pos + 1); 270 } else { 271 System.out.print(DeployUtils.reformat("Unknown encryption used in saved login file", 4, 72)); 272 } 273 } 274 } catch (IOException e) { 275 System.out.print(DeployUtils.reformat("Unable to read authentication from saved login file: " + e.getMessage(), 4, 72)); 276 } finally { 277 try { 278 in.close(); 279 } catch (IOException e) { 280 } 282 } 283 } 284 } 285 286 if (authPrompt && !useURI.equals(DEFAULT_URI) && user == null && password == null) { 287 doAuthPromptAndRetry(useURI, user, password); 289 return; 290 } else { try { 292 manager = mgr.getDeploymentManager(useURI, user, password); 293 auth = new SavedAuthentication(useURI, user, password == null ? null : password.toCharArray()); 294 } catch (AuthenticationFailedException e) { if (authPrompt) { 296 doAuthPromptAndRetry(useURI, user, password); 297 return; 298 } else { 299 throw new DeploymentException("Login Failed"); 300 } 301 } catch (DeploymentManagerCreationException e) { 302 throw new DeploymentException("Unable to connect to server at " + useURI + " -- " + e.getMessage()); 303 } 304 } 305 306 if (manager instanceof JMXDeploymentManager) { 307 JMXDeploymentManager deploymentManager = (JMXDeploymentManager) manager; 308 deploymentManager.setLogConfiguration(logToSysErr, verboseMessages); 309 } 310 } 311 312 private void loadDriver(String driver, DeploymentFactoryManager mgr) throws DeploymentException { 313 File file = new File (driver); 314 if (!file.exists() || !file.canRead() || !DeployUtils.isJarFile(file)) { 315 throw new DeploymentSyntaxException("Driver '" + file.getAbsolutePath() + "' is not a readable JAR file"); 316 } 317 String className = null; 318 try { 319 JarFile jar = new JarFile (file); 320 className = jar.getManifest().getMainAttributes().getValue("J2EE-DeploymentFactory-Implementation-Class"); 321 if (className == null) { 322 throw new DeploymentException("The driver JAR " + file.getAbsolutePath() + " does not specify a J2EE-DeploymentFactory-Implementation-Class; cannot load driver."); 323 } 324 jar.close(); 325 DeploymentFactory factory = (DeploymentFactory ) Class.forName(className).newInstance(); 326 mgr.registerDeploymentFactory(factory); 327 } catch (DeploymentException e) { 328 throw e; 329 } catch (Exception e) { 330 throw new DeploymentSyntaxException("Unable to load driver class " + className + " from JAR " + file.getAbsolutePath(), e); 331 } 332 } 333 334 private void doAuthPromptAndRetry(String uri, String user, String password) throws DeploymentException { 335 try { 336 InputPrompt prompt = new InputPrompt(in, out); 337 if (user == null) { 338 user = prompt.getInput("Username: "); 339 } 340 if (password == null) { 341 password = prompt.getPassword("Password: "); 342 } 343 } catch (IOException e) { 344 throw new DeploymentException("Unable to prompt for login", e); 345 } 346 tryToConnect(uri, null, user, password, false); 347 } 348 349 public DeploymentManager getDeploymentManager() { 350 return manager; 351 } 352 353 public boolean isGeronimo() { 354 return manager.getClass().getName().startsWith("org.apache.geronimo."); 355 } 356 357 private final static class SavedAuthentication implements Serializable { 358 private String uri; 359 private String user; 360 private char[] password; 361 362 public SavedAuthentication(String uri, String user, char[] password) { 363 this.uri = uri; 364 this.user = user; 365 this.password = password; 366 } 367 } 368 } 369 | Popular Tags |