001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.iiop;
023:
024: import java.io.InputStream;
025: import java.util.Hashtable;
026: import java.util.Iterator;
027: import java.util.Properties;
028:
029: import javax.naming.Context;
030: import javax.naming.InitialContext;
031: import javax.naming.Name;
032: import javax.naming.Reference;
033: import javax.naming.spi.ObjectFactory;
034:
035: import javax.ejb.spi.HandleDelegate;
036:
037: import org.jboss.system.ServiceMBeanSupport;
038: import org.jboss.system.server.ServerConfigUtil;
039: import org.omg.CORBA.ORB;
040: import org.omg.CORBA.Policy;
041: import org.omg.PortableServer.IdAssignmentPolicy;
042: import org.omg.PortableServer.IdAssignmentPolicyValue;
043: import org.omg.PortableServer.LifespanPolicy;
044: import org.omg.PortableServer.LifespanPolicyValue;
045: import org.omg.PortableServer.POA;
046: import org.omg.PortableServer.POAHelper;
047:
048: import org.w3c.dom.Element;
049:
050: import org.jboss.iiop.naming.ORBInitialContextFactory;
051: import org.jboss.metadata.MetaData;
052: import org.jboss.security.SecurityDomain;
053: import org.jboss.system.Registry;
054: import org.jboss.proxy.ejb.handle.HandleDelegateImpl;
055:
056: /**
057: * This is a JMX service that provides the default CORBA ORB
058: * for JBoss to use.
059: *
060: * @author <a href="mailto:osh@sparre.dk">Ole Husgaard</a>
061: * @author <a href="mailto:reverbel@ime.usp.br">Francisco Reverbel</a>
062: * @version $Revision: 61534 $
063: */
064: public class CorbaORBService extends ServiceMBeanSupport implements
065: CorbaORBServiceMBean, ObjectFactory {
066: // Constants -----------------------------------------------------
067:
068: public static String ORB_NAME = "JBossCorbaORB";
069: public static String POA_NAME = "JBossCorbaPOA";
070: public static String IR_POA_NAME = "JBossCorbaInterfaceRepositoryPOA";
071: public static String SSL_DOMAIN = "JBossCorbaSSLDomain";
072:
073: // Attributes ----------------------------------------------------
074:
075: private String orbClass = null;
076: private String orbSingletonClass = null;
077: private String orbSingletonDelegate = null;
078: private String orbPropertiesFileName = "orb-properties-file-not-defined";
079: private Element portableInterceptorInitializers = null;
080: private int port = 0;
081: private int sslPort = 0;
082: private String sslDomain = null;
083: private boolean sunJDK14IsLocalBugFix = false;
084:
085: // Static --------------------------------------------------------
086:
087: private static ORB orb;
088: private static POA poa;
089: private static POA irPoa;
090: private static HandleDelegate hd;
091: private static int oaSslPort;
092:
093: /**
094: * Addition of SSL components to IORs is disabled by default.
095: * This must remain off for interoperation with IONA's ASP 6.0,
096: * which does not accept IORs with SSL components.
097: */
098: private static boolean sslComponentsEnabledFlag = false;
099:
100: /**
101: * Sending an IIOP reply that carries both a CompleteEstablishContext
102: * (SAS accept) reply and an exception is enabled by default, because
103: * the CSIv2 spect does not explicitly disallow an SAS accept in an
104: * IIOP exception reply. This flag must be turned off for interoperation
105: * with IONA's ASP 6.0, which throws an ArrayIndexOutOfBoundsException
106: * when it receives an IIOP reply carrying both an application exception
107: * and a SAS reply CompleteEstablishContext.
108: */
109: private static boolean sendSasAcceptWithExceptionEnabledFlag = true;
110:
111: /**
112: * Returns the actual SSL port. This method is intended to be called
113: * by the CSIv2 IOR interceptor, which needs to know the SSL port.
114: */
115: public static int getTheActualSSLPort() {
116: return oaSslPort;
117: }
118:
119: /**
120: * Returns true if addition of SSL components to IORs is enabled.
121: * This method is intended to be called by the CSIv2 IOR interceptor.
122: */
123: public static boolean getSSLComponentsEnabledFlag() {
124: return sslComponentsEnabledFlag;
125: }
126:
127: /**
128: * Returns true if sending an SAS accept reply together with an IIOP
129: * exception reply is enabled. This method is intended to be called by
130: * the CSIv2 server request interceptor.
131: */
132: public static boolean getSendSASAcceptWithExceptionEnabledFlag() {
133: return sendSasAcceptWithExceptionEnabledFlag;
134: }
135:
136: // ServiceMBeanSupport overrides ---------------------------------
137:
138: protected void startService() throws Exception {
139:
140: Properties props = new Properties();
141:
142: // Read orb properties file into props
143: ClassLoader cl = Thread.currentThread().getContextClassLoader();
144: InputStream is = cl.getResourceAsStream(orbPropertiesFileName);
145: props.load(is);
146: String oaiAddr = props.getProperty("OAIAddr");
147: if (oaiAddr == null)
148: oaiAddr = ServerConfigUtil.getSpecificBindAddress();
149: if (oaiAddr != null)
150: props.setProperty("OAIAddr", oaiAddr);
151: log.debug("Using OAIAddr=" + oaiAddr);
152:
153: // Set ORB initialization properties
154: Properties systemProps = System.getProperties();
155: if (orbClass != null) {
156: props.put("org.omg.CORBA.ORBClass", orbClass);
157: systemProps.put("org.omg.CORBA.ORBClass", orbClass);
158: }
159: if (orbSingletonClass != null) {
160: props.put("org.omg.CORBA.ORBSingletonClass",
161: orbSingletonClass);
162: systemProps.put("org.omg.CORBA.ORBSingletonClass",
163: orbSingletonClass);
164: }
165: if (orbSingletonDelegate != null)
166: systemProps.put(
167: org.jboss.system.ORBSingleton.DELEGATE_CLASS_KEY,
168: orbSingletonDelegate);
169:
170: // JacORB-specific hack: add jacorb.config.log.verbosity to the system
171: // properties so that it is seen by JacORB at configuration time.
172: // This allows us (by setting jacorb.config.log.verbosity=0) to get rid
173: // of the messages "jacorb.home unset! Will use '.'" and
174: // "File ./jacorb.properties for configuration jacorb not found", which
175: // would otherwise be sent to the standard output.
176: String str = props.getProperty("jacorb.config.log.verbosity");
177: if (str != null)
178: systemProps.put("jacorb.config.log.verbosity", str);
179:
180: // This is for SUN JDK bug with isLocal
181: if (sunJDK14IsLocalBugFix) {
182: /* Validate that the class can actually be loaded. It cannot be used
183: under java 5 for example because the SunJDK14IsLocalBugFix base class
184: does not exist
185: */
186: try {
187: Class SunJDK14IsLocalBugFix = cl
188: .loadClass("org.jboss.iiop.SunJDK14IsLocalBugFix");
189: log
190: .debug("Was able to load SunJDK14IsLocalBugFix, class="
191: + SunJDK14IsLocalBugFix);
192: // Its loadable to use it
193: systemProps.put("javax.rmi.CORBA.UtilClass",
194: "org.jboss.iiop.SunJDK14IsLocalBugFix");
195: } catch (Throwable t) {
196: log
197: .debug(
198: "Ignoring sunJDK14IsLocalBugFix=true due to inability to load org.jboss.iiop.SunJDK14IsLocalBugFix",
199: t);
200: }
201: }
202:
203: System.setProperties(systemProps);
204:
205: // Add portable interceptor initializers
206: Iterator initializerElements = MetaData.getChildrenByTagName(
207: portableInterceptorInitializers, "initializer");
208: if (initializerElements != null) {
209: while (initializerElements.hasNext()) {
210: Element initializerElement = (Element) initializerElements
211: .next();
212: String portableInterceptorInitializerClassName = MetaData
213: .getElementContent(initializerElement);
214: log.debug("Adding portable interceptor initializer: "
215: + portableInterceptorInitializerClassName);
216: if (portableInterceptorInitializerClassName != null
217: && !portableInterceptorInitializerClassName
218: .equals(""))
219: props
220: .put(
221: "org.omg.PortableInterceptor.ORBInitializerClass."
222: + portableInterceptorInitializerClassName,
223: "");
224: }
225: }
226:
227: // Allows overriding of OAPort/OASSLPort
228: // from config file through MBean config
229: if (port != 0)
230: props.put("OAPort", Integer.toString(this .port));
231: if (sslPort != 0)
232: props.put("OASSLPort", Integer.toString(this .sslPort));
233:
234: // Keep the actual SSL port in a static field
235: // (the CSIv2 IOR interceptor needs this value)
236: String oaSslPortString = props.getProperty("OASSLPort");
237: if (oaSslPortString != null)
238: oaSslPort = Integer.parseInt(oaSslPortString);
239:
240: // Allow SSL domain to be specified through MBean config
241: if (sslDomain != null) {
242: InitialContext ctx = new InitialContext();
243: log.debug("sslDomain: " + sslDomain);
244: try {
245: SecurityDomain domain = (SecurityDomain) ctx
246: .lookup(sslDomain);
247:
248: // Make SSL domain available to socket factories
249: Registry.bind(SSL_DOMAIN, domain);
250: } catch (Exception e) {
251: log.warn("Security domain " + sslDomain + " not found");
252: if (log.isDebugEnabled())
253: log.debug("Exception looking up " + sslDomain
254: + ": ", e);
255: }
256: }
257:
258: // Initialize the ORB
259: orb = ORB.init(new String[0], props);
260: bind(ORB_NAME, "org.omg.CORBA.ORB");
261: CorbaORB.setInstance(orb);
262: ORBInitialContextFactory.setORB(orb);
263:
264: // Initialize the POA
265: poa = POAHelper.narrow(orb
266: .resolve_initial_references("RootPOA"));
267: poa.the_POAManager().activate();
268: bind(POA_NAME, "org.omg.PortableServer.POA");
269:
270: // Make the ORB work
271: new Thread(new Runnable() {
272: public void run() {
273: orb.run();
274: }
275: }, "ORB thread").start();
276:
277: // Create a POA for interface repositories
278: try {
279: LifespanPolicy lifespanPolicy = poa
280: .create_lifespan_policy(LifespanPolicyValue.PERSISTENT);
281: IdAssignmentPolicy idAssignmentPolicy = poa
282: .create_id_assignment_policy(IdAssignmentPolicyValue.USER_ID);
283:
284: irPoa = poa.create_POA("IR", null, new Policy[] {
285: lifespanPolicy, idAssignmentPolicy });
286: bind(IR_POA_NAME, "org.omg.PortableServer.POA");
287:
288: // Activate the poa
289: irPoa.the_POAManager().activate();
290:
291: } catch (Exception ex) {
292: getLog().error("Error in IR POA initialization", ex);
293: }
294:
295: // Keep a HandleDelegate
296: hd = new HandleDelegateImpl();
297: }
298:
299: protected void stopService() throws Exception {
300: /*
301: if( mJSR77 != null )
302: {
303: RMI_IIOPResource.destroy(
304: getServer(),
305: ORB_NAME
306: );
307: mJSR77 = null;
308: }
309: */
310: try {
311: // Unbind from JNDI
312: unbind(ORB_NAME);
313: unbind(POA_NAME);
314: unbind(IR_POA_NAME);
315:
316: // Stop ORB
317: orb.shutdown(false);
318:
319: // Unbind SSL domain
320: Registry.unbind(SSL_DOMAIN);
321: } catch (Exception e) {
322: log.error("Exception while stopping ORB service", e);
323: }
324: }
325:
326: // CorbaORBServiceMBean implementation ---------------------------
327:
328: public ORB getORB() {
329: return orb;
330: }
331:
332: public HandleDelegate getHandleDelegate() {
333: return hd;
334: }
335:
336: public String getORBClass() {
337: return orbClass;
338: }
339:
340: public void setORBClass(String orbClass) {
341: this .orbClass = orbClass;
342: }
343:
344: public String getORBSingletonClass() {
345: return orbSingletonClass;
346: }
347:
348: public void setORBSingletonClass(String orbSingletonClass) {
349: this .orbSingletonClass = orbSingletonClass;
350: }
351:
352: public String getORBSingletonDelegate() {
353: return orbSingletonDelegate;
354: }
355:
356: public void setORBSingletonDelegate(String orbSingletonDelegate) {
357: this .orbSingletonDelegate = orbSingletonDelegate;
358: }
359:
360: public void setORBPropertiesFileName(String orbPropertiesFileName) {
361: this .orbPropertiesFileName = orbPropertiesFileName;
362: }
363:
364: public String getORBPropertiesFileName() {
365: return orbPropertiesFileName;
366: }
367:
368: public Element getPortableInterceptorInitializers() {
369: return portableInterceptorInitializers;
370: }
371:
372: public void setPortableInterceptorInitializers(
373: Element portableInterceptorInitializers) {
374: this .portableInterceptorInitializers = portableInterceptorInitializers;
375: }
376:
377: public void setPort(int port) {
378: this .port = port;
379: }
380:
381: public int getPort() {
382: return this .port;
383: }
384:
385: public void setSSLPort(int sslPort) {
386: this .sslPort = sslPort;
387: }
388:
389: public int getSSLPort() {
390: return this .sslPort;
391: }
392:
393: public void setSecurityDomain(String sslDomain) {
394: this .sslDomain = sslDomain;
395: }
396:
397: public String getSecurityDomain() {
398: return this .sslDomain;
399: }
400:
401: public boolean getSSLComponentsEnabled() {
402: return CorbaORBService.sslComponentsEnabledFlag;
403: }
404:
405: public void setSSLComponentsEnabled(boolean sslComponentsEnabled) {
406: CorbaORBService.sslComponentsEnabledFlag = sslComponentsEnabled;
407: }
408:
409: public boolean getSendSASAcceptWithExceptionEnabled() {
410: return CorbaORBService.sendSasAcceptWithExceptionEnabledFlag;
411: }
412:
413: public void setSendSASAcceptWithExceptionEnabled(boolean value) {
414: CorbaORBService.sendSasAcceptWithExceptionEnabledFlag = value;
415: }
416:
417: public boolean getSunJDK14IsLocalBugFix() {
418: return sunJDK14IsLocalBugFix;
419: }
420:
421: public void setSunJDK14IsLocalBugFix(boolean sunJDK14IsLocalBugFix) {
422: this .sunJDK14IsLocalBugFix = sunJDK14IsLocalBugFix;
423: }
424:
425: // ObjectFactory implementation ----------------------------------
426:
427: public Object getObjectInstance(Object obj, Name name,
428: Context nameCtx, Hashtable environment) throws Exception {
429: String s = name.toString();
430: if (getLog().isTraceEnabled())
431: getLog().trace(
432: "getObjectInstance: obj.getClass().getName=\""
433: + obj.getClass().getName()
434: + "\n name=" + s);
435: if (ORB_NAME.equals(s))
436: return orb;
437: if (POA_NAME.equals(s))
438: return poa;
439: if (IR_POA_NAME.equals(s))
440: return irPoa;
441: return null;
442: }
443:
444: // Private -------------------------------------------------------
445:
446: private void bind(String name, String className) throws Exception {
447: Reference ref = new Reference(className, getClass().getName(),
448: null);
449: new InitialContext().bind("java:/" + name, ref);
450: }
451:
452: private void unbind(String name) throws Exception {
453: new InitialContext().unbind("java:/" + name);
454: }
455:
456: }
|