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 033 import org.apache.commons.logging.Log; 034 import org.apache.commons.logging.LogFactory; 035 import org.apache.geronimo.deployment.ModuleConfigurer; 036 import org.apache.geronimo.deployment.plugin.DisconnectedDeploymentManager; 037 import org.apache.geronimo.deployment.plugin.jmx.LocalDeploymentManager; 038 import org.apache.geronimo.deployment.plugin.jmx.RemoteDeploymentManager; 039 import org.apache.geronimo.kernel.KernelRegistry; 040 041 /** 042 * Base implementation of JSR88 DeploymentFactory. 043 * 044 * This will create a DeploymentManager using a local Geronimo kernel 045 * to contain the GBeans that are responsible for deploying each module 046 * type. 047 * 048 * @version $Rev: 527918 $ $Date: 2007-04-12 09:04:16 -0400 (Thu, 12 Apr 2007) $ 049 */ 050 public class BaseDeploymentFactory implements DeploymentFactory { 051 private static final Log log = LogFactory.getLog(BaseDeploymentFactory.class); 052 053 public static final String URI_PREFIX = "deployer:geronimo:"; 054 private static final int DEFAULT_PORT = 1099; 055 056 public BaseDeploymentFactory() { 057 } 058 059 public String getDisplayName() { 060 return "Apache Geronimo"; 061 } 062 063 public String getProductVersion() { 064 return "1.0"; 065 } 066 067 public boolean handlesURI(String uri) { 068 return parseURI(uri) != null; 069 } 070 071 private ConnectParams parseURI(String uri) { 072 uri = uri.trim(); 073 if(!uri.startsWith(URI_PREFIX)) { 074 return null; 075 } 076 uri = uri.substring(URI_PREFIX.length()); 077 int pos = uri.indexOf(":"); 078 String protocol = pos == -1 ? uri : uri.substring(0, pos); 079 uri = pos == -1 ? "" : uri.substring(pos+1); 080 if(protocol.equals("jmx")) { 081 if(!uri.startsWith("//")) { 082 return new ConnectParams(protocol, "localhost", DEFAULT_PORT); 083 } 084 uri = uri.substring(2); 085 pos = uri.indexOf(':'); 086 if(pos == -1) { 087 return new ConnectParams(protocol, uri.equals("") ? "localhost" : uri, DEFAULT_PORT); 088 } 089 if(uri.indexOf('/', pos+1) > -1) { 090 return null; 091 } 092 if(uri.indexOf(':', pos+1) > -1) { 093 return null; 094 } 095 String host = uri.substring(0, pos); 096 String port = uri.substring(pos+1); 097 try { 098 return new ConnectParams(protocol, host.equals("") ? "localhost" : host, Integer.parseInt(port)); 099 } catch (NumberFormatException e) { 100 return null; 101 } 102 } else if(protocol.equals("inVM")) { 103 if(uri.startsWith("//")) { 104 String kernel = uri.substring(2); 105 return new ConnectParams(protocol, kernel, -1); 106 } else { 107 return new ConnectParams(protocol, 108 KernelRegistry.getSingleKernel() == null ? null : KernelRegistry.getSingleKernel().getKernelName(), 109 -1); 110 } 111 } else return null; 112 } 113 114 public DeploymentManager getDisconnectedDeploymentManager(String uri) throws DeploymentManagerCreationException { 115 if (!handlesURI(uri)) { 116 return null; 117 } 118 119 Collection<ModuleConfigurer> moduleConfigurers = getModuleConfigurers(); 120 return new DisconnectedDeploymentManager(moduleConfigurers); 121 } 122 123 public DeploymentManager getDeploymentManager(String uri, String username, String password) throws DeploymentManagerCreationException { 124 ConnectParams params = parseURI(uri); 125 if (params == null) { 126 return null; 127 } 128 129 try { 130 if (params.getProtocol().equals("jmx")) { 131 return newRemoteDeploymentManager(username, password, params); 132 } else if(params.getProtocol().equals("inVM")) { 133 return new LocalDeploymentManager(KernelRegistry.getKernel(params.getHost())); 134 } else { 135 throw new DeploymentManagerCreationException("Invalid URI: " + uri); 136 } 137 } catch (RuntimeException e) { 138 // some DeploymentManagerFactories suppress unchecked exceptions - log and rethrow 139 log.error(e.getMessage(), e); 140 throw e; 141 } catch (Error e) { 142 // some DeploymentManagerFactories suppress unchecked exceptions - log and rethrow 143 log.error(e.getMessage(), e); 144 throw e; 145 } 146 } 147 148 protected Collection<ModuleConfigurer> getModuleConfigurers() throws DeploymentManagerCreationException { 149 return Collections.EMPTY_LIST; 150 } 151 152 protected DeploymentManager newRemoteDeploymentManager(String username, String password, ConnectParams params) throws DeploymentManagerCreationException, AuthenticationFailedException { 153 Map environment = new HashMap(); 154 String[] credentials = new String[]{username, password}; 155 environment.put(JMXConnector.CREDENTIALS, credentials); 156 environment.put(JMXConnectorFactory.DEFAULT_CLASS_LOADER, BaseDeploymentFactory.class.getClassLoader()); 157 try { 158 JMXServiceURL address = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://"+params.getHost()+":"+params.getPort()+"/JMXConnector"); 159 JMXConnector jmxConnector = JMXConnectorFactory.connect(address, environment); 160 RemoteDeploymentManager manager = getRemoteDeploymentManager(); 161 manager.init(jmxConnector, params.getHost()); 162 if(!manager.isSameMachine()) { 163 manager.setAuthentication(username, password); 164 } 165 return manager; 166 } catch (IOException e) { 167 throw (DeploymentManagerCreationException)new DeploymentManagerCreationException(e.getMessage()).initCause(e); 168 } catch (SecurityException e) { 169 throw (AuthenticationFailedException) new AuthenticationFailedException("Invalid login.").initCause(e); 170 } 171 } 172 173 protected RemoteDeploymentManager getRemoteDeploymentManager() throws DeploymentManagerCreationException { 174 Collection<ModuleConfigurer> moduleConfigurers = getModuleConfigurers(); 175 return new RemoteDeploymentManager(moduleConfigurers); 176 } 177 178 private final static class ConnectParams { 179 private String protocol; 180 private String host; 181 private int port; 182 183 public ConnectParams(String protocol, String host, int port) { 184 this.protocol = protocol; 185 this.host = host; 186 this.port = port; 187 } 188 189 public String getProtocol() { 190 return protocol; 191 } 192 193 public String getHost() { 194 return host; 195 } 196 197 public int getPort() { 198 return port; 199 } 200 201 public String toString() { 202 return protocol+" / "+host+" / "+port; 203 } 204 } 205 206 }