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 }