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.corba;
017:
018: import java.net.InetAddress;
019: import java.net.InetSocketAddress;
020: import java.net.UnknownHostException;
021:
022: import javax.ejb.spi.HandleDelegate;
023:
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026: import org.apache.geronimo.gbean.AbstractName;
027: import org.apache.geronimo.gbean.GBeanLifecycle;
028: import org.apache.geronimo.gbean.InvalidConfigurationException;
029: import org.apache.geronimo.corba.security.ServerPolicy;
030: import org.apache.geronimo.corba.security.ServerPolicyFactory;
031: import org.apache.geronimo.corba.security.config.ConfigAdapter;
032: import org.apache.geronimo.corba.security.config.ssl.SSLConfig;
033: import org.apache.geronimo.corba.security.config.tss.TSSConfig;
034: import org.apache.geronimo.corba.security.config.tss.TSSSSLTransportConfig;
035: import org.apache.geronimo.corba.security.config.tss.TSSTransportMechConfig;
036: import org.apache.geronimo.corba.util.Util;
037: import org.apache.geronimo.openejb.OpenEjbSystem;
038: import org.omg.CORBA.Any;
039: import org.omg.CORBA.ORB;
040: import org.omg.CORBA.Policy;
041: import org.omg.PortableServer.POA;
042: import org.omg.PortableServer.POAHelper;
043:
044: /**
045: * A CORBABean is a main CORBA server configuration. The
046: * CORBABean is the hosting ORB to which additional TSSBeans
047: * attach to export EJBs. The CORBABean may be configured
048: * to use either plain socket listeners or SSL listeners, based
049: * on the bean specification. All TSSBean objects attached
050: * to this Bean instance will share the same listener
051: * endpoint and transport-level security.
052: * @version $Revision: 497125 $ $Date: 2007-01-17 10:51:30 -0800 (Wed, 17 Jan 2007) $
053: */
054: public class CORBABean implements GBeanLifecycle, ORBRef,
055: ORBConfiguration {
056: private final Log log = LogFactory.getLog(CORBABean.class);
057:
058: private final ClassLoader classLoader;
059: private final ConfigAdapter configAdapter;
060: // the initial listener port
061: private int listenerPort;
062: // the host name we expose in IORs
063: private String host;
064: private TSSConfig tssConfig;
065: private SSLConfig sslConfig;
066: private ORB orb;
067: private POA rootPOA;
068: private NameService nameService;
069: private AbstractName abstractName;
070: private OpenEjbSystem ejbSystem;
071: // ORB-specific policy overrides we need to add to POA policies created by
072: // child TSSBeans.
073: private Policy[] policyOverrides = null;
074:
075: public CORBABean() {
076: this .classLoader = null;
077: this .configAdapter = null;
078: this .sslConfig = null;
079: this .listenerPort = -1;
080: this .host = null;
081: this .abstractName = null;
082: this .policyOverrides = null;
083: this .ejbSystem = null;
084: }
085:
086: /**
087: * Instantiate a CORBABean instance.
088: *
089: * @param abstractName
090: * The server-created abstract name for this bean instance.
091: * @param configAdapter
092: * The ORB ConfigAdapter used to interface with the
093: * JVM-configured ORB instance.
094: * @param host The hostname we publish ourselves under.
095: * @param listenerPort
096: * The initial listener port to use.
097: * @param classLoader
098: * The ClassLoader used for ORB context class loading.
099: * @param nameService
100: * The initial name service the created ORB will use
101: * for object resolution.
102: * @param ssl The SSL configuration, including the KeystoreManager.
103: *
104: */
105: public CORBABean(AbstractName abstractName,
106: ConfigAdapter configAdapter, String host, int listenerPort,
107: ClassLoader classLoader, NameService nameService,
108: OpenEjbSystem ejbSystem, SSLConfig ssl) {
109: this .abstractName = abstractName;
110: this .classLoader = classLoader;
111: this .configAdapter = configAdapter;
112: sslConfig = ssl;
113: this .nameService = nameService;
114: this .host = host;
115: this .listenerPort = listenerPort;
116: this .policyOverrides = null;
117: this .ejbSystem = ejbSystem;
118: }
119:
120: /**
121: * Retrieve the NameService this CORBA server depends upon.
122: *
123: * @return The configured NameService instance.
124: */
125: public NameService getNameService() {
126: return nameService;
127: }
128:
129: /**
130: * Setter attribute for the NameService.
131: *
132: * @param s The new target name service.
133: */
134: public void setNameService(NameService s) {
135: nameService = s;
136: }
137:
138: /**
139: * Get the optional TSSConfig object specified for this
140: * CORBABean server.
141: *
142: * @return The TSSConfig object (if any).
143: */
144: public TSSConfig getTssConfig() {
145: // if nothing has been explicitly set, ensure we return
146: // a default one.
147: if (tssConfig == null) {
148: tssConfig = new TSSConfig();
149: }
150: return tssConfig;
151: }
152:
153: /**
154: * Set a TSSConfig value for this CORBA instance.
155: *
156: * @param config The required TSSConfig information.
157: */
158: public void setTssConfig(TSSConfig config) {
159: this .tssConfig = config;
160: }
161:
162: /**
163: * Return the SSLConfig used for this ORB instance.
164: * if one has not been configured, this returns
165: * a default configuration.
166: *
167: * @return The SSLConfig object use to manage transport-level
168: * security.
169: */
170: public SSLConfig getSslConfig() {
171: if (sslConfig == null) {
172: sslConfig = new SSLConfig();
173: }
174: return sslConfig;
175: }
176:
177: /**
178: * Attribute setter for the SSL configuration.
179: *
180: * @param c The new SSLConfig object used for secure communications.
181: */
182: public void setSslConfing(SSLConfig c) {
183: sslConfig = c;
184: }
185:
186: /**
187: * Return the ORB instance created for this CORBABean.
188: *
189: * @return The ORB instance backing this bean.
190: */
191: public ORB getORB() {
192: return orb;
193: }
194:
195: public HandleDelegate getHandleDelegate() {
196: return new CORBAHandleDelegate();
197: }
198:
199: /**
200: * Get the root POA() instance associated with the ORB.
201: *
202: * @return The rootPOA instance obtained from the ORB.
203: */
204: public POA getRootPOA() {
205: return rootPOA;
206: }
207:
208: /**
209: * Retrieve the listener address (host/port combo) used
210: * by the ORB.
211: *
212: * @return An InetSocketAddress item identifying the end point
213: * for the ORB.
214: */
215: public InetSocketAddress getListenAddress() {
216: return new InetSocketAddress(host, listenerPort);
217: }
218:
219: /**
220: * Start the ORB associated with this bean instance.
221: *
222: * @exception Exception
223: */
224: public void doStart() throws Exception {
225:
226: ClassLoader savedLoader = Thread.currentThread()
227: .getContextClassLoader();
228: try {
229: Thread.currentThread().setContextClassLoader(classLoader);
230:
231: // make sure we've decided how the listener should be configured.
232: resolveListenerAddress();
233: // register this so we can retrieve this in the interceptors
234: Util.registerORB(getURI(), this );
235:
236: log.debug("CORBABean " + getURI()
237: + " creating listener on port " + listenerPort);
238: // the config adapter creates the actual ORB instance for us.
239: orb = configAdapter.createServerORB(this );
240:
241: // we set this ORB value into the Util. The Util ORB is used for a lot of utility things, so
242: // we'll cache the first instance created.
243: Util.setORB(orb);
244:
245: // TSSBeans are going to need our rootPOA instance, so resolve this now.
246: org.omg.CORBA.Object obj = orb
247: .resolve_initial_references("RootPOA");
248: rootPOA = POAHelper.narrow(obj);
249: // if we have an OpenEjbSystem reference, inform the ejb subsystem
250: // there's now an ORB available for the JNDI context.
251: if (ejbSystem != null) {
252: ejbSystem.setORBContext(orb, getHandleDelegate());
253: }
254: } catch (NoSuchMethodError e) {
255: log
256: .error("Incorrect level of org.omg.CORBA classes found.\nLikely cause is an incorrect java.endorsed.dirs configuration");
257: throw new InvalidConfigurationException(
258: "CORBA usage requires Yoko CORBA spec classes in java.endorsed.dirs classpath",
259: e);
260: } finally {
261: Thread.currentThread().setContextClassLoader(savedLoader);
262: }
263:
264: }
265:
266: public void doStop() throws Exception {
267: orb.destroy();
268: // remove this from the registry
269: Util.unregisterORB(getURI());
270: log.debug("Stopped CORBABean");
271: }
272:
273: public void doFail() {
274: log.warn("Failed CORBABean");
275: }
276:
277: /**
278: * Process the specified host/port information on
279: * both the bean and the TSSConfig to arrive at a
280: * target port. This must be called prior to creating
281: * the ORB.
282: */
283: private void resolveListenerAddress() {
284: // now provide defaults for anything still needing resolving
285: if (host == null) {
286: try {
287: host = InetAddress.getLocalHost().getHostName();
288: } catch (UnknownHostException e) {
289: // just punt an use localhost as an absolute fallback.
290: host = "localhost";
291: }
292: }
293:
294: // if nothing has been explicitly specified, we use a port value of -1, which
295: // allows the ORB to allocate the address.
296:
297: // if we have a config with a TSSSSLTransportConfig defined, the
298: // host and port from the config override bean-configured values.
299: if (tssConfig != null) {
300: TSSTransportMechConfig transportMech = tssConfig
301: .getTransport_mech();
302: if (transportMech != null) {
303: if (transportMech instanceof TSSSSLTransportConfig) {
304: TSSSSLTransportConfig transportConfig = (TSSSSLTransportConfig) transportMech;
305: transportConfig.setHostname(host);
306: transportConfig.setPort((short) listenerPort);
307: }
308: }
309: }
310:
311: }
312:
313: /**
314: * Return the retrieval URI for this bean.
315: *
316: * @return The URI for the bean AbstractName;
317: */
318: public String getURI() {
319: return abstractName.toString();
320: }
321:
322: /**
323: * Get the configured listener port.
324: *
325: * @return The configeration port value.
326: */
327: public int getPort() {
328: return listenerPort;
329: }
330:
331: /**
332: * Get the configuration host name.
333: *
334: * @return The configuration host name. The default is "localhost".
335: */
336: public String getHost() {
337: return host;
338: }
339:
340: /**
341: * Set a set of policy overrides to be used with
342: * this ORB instance. These are normally set by
343: * the ORBConfigAdapter instance when the ORB
344: * is created.
345: *
346: * @param overrides The new override list.
347: */
348: public void setPolicyOverrides(Policy[] overrides) {
349: policyOverrides = overrides;
350: }
351:
352: /**
353: * Add the policy overrides (if any) to the list
354: * of policies used to create a POA instance.
355: *
356: * @param policies The base set of policies.
357: *
358: * @return A new Policy array with the overrides added. Returns
359: * the same array if no overrides are required.
360: */
361: public Policy[] addPolicyOverrides(Policy[] policies) {
362: // just return the same list of no overrides exist
363: if (policyOverrides == null) {
364: return policies;
365: }
366:
367: Policy[] newPolicies = new Policy[policies.length
368: + policyOverrides.length];
369:
370: System.arraycopy(policies, 0, newPolicies, 0, policies.length);
371: System.arraycopy(policyOverrides, 0, newPolicies,
372: policies.length, policyOverrides.length);
373:
374: return newPolicies;
375: }
376: }
|