001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.geronimo.deployment.plugin.factories; 019 020 import java.io.IOException; 021 import java.util.Collection; 022 import java.util.Collections; 023 import java.util.HashMap; 024 import java.util.Map; 025 026 import javax.enterprise.deploy.spi.DeploymentManager; 027 import javax.enterprise.deploy.spi.exceptions.DeploymentManagerCreationException; 028 import javax.enterprise.deploy.spi.factories.DeploymentFactory; 029 import javax.management.remote.JMXConnector; 030 import javax.management.remote.JMXConnectorFactory; 031 import javax.management.remote.JMXServiceURL; 032 import javax.management.remote.rmi.RMIConnectorServer; 033 import javax.rmi.ssl.SslRMIClientSocketFactory; 034 035 import org.apache.commons.logging.Log; 036 import org.apache.commons.logging.LogFactory; 037 import org.apache.geronimo.deployment.ModuleConfigurer; 038 import org.apache.geronimo.deployment.plugin.DisconnectedDeploymentManager; 039 import org.apache.geronimo.deployment.plugin.jmx.LocalDeploymentManager; 040 import org.apache.geronimo.deployment.plugin.jmx.RemoteDeploymentManager; 041 import org.apache.geronimo.kernel.KernelRegistry; 042 043 /** 044 * Base implementation of JSR88 DeploymentFactory. 045 * 046 * This will create a DeploymentManager using a local Geronimo kernel 047 * to contain the GBeans that are responsible for deploying each module 048 * type. 049 * 050 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $ 051 */ 052 public class BaseDeploymentFactory implements DeploymentFactory { 053 private static final Log log = LogFactory.getLog(BaseDeploymentFactory.class); 054 055 public static final String URI_PREFIX = "deployer:geronimo:"; 056 private static final int DEFAULT_PORT = 1099; 057 058 public BaseDeploymentFactory() { 059 } 060 061 public String getDisplayName() { 062 return "Apache Geronimo"; 063 } 064 065 public String getProductVersion() { 066 return "1.0"; 067 } 068 069 public boolean handlesURI(String uri) { 070 return parseURI(uri) != null; 071 } 072 073 private ConnectParams parseURI(String uri) { 074 uri = uri.trim(); 075 if (log.isDebugEnabled()) { 076 log.debug("Parsing URI=" + uri); 077 } 078 if(!uri.startsWith(URI_PREFIX)) { 079 return null; 080 } 081 uri = uri.substring(URI_PREFIX.length()); 082 int pos = uri.indexOf(":"); 083 String protocol = pos == -1 ? uri : uri.substring(0, pos); 084 uri = pos == -1 ? "" : uri.substring(pos+1); 085 if(protocol.equals("jmx") || protocol.equals("jmxs")) { 086 boolean secure = protocol.equals("jmxs"); 087 if(!uri.startsWith("//")) { 088 return new ConnectParams(protocol, "localhost", DEFAULT_PORT, secure); 089 } 090 uri = uri.substring(2); 091 pos = uri.indexOf(':'); 092 if(pos == -1) { 093 return new ConnectParams(protocol, uri.equals("") ? "localhost" : uri, DEFAULT_PORT, secure); 094 } 095 if(uri.indexOf('/', pos+1) > -1) { 096 return null; 097 } 098 if(uri.indexOf(':', pos+1) > -1) { 099 return null; 100 } 101 String host = uri.substring(0, pos); 102 String port = uri.substring(pos+1); 103 try { 104 return new ConnectParams(protocol, host.equals("") ? "localhost" : host, Integer.parseInt(port), secure); 105 } catch (NumberFormatException e) { 106 return null; 107 } 108 } else if(protocol.equals("inVM")) { 109 if(uri.startsWith("//")) { 110 String kernel = uri.substring(2); 111 return new ConnectParams(protocol, kernel, -1); 112 } else { 113 return new ConnectParams(protocol, 114 KernelRegistry.getSingleKernel() == null ? null : KernelRegistry.getSingleKernel().getKernelName(), 115 -1); 116 } 117 } else return null; 118 } 119 120 public DeploymentManager getDisconnectedDeploymentManager(String uri) throws DeploymentManagerCreationException { 121 if (!handlesURI(uri)) { 122 return null; 123 } 124 125 Collection<ModuleConfigurer> moduleConfigurers = getModuleConfigurers(); 126 return new DisconnectedDeploymentManager(moduleConfigurers); 127 } 128 129 public DeploymentManager getDeploymentManager(String uri, String username, String password) throws DeploymentManagerCreationException { 130 ConnectParams params = parseURI(uri); 131 if (params == null) { 132 return null; 133 } 134 if (log.isDebugEnabled()) { 135 log.debug("Using protocol=" + params.getProtocol() + ", host=" + params.getHost() + ", port=" + params.getPort()); 136 } 137 138 try { 139 if (params.getProtocol().equals("jmx") || params.getProtocol().equals("jmxs")) { 140 return newRemoteDeploymentManager(username, password, params); 141 } else if(params.getProtocol().equals("inVM")) { 142 return new LocalDeploymentManager(KernelRegistry.getKernel(params.getHost())); 143 } else { 144 throw new DeploymentManagerCreationException("Invalid URI: " + uri); 145 } 146 } catch (RuntimeException e) { 147 // some DeploymentManagerFactories suppress unchecked exceptions - log and rethrow 148 log.error(e.getMessage(), e); 149 throw e; 150 } catch (Error e) { 151 // some DeploymentManagerFactories suppress unchecked exceptions - log and rethrow 152 log.error(e.getMessage(), e); 153 throw e; 154 } 155 } 156 157 protected Collection<ModuleConfigurer> getModuleConfigurers() throws DeploymentManagerCreationException { 158 return Collections.EMPTY_LIST; 159 } 160 161 protected DeploymentManager newRemoteDeploymentManager(String username, String password, ConnectParams params) throws DeploymentManagerCreationException, AuthenticationFailedException { 162 Map environment = new HashMap(); 163 String[] credentials = new String[]{username, password}; 164 environment.put(JMXConnector.CREDENTIALS, credentials); 165 environment.put(JMXConnectorFactory.DEFAULT_CLASS_LOADER, BaseDeploymentFactory.class.getClassLoader()); 166 String connectorName = "/JMXConnector"; 167 if (params.isSecure()) { 168 connectorName = "/JMXSecureConnector"; 169 SslRMIClientSocketFactory csf = new SslRMIClientSocketFactory(); 170 environment.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf); 171 } 172 try { 173 // if ipv6 numeric address wrap with "[" "]" 174 String host = params.getHost(); 175 if (host.indexOf(":") >= 0) { 176 host = "[" + host + "]"; 177 } 178 if (log.isDebugEnabled()) { 179 log.debug("Using JMXServiceURL with host=" + host + ", port=" + params.getPort() + ", secure=" + params.isSecure()); 180 } 181 JMXServiceURL address = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://"+ host +":"+params.getPort()+connectorName); 182 JMXConnector jmxConnector = JMXConnectorFactory.connect(address, environment); 183 RemoteDeploymentManager manager = getRemoteDeploymentManager(); 184 manager.init(jmxConnector, host); 185 if(!manager.isSameMachine()) { 186 manager.setAuthentication(username, password); 187 } 188 return manager; 189 } catch (IOException e) { 190 DeploymentManagerCreationException deploymentManagerCreationException = 191 (DeploymentManagerCreationException) new DeploymentManagerCreationException(e.getMessage()).initCause(e); 192 log.debug("throwing ", deploymentManagerCreationException); 193 throw deploymentManagerCreationException; 194 } catch (SecurityException e) { 195 AuthenticationFailedException authenticationFailedException = 196 (AuthenticationFailedException) new AuthenticationFailedException("Invalid login.").initCause(e); 197 log.debug("throwing ", authenticationFailedException); 198 throw authenticationFailedException; 199 } 200 } 201 202 protected RemoteDeploymentManager getRemoteDeploymentManager() throws DeploymentManagerCreationException { 203 Collection<ModuleConfigurer> moduleConfigurers = getModuleConfigurers(); 204 return new RemoteDeploymentManager(moduleConfigurers); 205 } 206 207 private final static class ConnectParams { 208 private String protocol; 209 private String host; 210 private int port; 211 private boolean secure; 212 213 public ConnectParams(String protocol, String host, int port) { 214 this(protocol, host, port, false); 215 } 216 217 public ConnectParams(String protocol, String host, int port, boolean secure) { 218 this.protocol = protocol; 219 this.host = host; 220 this.port = port; 221 this.secure = secure; 222 } 223 224 public String getProtocol() { 225 return protocol; 226 } 227 228 public String getHost() { 229 return host; 230 } 231 232 public int getPort() { 233 return port; 234 } 235 236 public boolean isSecure() { 237 return secure; 238 } 239 240 public String toString() { 241 return protocol+" / "+host+" / "+port; 242 } 243 } 244 245 }