1 /***
2 * Redistribution and use of this software and associated documentation
3 * ("Software"), with or without modification, are permitted provided
4 * that the following conditions are met:
5 *
6 * 1. Redistributions of source code must retain copyright
7 * statements and notices. Redistributions must also contain a
8 * copy of this document.
9 *
10 * 2. Redistributions in binary form must reproduce the
11 * above copyright notice, this list of conditions and the
12 * following disclaimer in the documentation and/or other
13 * materials provided with the distribution.
14 *
15 * 3. The name "Exolab" must not be used to endorse or promote
16 * products derived from this Software without prior written
17 * permission of Exoffice Technologies. For written permission,
18 * please contact info@exolab.org.
19 *
20 * 4. Products derived from this Software may not be called "Exolab"
21 * nor may "Exolab" appear in their names without prior written
22 * permission of Exoffice Technologies. Exolab is a registered
23 * trademark of Exoffice Technologies.
24 *
25 * 5. Due credit should be given to the Exolab Project
26 * (http://www.exolab.org/).
27 *
28 * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
32 * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39 * OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Copyright 2004-2005 (C) Exoffice Technologies Inc. All Rights Reserved.
42 *
43 * $Id: RemoteServerConnector.java,v 1.7 2006/02/23 11:17:40 tanderson Exp $
44 */
45 package org.exolab.jms.server.net;
46
47 import java.rmi.RemoteException;
48 import java.util.Hashtable;
49 import java.util.Map;
50 import javax.naming.Context;
51 import javax.naming.NamingException;
52
53 import org.apache.commons.logging.Log;
54 import org.apache.commons.logging.LogFactory;
55 import org.codehaus.spice.jndikit.NamingProvider;
56
57 import org.exolab.jms.client.net.JmsServerStubImpl;
58 import org.exolab.jms.config.Configuration;
59 import org.exolab.jms.config.types.SchemeType;
60 import org.exolab.jms.net.connector.Authenticator;
61 import org.exolab.jms.net.orb.ORB;
62 import org.exolab.jms.net.orb.ORBFactory;
63 import org.exolab.jms.net.registry.LocalRegistry;
64 import org.exolab.jms.server.AdminConnectionManager;
65 import org.exolab.jms.server.NameService;
66 import org.exolab.jms.server.ServerConnectionFactory;
67 import org.exolab.jms.server.ServerConnector;
68 import org.exolab.jms.server.ServerException;
69 import org.exolab.jms.common.threads.ThreadPoolFactory;
70
71
72 /***
73 * Implementation of the {@link ServerConnector} interface, that provides
74 * remoting via an {@link ORB}.
75 *
76 * @author <a href="mailto:tma@netspace.net.au">Tim Anderson</a>
77 * @version $Revision: 1.7 $ $Date: 2006/02/23 11:17:40 $
78 */
79 public class RemoteServerConnector implements ServerConnector {
80
81 /***
82 * The configuration.
83 */
84 private final Configuration _config;
85
86 /***
87 * The connector configuration.
88 */
89 private final ConnectorCfg _connector;
90
91 /***
92 * The authenticator, for authenticating clients.
93 */
94 private final Authenticator _authenticator;
95
96 /***
97 * The factory for <code>ServerConnection</code> instances.
98 */
99 private final ServerConnectionFactory _factory;
100
101 /***
102 * The admin connection manager.
103 */
104 private final AdminConnectionManager _manager;
105
106 /***
107 * The name service.
108 */
109 private final NameService _names;
110
111 /***
112 * The thread pool factory.
113 */
114 private final ThreadPoolFactory _threads;
115
116 /***
117 * The URI to export the server on. This is the URI that the server accepts
118 * connections from clients.
119 */
120 private final String _exportURI;
121
122 /***
123 * The URI that clients connect to the server on. This is different to the
124 * {@link _exportURI) if clients connect via a webserver.
125 */
126 private final String _connectURI;
127
128 /***
129 * The ORB.
130 */
131 private ORB _orb;
132
133 /***
134 * The logger.
135 */
136 private static final Log _log = LogFactory.getLog(
137 RemoteServerConnector.class);
138
139
140 /***
141 * Construct a new <code>RemoteServerConnector</code>.
142 *
143 * @param scheme the type of the connector to use
144 * @param config the server configuration
145 * @param authenticator the authenticator for authenticating clients
146 * @param factory the factory for <code>ServerConnection</code>
147 * instances
148 * @param names the name service
149 * @param threads the thread pool factory
150 */
151 public RemoteServerConnector(SchemeType scheme, Configuration config,
152 Authenticator authenticator,
153 ServerConnectionFactory factory,
154 AdminConnectionManager manager,
155 NameService names,
156 ThreadPoolFactory threads) {
157 if (scheme == null) {
158 throw new IllegalArgumentException("Argument 'scheme' is null");
159 }
160 if (config == null) {
161 throw new IllegalArgumentException("Argument 'config' is null");
162 }
163 if (authenticator == null) {
164 throw new IllegalArgumentException(
165 "Argument 'authenticator' is null");
166 }
167 if (factory == null) {
168 throw new IllegalArgumentException("Argument 'factory' is null");
169 }
170 if (manager == null) {
171 throw new IllegalArgumentException("Argument 'manager' is null");
172 }
173 if (names == null) {
174 throw new IllegalArgumentException("Arguement 'names' is null");
175 }
176 if (threads == null) {
177 throw new IllegalArgumentException("Arguement 'threads' is null");
178 }
179 _connector = ConnectorCfgFactory.create(scheme, config);
180 _config = config;
181 _authenticator = authenticator;
182 _factory = factory;
183 _manager = manager;
184 _names = names;
185 _threads = threads;
186 _exportURI = _connector.getExportURI();
187 _connectURI = _connector.getConnectURI();
188 }
189
190 /***
191 * Initialises the server interface for the specified connector.
192 *
193 * @throws ServerException if the interface cannot be initialised
194 */
195 public void init() throws ServerException {
196 try {
197 Map properties = _connector.getAcceptProperties();
198 properties.put("org.exolab.jms.net.orb.threads.factory", _threads);
199 _orb = ORBFactory.createORB(_authenticator, properties);
200 if (!_connectURI.equals(_exportURI)) {
201 _orb.addRoute(_exportURI, _connectURI);
202 }
203 } catch (RemoteException exception) {
204 throw new ServerException(
205 "Failed to create ORB for URI:" + _exportURI, exception);
206 }
207 try {
208 LocalRegistry registry = _orb.getRegistry();
209
210 RemoteServerConnectionFactory server =
211 new RemoteServerConnectionFactory(_factory, _orb,
212 _exportURI);
213 registry.bind("server", server.getProxy());
214 if (_log.isInfoEnabled()) {
215 _log.info("Server accepting connections on " + _exportURI);
216 }
217
218 if (_config.getServerConfiguration().getEmbeddedJNDI()) {
219 NamingProvider provider = _names.getNamingProvider();
220 RemoteNamingProvider jndi = new RemoteNamingProvider(provider,
221 _orb,
222 _connector.getJNDIExportURI());
223 registry.bind("jndi", jndi.getProxy());
224 if (_log.isInfoEnabled()) {
225 _log.info("JNDI service accepting connections on "
226 + _connector.getJNDIExportURI());
227 }
228 }
229
230 JmsAdminServerImpl admin = new JmsAdminServerImpl(_manager,
231 _orb,
232 _connector.getAdminExportURI());
233 registry.bind("admin", admin.getProxy());
234 if (_log.isInfoEnabled()) {
235 _log.info("Admin service accepting connections on "
236 + _connector.getAdminExportURI());
237 }
238
239 registry.setReadOnly(true);
240 } catch (Exception exception) {
241 throw new ServerException(
242 "Failed to initialise the server interface", exception);
243 }
244 }
245
246 /***
247 * Bind any factory object specified in the configuration file to the
248 * specified JNDI context.
249 *
250 * @param context context to bind factory objects
251 * @throws NamingException if a naming error occurs
252 */
253 public void bindConnectionFactories(Context context)
254 throws NamingException {
255
256
257 Map properties = _connector.getConnectProperties();
258 Hashtable env = new Hashtable();
259 env.putAll(properties);
260 ConnectionFactoryHelper.bind(context,
261 _connector.getConnectionFactories(),
262 JmsServerStubImpl.class, env);
263 }
264
265 /***
266 * Close the interface, releasing any resources.
267 *
268 * @throws ServerException if the interface cannot be closed
269 */
270 public void close() throws ServerException {
271 try {
272 _orb.shutdown();
273 } catch (RemoteException exception) {
274 throw new ServerException(exception.getMessage(), exception);
275 }
276 }
277
278 }