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