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 }