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: */package org.apache.geronimo.yoko;
017:
018: import java.lang.reflect.Method;
019: import java.util.ArrayList;
020: import java.util.Enumeration;
021: import java.util.List;
022: import java.util.Properties;
023:
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026: import org.apache.geronimo.corba.CORBABean;
027: import org.apache.geronimo.corba.CSSBean;
028: import org.apache.geronimo.corba.NameService;
029: import org.apache.geronimo.corba.ORBConfiguration;
030: import org.apache.geronimo.corba.security.config.ConfigAdapter;
031: import org.apache.geronimo.corba.security.config.ConfigException;
032: import org.apache.geronimo.corba.security.config.tss.TSSConfig;
033: import org.apache.geronimo.corba.security.config.tss.TSSSSLTransportConfig;
034: import org.apache.geronimo.corba.security.config.tss.TSSTransportMechConfig;
035: import org.apache.geronimo.gbean.GBeanLifecycle;
036: import org.apache.yoko.orb.CosNaming.tnaming.TransientNameService;
037: import org.apache.yoko.orb.CosNaming.tnaming.TransientServiceException;
038: import org.apache.yoko.orb.OB.ZERO_PORT_POLICY_ID;
039: import org.omg.CORBA.Any;
040: import org.omg.CORBA.ORB;
041: import org.omg.CORBA.Policy;
042:
043: /**
044: * A ConfigAdapter instance for the Apache Yoko
045: * CORBA support.
046: * @version $Revision: 497125 $ $Date: 2007-01-17 10:51:30 -0800 (Wed, 17 Jan 2007) $
047: */
048: public class ORBConfigAdapter implements GBeanLifecycle, ConfigAdapter {
049:
050: private final Log log = LogFactory.getLog(ORBConfigAdapter.class);
051:
052: public ORBConfigAdapter() {
053: }
054:
055: /**
056: * Start the config adapter GBean. This is basically
057: * an opportunity to set any system properties
058: * required to make the ORB hook ups. In particular,
059: * this makes the ORB hookups for the RMI over IIOP
060: * support.
061: *
062: * @exception Exception
063: */
064: public void doStart() throws Exception {
065: // define the default ORB for ORB.init();
066: System.setProperty("org.omg.CORBA.ORBClass",
067: "org.apache.yoko.orb.CORBA.ORB");
068: System.setProperty("org.omg.CORBA.ORBSingletonClass",
069: "org.apache.yoko.orb.CORBA.ORBSingleton");
070:
071: // redirect the RMI implementation to use the Yoko ORB.
072: System.setProperty("javax.rmi.CORBA.PortableRemoteObjectClass",
073: "org.apache.yoko.rmi.impl.PortableRemoteObjectImpl");
074: System.setProperty("javax.rmi.CORBA.StubClass",
075: "org.apache.yoko.rmi.impl.StubImpl");
076: // this hooks the util class and allows us to override certain functions
077: System.setProperty("javax.rmi.CORBA.UtilClass",
078: "org.apache.geronimo.corba.util.UtilDelegateImpl");
079: // this tells the openejb UtilDelegateImpl which implementation to delegate non-overridden
080: // operations to.
081: System.setProperty(
082: "org.apache.geronimo.corba.UtilDelegateClass",
083: "org.apache.yoko.rmi.impl.UtilImpl");
084: // this allows us to hook RMI stub invocation/serialization events.
085: System.setProperty(
086: "org.apache.yoko.rmi.RMIStubInitializerClass",
087: "org.apache.geronimo.yoko.RMIStubHandlerFactory");
088:
089: // ok, now we have a potential classloading problem because of where our util delegates are located.
090: // by forcing these classes to load now using our class loader, we can ensure things are properly initialized
091: Class clazz = this .getClass().getClassLoader().loadClass(
092: "javax.rmi.PortableRemoteObject");
093: Method m = clazz.getMethod("narrow", Object.class, Class.class);
094: m.invoke(null, new Object(), Object.class);
095:
096: log.debug("Started Yoko ORBConfigAdapter");
097: }
098:
099: public void doStop() throws Exception {
100: // nothing really required here.
101: log.debug("Stopped Yoko ORBConfigAdapter");
102: }
103:
104: public void doFail() {
105: // nothing much to do.
106: log.warn("Failed Yoko ORBConfigAdapter");
107: }
108:
109: /**
110: * Create an ORB for a CORBABean server context.
111: *
112: * @param server The CORBABean that owns this ORB's configuration.
113: *
114: * @return An ORB instance configured for the CORBABean.
115: * @exception ConfigException
116: */
117: public ORB createServerORB(CORBABean server) throws ConfigException {
118: ORB orb = createORB(server.getURI(), server,
119: translateToArgs(server), translateToProps(server));
120:
121: // check the tss config for a transport mech definition. If we have one, then
122: // the port information will be passed in that config, and the port in the IIOP profile
123: // needs to be zero.
124: TSSConfig config = server.getTssConfig();
125: TSSTransportMechConfig transportMech = config
126: .getTransport_mech();
127: if (transportMech != null) {
128: if (transportMech instanceof TSSSSLTransportConfig) {
129: Any any = orb.create_any();
130: any.insert_boolean(true);
131:
132: try {
133: Policy portPolicy = orb.create_policy(
134: ZERO_PORT_POLICY_ID.value, any);
135: Policy[] overrides = new Policy[] { portPolicy };
136: server.setPolicyOverrides(overrides);
137: } catch (org.omg.CORBA.PolicyError e) {
138: // shouldn't happen, but we'll let things continue with no policy set.
139: }
140:
141: }
142: }
143:
144: return orb;
145: }
146:
147: /**
148: * Create an ORB for a CSSBean client context.
149: *
150: * @param client The configured CSSBean used for access.
151: *
152: * @return An ORB instance configured for this client access.
153: * @exception ConfigException
154: */
155: public ORB createClientORB(CSSBean client) throws ConfigException {
156: return createORB(client.getURI(), client,
157: translateToArgs(client), translateToProps(client));
158: }
159:
160: /**
161: * Create an ORB for a CSSBean name service client context.
162: *
163: * @param client The configured CSSBean used for access.
164: *
165: * @return An ORB instance configured for this client access.
166: * @exception ConfigException
167: */
168: public ORB createNameServiceClientORB(CSSBean client)
169: throws ConfigException {
170: return createORB(client.getURI(), client,
171: translateToArgs(client),
172: translateToNameServiceProps(client));
173: }
174:
175: /**
176: * Create a transient name service instance using the
177: * specified host name and port.
178: *
179: * @param host The String host name.
180: * @param port The port number of the listener.
181: *
182: * @return An opaque object that represents the name service.
183: * @exception ConfigException
184: */
185: public Object createNameService(String host, int port)
186: throws ConfigException {
187: try {
188: // create a name service using the supplied host and publish under the name "NameService"
189: TransientNameService service = new TransientNameService(
190: host, port, "NameService");
191: service.run();
192: // the service instance is returned as an opaque object.
193: return service;
194: } catch (TransientServiceException e) {
195: throw new ConfigException(
196: "Error starting transient name service", e);
197: }
198: }
199:
200: /**
201: * Destroy a name service instance created by a
202: * prior call to createNameService().
203: *
204: * @param ns The opaque name service object returned from a
205: * prior call to createNameService().
206: */
207: public void destroyNameService(Object ns) {
208: // The name service instance handles its own shutdown.
209: ((TransientNameService) ns).destroy();
210: }
211:
212: /**
213: * Create an ORB instance using the configured argument
214: * and property bundles.
215: *
216: * @param name The String name of the configuration GBean used to
217: * create this ORB.
218: * @param config The GBean configuration object required by the
219: * SocketFactory instance.
220: * @param args The String arguments passed to ORB.init().
221: * @param props The property bundle passed to ORB.init().
222: *
223: * @return An ORB constructed from the provided args and properties.
224: */
225: private ORB createORB(String name, ORBConfiguration config,
226: String[] args, Properties props) {
227: return ORB.init(args, props);
228: }
229:
230: /**
231: * Translate a CORBABean configuration into an
232: * array of arguments used to configure the ORB
233: * instance.
234: *
235: * @param server The CORBABean we're creating an ORB instance for.
236: *
237: * @return A String{} array containing the initialization
238: * arguments.
239: * @exception ConfigException if configuration cannot be interpreted
240: */
241: private String[] translateToArgs(CORBABean server)
242: throws ConfigException {
243: ArrayList<String> list = new ArrayList<String>();
244: //TODO GERONIMO-2687, I don't think it makes sense to associate a default principal with a tss config, but if we need it
245: //here's the disfunctional code.
246: // TSSConfig config = server.getTssConfig();
247:
248: // if the TSSConfig includes principal information, we need to add argument values
249: // for this information.
250: // DefaultPrincipal principal = config.getDefaultPrincipal();
251: // if (principal != null) {
252: // if (principal instanceof DefaultRealmPrincipal) {
253: // DefaultRealmPrincipal realmPrincipal = (DefaultRealmPrincipal) principal;
254: // list.add("default-realm-principal::" + realmPrincipal.getRealm() + ":" + realmPrincipal.getDomain() + ":"
255: // + realmPrincipal.getPrincipal().getClassName() + ":" + realmPrincipal.getPrincipal().getPrincipalName());
256: // } else if (principal instanceof DefaultDomainPrincipal) {
257: // DefaultDomainPrincipal domainPrincipal = (DefaultDomainPrincipal) principal;
258: // list.add("default-domain-principal::" + domainPrincipal.getDomain() + ":"
259: // + domainPrincipal.getPrincipal().getClassName() + ":" + domainPrincipal.getPrincipal().getPrincipalName());
260: // } else {
261: // list.add("default-principal::" + principal.getPrincipal().getClassName() + ":" + principal.getPrincipal().getPrincipalName());
262: // }
263: // }
264:
265: // enable the connection plugin
266: enableSocketFactory(server.getURI(), list);
267:
268: NameService nameService = server.getNameService();
269: // if we have a name service to enable as an initial ref, add it to the init processing.
270: if (nameService != null) {
271: list.add("-ORBInitRef");
272: list.add("NameService=" + nameService.getURI());
273: }
274:
275: if (log.isDebugEnabled()) {
276: for (String configArg : list) {
277: log.debug(configArg);
278: }
279: }
280:
281: return list.toArray(new String[list.size()]);
282: }
283:
284: private Properties translateToProps(CORBABean server)
285: throws ConfigException {
286: Properties result = new Properties();
287:
288: result.put("org.omg.CORBA.ORBClass",
289: "org.apache.yoko.orb.CORBA.ORB");
290: result.put("org.omg.CORBA.ORBSingletonClass",
291: "org.apache.yoko.orb.CORBA.ORBSingleton");
292: result
293: .put(
294: "org.omg.PortableInterceptor.ORBInitializerClass.org.apache.geronimo.corba.transaction.TransactionInitializer",
295: "");
296: result
297: .put(
298: "org.omg.PortableInterceptor.ORBInitializerClass.org.apache.geronimo.corba.security.SecurityInitializer",
299: "");
300: result
301: .put(
302: "org.omg.PortableInterceptor.ORBInitializerClass.org.apache.geronimo.yoko.ORBInitializer",
303: "");
304: // don't specify the port if we're allowing this to default.
305: if (server.getPort() > 0) {
306: result.put("yoko.orb.oa.endpoint", "iiop --host "
307: + server.getHost() + " --port " + server.getPort());
308: } else {
309: result.put("yoko.orb.oa.endpoint", "iiop --host "
310: + server.getHost());
311: }
312:
313: // this gives us a connection we can use to retrieve the ORB configuration in the
314: // interceptors.
315: result.put("yoko.orb.id", server.getURI());
316:
317: // check the tss config for a transport mech definition. If we have one, then
318: // the port information will be passed in that config, and the port in the IIOP profile
319: // needs to be zero.
320: TSSConfig config = server.getTssConfig();
321: TSSTransportMechConfig transportMech = config
322: .getTransport_mech();
323: if (transportMech != null) {
324: if (transportMech instanceof TSSSSLTransportConfig) {
325: result.put("yoko.orb.policy.zero_port", "true");
326: }
327: }
328:
329: if (log.isDebugEnabled()) {
330: log.debug("translateToProps(TSSConfig)");
331: for (Enumeration iter = result.keys(); iter
332: .hasMoreElements();) {
333: String key = (String) iter.nextElement();
334: log.debug(key + " = " + result.getProperty(key));
335: }
336: }
337: return result;
338: }
339:
340: /**
341: * Translate a CSSBean configuration into the
342: * argument bundle needed to instantiate the
343: * ORB instance.
344: *
345: * @param client The CSSBean holding the configuration.
346: *
347: * @return A String array to be passed to ORB.init().
348: * @exception ConfigException if configuration cannot be interpreted
349: */
350: private String[] translateToArgs(CSSBean client)
351: throws ConfigException {
352: ArrayList<String> list = new ArrayList<String>();
353:
354: // enable the connection plugin
355: enableSocketFactory(client.getURI(), list);
356:
357: if (log.isDebugEnabled()) {
358: for (String configArg : list) {
359: log.debug(configArg);
360: }
361: }
362:
363: return list.toArray(new String[list.size()]);
364: }
365:
366: /**
367: * Add arguments to the ORB.init() argument list
368: * required to enable the SocketFactory used for
369: * SSL support.
370: *
371: * @param uri The URI name of the configuration GBean (either a
372: * CSSBean or a CORBABean).
373: * @param args configuration arguments to add to
374: */
375: private void enableSocketFactory(String uri, List<String> args) {
376: args.add("-IIOPconnectionHelper");
377: args.add("org.apache.geronimo.yoko.SocketFactory");
378: args.add("-IIOPconnectionHelperArgs");
379: args.add(uri);
380: }
381:
382: /**
383: * Translate a CSSBean configuration into the
384: * property bundle necessary to configure the
385: * ORB instance.
386: *
387: * @param client The CSSBean holding the configuration.
388: *
389: * @return A property bundle that can be passed to ORB.init();
390: * @exception ConfigException if configuration cannot be interpreted
391: */
392: private Properties translateToProps(CSSBean client)
393: throws ConfigException {
394: Properties result = new Properties();
395:
396: result.put("org.omg.CORBA.ORBClass",
397: "org.apache.yoko.orb.CORBA.ORB");
398: result.put("org.omg.CORBA.ORBSingletonClass",
399: "org.apache.yoko.orb.CORBA.ORBSingleton");
400: result
401: .put(
402: "org.omg.PortableInterceptor.ORBInitializerClass.org.apache.geronimo.corba.transaction.TransactionInitializer",
403: "");
404: result
405: .put(
406: "org.omg.PortableInterceptor.ORBInitializerClass.org.apache.geronimo.corba.security.SecurityInitializer",
407: "");
408: result
409: .put(
410: "org.omg.PortableInterceptor.ORBInitializerClass.org.apache.geronimo.yoko.ORBInitializer",
411: "");
412:
413: // this gives us a connection we can use to retrieve the ORB configuration in the
414: // interceptors.
415: result.put("yoko.orb.id", client.getURI());
416:
417: if (log.isDebugEnabled()) {
418: log.debug("translateToProps(CSSConfig)");
419: for (Enumeration iter = result.keys(); iter
420: .hasMoreElements();) {
421: String key = (String) iter.nextElement();
422: log.debug(key + " = " + result.getProperty(key));
423: }
424: }
425: return result;
426: }
427:
428: /**
429: * Translate a CSSBean configuration into the
430: * property bundle necessary to configure the
431: * ORB instance.
432: *
433: * @param client The CSSBean holding the configuration.
434: *
435: * @return A property bundle that can be passed to ORB.init();
436: * @exception ConfigException if configuration cannot be interpreted
437: */
438: private Properties translateToNameServiceProps(CSSBean client)
439: throws ConfigException {
440: Properties result = new Properties();
441:
442: result.put("org.omg.CORBA.ORBClass",
443: "org.apache.yoko.orb.CORBA.ORB");
444: result.put("org.omg.CORBA.ORBSingletonClass",
445: "org.apache.yoko.orb.CORBA.ORBSingleton");
446:
447: if (log.isDebugEnabled()) {
448: log.debug("translateToNameServiceProps(CSSConfig)");
449: for (Enumeration iter = result.keys(); iter
450: .hasMoreElements();) {
451: String key = (String) iter.nextElement();
452: log.debug(key + " = " + result.getProperty(key));
453: }
454: }
455: return result;
456: }
457: }
|