1 /*------------------------------------------------------------------------------
2 Name: CorbaConnection.java
3 Project: xmlBlaster.org
4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
5 Comment: Helper to connect to xmlBlaster using IIOP
6 Author: xmlBlaster@marcelruff.info
7 ------------------------------------------------------------------------------*/
8 package org.xmlBlaster.client.protocol.corba;
9
10 import org.xmlBlaster.client.protocol.I_XmlBlasterConnection;
11
12 import java.util.logging.Logger;
13 import java.util.logging.Level;
14
15 import org.xmlBlaster.util.FileLocator;
16 import org.xmlBlaster.util.Global;
17 import org.xmlBlaster.client.qos.ConnectReturnQos;
18 import org.xmlBlaster.util.XmlBlasterException;
19 import org.xmlBlaster.util.def.ErrorCode;
20 import org.xmlBlaster.util.qos.address.Address;
21 import org.xmlBlaster.util.xbformat.I_ProgressListener;
22
23 import org.xmlBlaster.util.plugin.I_Plugin;
24 import org.xmlBlaster.util.plugin.PluginInfo;
25 import org.xmlBlaster.util.protocol.corba.OrbInstanceFactory;
26
27 import org.xmlBlaster.util.def.Constants;
28 import org.xmlBlaster.util.MsgUnitRaw;
29 import org.xmlBlaster.protocol.corba.serverIdl.Server;
30 import org.xmlBlaster.protocol.corba.serverIdl.ServerHelper;
31 import org.xmlBlaster.protocol.corba.authenticateIdl.AuthServer;
32 import org.xmlBlaster.protocol.corba.authenticateIdl.AuthServerHelper;
33
34 import org.omg.CosNaming.NamingContext;
35 import org.omg.CosNaming.NamingContextExt;
36 import org.omg.CosNaming.NameComponent;
37 import org.omg.CosNaming.BindingHolder;
38 import org.omg.CosNaming.BindingListHolder;
39 import org.omg.CosNaming.BindingIteratorHolder;
40
41 import java.applet.Applet;
42
43
44 /**
45 * This is a helper class, helping a Java client to connect to xmlBlaster
46 * using IIOP (CORBA).
47 * <p>
48 * Please note that you don't need to use this wrapper, you can use the raw CORBA
49 * interface as well. You can also hack your own little wrapper, which does exactly
50 * what you want.
51 * <p>
52 * This class converts the Corba based exception<br />
53 * org.xmlBlaster.protocol.corba.serverIdl.XmlBlasterException<br />
54 * to<br />
55 * org.xmlBlaster.util.XmlBlasterException
56 * <p>
57 * There is a constructor for applets, and standalone Java clients.
58 * <p />
59 * If you need a failsafe client, you can invoke the xmlBlaster CORBA methods
60 * through this class as well (for example use corbaConnection.publish() instead of the direct
61 * CORBA server.publish()).
62 * <p />
63 * You should set jacorb.retries=0 in $HOME/.jacorb_properties if you use the failsafe mode
64 * <p />
65 * If you want to connect from a servlet, please use the framework in xmlBlaster/src/java/org/xmlBlaster/protocol/http
66 * <p />
67 * NOTE: JacORB 1.1 does not release the listener thread and the poa threads of the callback server
68 * on orb.shutdown().<br />
69 * Therefor we recycle the ORB and POA instance to avoid a thread leak.
70 * The drawback is that a client for the bug being can't change the orb behavior after the
71 * first time the ORB is created.<br />
72 * This will be fixed as soon as possible.
73 *
74 * @see <a href="http://www.xmlBlaster.org/xmlBlaster/src/java/org/xmlBlaster/protocol/corba/xmlBlaster.idl" target="others">CORBA xmlBlaster.idl</a>
75 * @author <a href="mailto:xmlBlaster@marcelruff.info">Marcel Ruff</a>.
76 */
77 public final class CorbaConnection implements I_XmlBlasterConnection, I_Plugin
78 {
79 private String ME = "CorbaConnection";
80 private Global glob;
81 private static Logger log = Logger.getLogger(CorbaConnection.class.getName());
82
83 private org.omg.CORBA.ORB orb;
84
85 private NamingContextExt nameService;
86 private AuthServer authServer;
87 private Server xmlBlaster;
88 private Address clientAddress;
89 private String sessionId;
90 private boolean verbose = true;
91 private PluginInfo pluginInfo;
92
93
94 /**
95 * Called by plugin loader which calls init(Global, PluginInfo) thereafter.
96 */
97 public CorbaConnection() {
98 }
99
100 /**
101 * CORBA client access to xmlBlaster for <strong>applets</strong>.
102 * <p />
103 * Use these environment settings for JacORB if you don't use this constructor!
104 * <br />
105 * Example:
106 * <pre>
107 * <APPLET
108 * CODEBASE = "http://localhost"
109 * CODE = "DemoApplet.class"
110 * NAME = "xmlBlaster demo"
111 * WIDTH = 200
112 * HEIGHT = 200
113 * HSPACE = 0
114 * VSPACE = 0
115 * ALIGN = middle
116 * >
117 * <PARAM name=org.omg.CORBA.ORBClass value=org.jacorb.orb.ORB>
118 * <PARAM name=org.omg.CORBA.ORBSingletonClass value=org.jacorb.orb.ORBSingleton>
119 * <PARAM name=SVCnameroot value=xmlBlaster-Authenticate>
120 * </APPLET>
121 * </pre>
122 * @param ap Applet handle
123 */
124 public CorbaConnection(Global glob, Applet ap) {
125 // try to force to use JacORB instead of builtin CORBA:
126 String orbClassName = "org.jacorb.orb.ORB";
127 String orbSingleton = "org.jacorb.orb.ORBSingleton";
128 java.util.Properties props = new java.util.Properties();
129 props.put("org.omg.CORBA.ORBClass", orbClassName);
130 props.put("org.omg.CORBA.ORBSingletonClass", orbSingleton);
131
132 orb = org.omg.CORBA.ORB.init(ap, props); // for applets only
133
134 init(glob, null);
135
136 log.info("Using ORB=" + orbClassName + " and ORBSingleton=" + orbSingleton);
137 }
138
139 /**
140 * Enforced by I_Plugin
141 * @return "IOR"
142 */
143 public String getType() {
144 return getProtocol();
145 }
146
147 /** Enforced by I_Plugin */
148 public String getVersion() {
149 return "1.0";
150 }
151
152 /**
153 * This method is called by the PluginManager (enforced by I_Plugin).
154 * @see org.xmlBlaster.util.plugin.I_Plugin#init(org.xmlBlaster.util.Global,org.xmlBlaster.util.plugin.PluginInfo)
155 */
156 public void init(org.xmlBlaster.util.Global glob, PluginInfo pluginInfo) {
157 this.glob = (glob == null) ? Global.instance() : glob;
158
159 this.pluginInfo = pluginInfo;
160 resetConnection();
161 log.info("Created '" + getProtocol() + "' protocol plugin to connect to xmlBlaster server");
162 }
163
164 /**
165 * Reset
166 */
167 public void resetConnection() {
168 if (log.isLoggable(Level.FINE)) log.fine("resetConnection():");
169 this.authServer = null;
170 this.xmlBlaster = null;
171 }
172
173 /**
174 * @return The connection protocol name "IOR"
175 */
176 public final String getProtocol() {
177 return "IOR";
178 }
179
180 /**
181 * Accessing the orb handle.
182 * @return org.omg.CORBA.ORB
183 */
184 public org.omg.CORBA.ORB getOrb() {
185 return this.orb;
186 }
187
188 /**
189 * Accessing the xmlBlaster handle.
190 * For internal use, throws a COMMUNICATION XmlBlasterException if xmlBlaster==null
191 * We use this for similar handling as org.omg exceptions.
192 * @return Server
193 */
194 private Server getXmlBlaster() throws XmlBlasterException {
195 if (this.xmlBlaster == null) {
196 if (log.isLoggable(Level.FINE)) log.fine("No CORBA connection available.");
197 throw new XmlBlasterException(glob, ErrorCode.COMMUNICATION_NOCONNECTION, ME,
198 "The CORBA xmlBlaster handle is null, no connection available");
199 }
200 return this.xmlBlaster;
201 }
202
203
204 /**
205 * Locate the CORBA Name Service.
206 * <p />
207 * The found name service is cached, for better performance in subsequent calls
208 * @return NamingContextExt, reference on name service
209 * @exception XmlBlasterException id="NoNameService"
210 * CORBA error handling if no naming service is found
211 */
212 NamingContextExt getNamingService() throws XmlBlasterException
213 {
214 if (log.isLoggable(Level.FINER)) log.finer("getNamingService() ...");
215 if (nameService != null)
216 return nameService;
217
218 if (orb == null) {
219 log.severe("orb==null, internal problem");
220 Thread.dumpStack();
221 throw new XmlBlasterException(glob, ErrorCode.COMMUNICATION_NOCONNECTION, ME, "orb==null, internal problem");
222 }
223
224 // Get a reference to the Name Service, CORBA compliant:
225 org.omg.CORBA.Object nameServiceObj = null;
226 try {
227 nameServiceObj = orb.resolve_initial_references("NameService");
228 }
229 catch (Throwable e) {
230 String text = "Can't access naming service, is there any running?\n" +
231 " - try to specify '-dispatch/connection/plugin/ior/iorFile <fileName>' if server is running on same host (not using any naming service)\n" +
232 " - try to specify '-bootstrapHostname <hostName> -bootstrapPort " + Constants.XMLBLASTER_PORT + "' to locate xmlBlaster (not using any naming service)\n" +
233 " - or contact the server administrator to start a naming service";
234 if (this.verbose)
235 log.warning(text);
236 throw new XmlBlasterException(glob, ErrorCode.RESOURCE_UNAVAILABLE, "NoNameService", text);
237 }
238 if (nameServiceObj == null) {
239 throw new XmlBlasterException(glob, ErrorCode.RESOURCE_UNAVAILABLE, "NoNameService", "Can't access naming service (null), is there any running?");
240 }
241 // if (log.isLoggable(Level.FINE)) log.trace(ME, "Successfully accessed initial orb references for naming service (IOR)");
242
243 try {
244 nameService = org.omg.CosNaming.NamingContextExtHelper.narrow(nameServiceObj);
245 if (nameService == null) {
246 log.severe("Can't access naming service (narrow problem)");
247 throw new XmlBlasterException(glob, ErrorCode.RESOURCE_UNAVAILABLE, "NoNameService", "Can't access naming service (narrow problem)");
248 }
249 if (log.isLoggable(Level.FINE)) log.fine("Successfully narrowed handle for naming service");
250 return nameService; // Note: the naming service IOR is successfully evaluated (from a IOR),
251 // but it is not sure that the naming service is really running
252 }
253 catch (Throwable e) {
254 if (this.verbose) log.warning("Can't access naming service");
255 throw new XmlBlasterException(glob, ErrorCode.RESOURCE_UNAVAILABLE, "NoNameService", e.toString());
256 }
257 }
258
259
260 /**
261 * Access the authentication service.
262 * <p />
263 * There are several ways to bootstrap the authentication service:
264 * <br />
265 * <ul>
266 * <li>Give the authentication service string-IOR at command line, e.g.<br />
267 * <code> -dispatch/callback/plugin/ior/iorString "IOR:0000..."</code><br />
268 * or giving a file name<br />
269 * <code> -dispatch/connection/plugin/ior/iorFile yourIorFile</code></li>
270 * <li>Give the xmlBlaster host and bootstrap port where xmlBlaster-Authenticate serves the IOR via http, give at command line e.g.
271 * <code> -bootstrapHostname server.xmlBlaster.org -bootstrapPort 3412</code></li>
272 * <li>Try to find a naming service which knows about 'xmlBlaster-Authenticate'</li>
273 * </ul>
274 * <p />
275 * @return a handle on the AuthServer IDL interface
276 * @exception XmlBlasterException id="NoAuthService"
277 *
278 */
279 public AuthServer getAuthenticationService(Address address) throws XmlBlasterException {
280 if (log.isLoggable(Level.FINER)) log.finer("getAuthenticationService() ...");
281 if (this.authServer != null) {
282 return this.authServer;
283 }
284
285 address = (address == null) ? new Address(glob) : address;
286 if (this.pluginInfo != null)
287 address.setPluginInfoParameters(this.pluginInfo.getParameters());
288
289 try {
290 // 0) Check if programmer has given the IOR hardcoded
291 if (address.getRawAddress() != null && address.getRawAddress().length() > 2) {
292 String authServerIOR = address.getRawAddress();
293 this.authServer = AuthServerHelper.narrow(orb.string_to_object(authServerIOR));
294 if (this.verbose) log.info("Accessing xmlBlaster using your given IOR string in Address.getRawAddress()");
295 return this.authServer;
296 }
297
298 // 1) check if argument -IOR at program startup is given "-dispatch/connection/plugin/ior/iorString"
299 String authServerIOR = address.getEnv("iorString", (String)null).getValue();
300 if (authServerIOR != null) {
301 this.authServer = AuthServerHelper.narrow(orb.string_to_object(authServerIOR));
302 if (this.verbose) log.info("Accessing xmlBlaster using your given IOR string");
303 return this.authServer;
304 }
305 if (log.isLoggable(Level.FINE)) log.fine("No -dispatch/connection/plugin/ior/iorString ...");
306
307 String authServerIORFile = glob.getProperty().get("dispatch/connection/plugin/ior/iorFile", (String)null); // -dispatch/connection/plugin/ior/iorFile IOR string is given through a file
308 if (authServerIORFile != null) {
309 try {
310 authServerIOR = FileLocator.readAsciiFile(authServerIORFile);
311 } catch (XmlBlasterException e) {
312 log.warning("Accessing xmlBlaster given IOR file '" + authServerIORFile + "' failed, please check 'dispatch/connection/plugin/ior/iorFile'");
313 }
314 this.authServer = AuthServerHelper.narrow(orb.string_to_object(authServerIOR));
315 log.info("Accessing xmlBlaster using your given IOR file " + authServerIORFile);
316 return this.authServer;
317 }
318 if (log.isLoggable(Level.FINE)) log.fine("No -dispatch/connection/plugin/ior/iorFile ...");
319
320
321 // 2) check if argument -bootstrapHostname <hostName or IP> -bootstrapPort <number> at program startup is given
322 // To avoid the name service, one can access the AuthServer IOR directly
323 // using a http connection.
324 try {
325 authServerIOR = glob.accessFromInternalHttpServer(address, "AuthenticationService.ior", this.verbose);
326 if (System.getProperty("java.version").startsWith("1") && !authServerIOR.startsWith("IOR:")) {
327 authServerIOR = "IOR:000" + authServerIOR; // hack for JDK 1.1.x, where the IOR: is cut away from ByteReader ??? !!!
328 log.warning("Manipulated IOR because of missing 'IOR:'");
329 }
330 this.authServer = AuthServerHelper.narrow(orb.string_to_object(authServerIOR));
331 log.info("Accessing xmlBlaster AuthServer IOR using builtin http connection to " +
332 address.getBootstrapUrl());
333 return this.authServer;
334 }
335 catch(XmlBlasterException e) {
336 ;
337 }
338 catch(Throwable e) {
339 if (this.verbose) {
340 log.severe("XmlBlaster not found with internal HTTP download");
341 e.printStackTrace();
342 }
343 }
344 if (log.isLoggable(Level.FINE)) log.fine("No -bootstrapHostname / -bootstrapPort for " + address.getBootstrapUrl() + " ...");
345
346 String contextId = glob.getProperty().get("NameService.context.id", "xmlBlaster");
347 if (contextId == null) contextId = "";
348 String contextKind = glob.getProperty().get("NameService.context.kind", "MOM");
349 if (contextKind == null) contextKind = "";
350 String clusterId = glob.getProperty().get("NameService.node.id", glob.getStrippedId());
351 if (clusterId == null) clusterId = "";
352 String clusterKind = glob.getProperty().get("NameService.node.kind", "MOM");
353 if (clusterKind == null) clusterKind = "";
354
355 String text = "Can't access xmlBlaster Authentication Service, is the server running and ready?\n" +
356 " - try to specify '-dispatch/connection/plugin/ior/iorFile <fileName>' if server is running on same host\n" +
357 " - try to specify '-bootstrapHostname <hostName> -bootstrapPort " + Constants.XMLBLASTER_PORT + "' to locate xmlBlaster\n" +
358 " - or start a naming service '" + contextId + "." + contextKind + "/" +
359 clusterId + "." + clusterKind + "'";
360
361 // 3) asking Name Service CORBA compliant
362 boolean useNameService = address.getEnv("useNameService", true).getValue(); // -plugin/ior/ns default is to ask the naming service
363 if (useNameService) {
364
365 if (this.verbose) log.info("Trying to find a CORBA naming service ...");
366 try {
367
368 // NameService entry is e.g. "xmlBlaster.MOM/heron.MOM"
369 // where "xmlBlaster.MOM" is a context node and
370 // "heron.MOM" is a subnode for each running server (containing the AuthServer POA reference)
371
372 NamingContextExt namingContextExt = getNamingService();
373 NameComponent [] nameXmlBlaster = new NameComponent[] { new NameComponent(contextId, contextKind) };
374 if (log.isLoggable(Level.FINE)) log.fine("Query NameServer -ORBInitRef NameService=" + glob.getProperty().get("ORBInitRef","") +
375 ((System.getProperty("ORBInitRef.NameService") != null) ? System.getProperty("ORBInitRef.NameService") : "") +
376 " to find the xmlBlaster root context " + OrbInstanceFactory.getString(nameXmlBlaster));
377 org.omg.CORBA.Object obj = namingContextExt.resolve(nameXmlBlaster);
378 NamingContext relativeContext = org.omg.CosNaming.NamingContextExtHelper.narrow(obj);
379
380 if (relativeContext == null) {
381 throw new Exception("Can't resolve CORBA NameService");
382 }
383
384 NameComponent [] nameNode = new NameComponent[] { new NameComponent(clusterId, clusterKind) };
385
386 AuthServer authServerFirst = null;
387 String tmpId = ""; // for logging only
388 String tmpServerName = ""; // for logging only
389 String firstServerName = ""; // for logging only
390 int countServerFound = 0; // for logging only
391 String serverNameList = ""; // for logging only
392 try {
393 this.authServer = AuthServerHelper.narrow(relativeContext.resolve(nameNode));
394 }
395 catch (Exception ex) {
396 if (log.isLoggable(Level.FINE)) log.fine("Query NameServer to find a suitable xmlBlaster server for " + OrbInstanceFactory.getString(nameXmlBlaster) + "/" + OrbInstanceFactory.getString(nameNode));
397 BindingListHolder bl = new BindingListHolder();
398 BindingIteratorHolder bi = new BindingIteratorHolder();
399 relativeContext.list(0, bl, bi);
400 //for (int i=0; i<bl.value.length; i++) { // bl.value.length should be 0
401 // String id = bl.value[i].binding_name[0].id;
402 // String kind = bl.value[i].binding_name[0].kind;
403
404 // process the remaining bindings if an iterator exists:
405 if (this.authServer == null && bi.value != null) {
406 BindingHolder bh = new BindingHolder();
407 int i = 0;
408 while ( bi.value.next_one(bh) ) {
409 String id = bh.value.binding_name[0].id;
410 String kind = bh.value.binding_name[0].kind;
411 NameComponent [] nameNodeTmp = new NameComponent[] { new NameComponent(id, kind) };
412
413 tmpId = id;
414 countServerFound++;
415 tmpServerName = OrbInstanceFactory.getString(nameXmlBlaster)+"/"+OrbInstanceFactory.getString(nameNodeTmp);
416 if (i>0) serverNameList += ", ";
417 i++;
418 serverNameList += tmpServerName;
419
420 if (clusterId.equals(id) && clusterKind.equals(kind)) {
421 try {
422 if (log.isLoggable(Level.FINE)) log.fine("Trying to resolve NameService entry '"+OrbInstanceFactory.getString(nameNodeTmp)+"'");
423 this.authServer = AuthServerHelper.narrow(relativeContext.resolve(nameNodeTmp));
424 break; // found a matching server
425 }
426 catch (Exception exc) {
427 log.warning("Connecting to NameService entry '"+tmpServerName+"' failed: " + exc.toString());
428 }
429 }
430
431 if (authServerFirst == null) {
432 if (log.isLoggable(Level.FINE)) log.fine("Remember the first server");
433 try {
434 firstServerName = tmpServerName;
435 if (log.isLoggable(Level.FINE)) log.fine("Remember the first reachable xmlBlaster server from NameService entry '"+firstServerName+"'");
436 authServerFirst = AuthServerHelper.narrow(relativeContext.resolve(nameNodeTmp));
437 }
438 catch (Exception exc) {
439 log.warning("Connecting to NameService entry '"+tmpServerName+"' failed: " + exc.toString());
440 }
441 }
442 }
443 }
444 }
445
446 if (this.authServer == null) {
447 if (authServerFirst != null) {
448 if (countServerFound > 1) {
449 String str = "Can't choose one of " + countServerFound +
450 " avalailable server in CORBA NameService: " + serverNameList +
451 ". Please choose one with e.g. -NameService.node.id " + tmpId;
452 log.severe(str);
453 throw new Exception(str);
454 }
455 log.info("Choosing only available server '" + firstServerName + "' in CORBA NameService -ORBInitRef NameService=" +
456 System.getProperty("ORBInitRef"));
457 this.authServer = authServerFirst;
458 return authServerFirst;
459 }
460 else {
461 throw new Exception("No xmlBlaster server found in NameService");
462 }
463 }
464
465 log.info("Accessing xmlBlaster using a naming service '" + nameXmlBlaster[0].id + "." + nameXmlBlaster[0].kind + "/" +
466 nameNode[0].id + "." + nameNode[0].kind + "' on " + System.getProperty("ORBInitRef"));
467 return this.authServer;
468 }
469 catch(Throwable e) {
470 throw new XmlBlasterException(glob, ErrorCode.COMMUNICATION_NOCONNECTION, ME, text, e);
471 }
472 }
473 if (log.isLoggable(Level.FINE)) log.fine("No -plugin/ior/useNameService ...");
474 throw new XmlBlasterException(glob, ErrorCode.COMMUNICATION_NOCONNECTION, ME, text);
475 }
476 finally {
477 this.verbose = false;
478 }
479 }
480
481 /**
482 * Login to the server.
483 * <p />
484 * @param connectQos The encrypted connect QoS
485 * @exception XmlBlasterException if login fails
486 */
487 public String connect(String connectQos) throws XmlBlasterException {
488 if (connectQos == null)
489 throw new XmlBlasterException(glob, ErrorCode.INTERNAL_ILLEGALARGUMENT, ME, "Please pass a valid QoS for connect()");
490
491 this.ME = "CorbaConnection";
492 if (log.isLoggable(Level.FINER)) log.finer("connect(xmlBlaster="+this.xmlBlaster+") ...");
493 try {
494 AuthServer remoteAuthServer = getAuthenticationService(this.clientAddress);
495 if (log.isLoggable(Level.FINE)) log.fine("Got authServer handle, trying connect ...");
496 return remoteAuthServer.connect(connectQos);
497 }
498 catch(XmlBlasterException e) {
499 throw e;
500 }
501 catch(org.xmlBlaster.protocol.corba.serverIdl.XmlBlasterException e) {
502 XmlBlasterException xmlBlasterException = OrbInstanceFactory.convert(glob, e);
503 //xmlBlasterException.changeErrorCode(ErrorCode.COMMUNICATION_NOCONNECTION);
504 throw xmlBlasterException; // Wrong credentials
505 }
506 catch(Throwable e) {
507 XmlBlasterException xmlBlasterException = XmlBlasterException.convert(glob, ME, "Login failed", e);
508 xmlBlasterException.changeErrorCode(ErrorCode.COMMUNICATION_NOCONNECTION);
509 throw xmlBlasterException;
510 }
511 }
512
513 /**
514 * @see I_XmlBlasterConnection#connectLowlevel(Address)
515 */
516 public void connectLowlevel(Address address) throws XmlBlasterException {
517 if (log.isLoggable(Level.FINER)) log.finer("connectLowlevel() ...");
518 this.clientAddress = address;
519 if (this.orb == null) {
520 this.orb = OrbInstanceFactory.createOrbInstance(this.glob,(String[])null,
521 glob.getProperty().getProperties(), this.clientAddress);
522 }
523 getAuthenticationService(this.clientAddress);
524 if (log.isLoggable(Level.FINE)) log.fine("Success, connectLowlevel()");
525 }
526
527 /**
528 * @see I_XmlBlasterConnection#setConnectReturnQos(ConnectReturnQos)
529 */
530 public void setConnectReturnQos(ConnectReturnQos connectReturnQos) throws XmlBlasterException {
531 try {
532 this.sessionId = connectReturnQos.getSecretSessionId();
533 String xmlBlasterIOR = connectReturnQos.getServerRef().getAddress();
534 this.xmlBlaster = ServerHelper.narrow(orb.string_to_object(xmlBlasterIOR));
535 this.ME = "CorbaConnection-"+connectReturnQos.getSessionName().toString();
536 if (log.isLoggable(Level.FINE)) log.fine("setConnectReturnQos(): xmlBlaster=" + this.xmlBlaster);
537 }
538 catch(Throwable e) {
539 this.xmlBlaster = null;
540 XmlBlasterException xmlBlasterException = XmlBlasterException.convert(glob, ME, "Login failed", e);
541 xmlBlasterException.changeErrorCode(ErrorCode.COMMUNICATION_NOCONNECTION);
542 throw xmlBlasterException;
543 }
544 }
545
546 /**
547 * Logout from the server.
548 * Note that this kills the server ping thread as well (if in failsafe mode)
549 * @return true successfully logged out
550 * false failure on logout
551 */
552 public boolean disconnect(String qos) {
553 if (log.isLoggable(Level.FINER)) log.finer("disconnect() ...");
554
555 if (this.xmlBlaster == null) {
556 try {
557 shutdown();
558 }
559 catch (XmlBlasterException ex) {
560 log.severe("disconnect. Could not shutdown properly. " + ex.getMessage());
561 }
562 return false;
563 }
564
565 try {
566 if (this.authServer != null) {
567 if(this.sessionId==null) {
568 this.authServer.logout(xmlBlaster);
569 }
570 else {
571 this.authServer.disconnect(this.sessionId, (qos==null)?"":qos); // secPlgn.exportMessage(""));
572 }
573 }
574 shutdown();
575 this.xmlBlaster = null;
576 return true;
577 } catch(org.xmlBlaster.protocol.corba.serverIdl.XmlBlasterException e) {
578 log.warning("Remote exception: " + OrbInstanceFactory.convert(glob, e).getMessage());
579 } catch(org.omg.CORBA.OBJ_ADAPTER e) {
580 log.warning("No disconnect possible, no CORBA connection available: " + e.toString());
581 } catch(org.omg.CORBA.TRANSIENT e) {
582 log.warning("No disconnect possible, CORBA connection lost: " + e.toString());
583 } catch(org.omg.CORBA.COMM_FAILURE e) {
584 log.warning("No disconnect possible, CORBA connection lost: " + e.toString());
585 } catch(org.omg.CORBA.OBJECT_NOT_EXIST e) {
586 log.warning("No disconnect possible, CORBA connection lost: " + e.toString());
587 } catch(Throwable e) {
588 XmlBlasterException xmlBlasterException = XmlBlasterException.convert(glob, ME, null, e);
589 log.warning(xmlBlasterException.getMessage());
590 e.printStackTrace();
591 }
592
593 try {
594 shutdown();
595 }
596 catch (XmlBlasterException ex) {
597 log.severe("disconnect. Could not shutdown properly. " + ex.getMessage());
598 }
599 this.xmlBlaster = null;
600 return false;
601 }
602
603 /**
604 * Shut down the callback server.
605 * Is called by logout()
606 */
607 public void shutdown() throws XmlBlasterException {
608 if (log.isLoggable(Level.FINER)) log.finer("shutdown()");
609 if (this.authServer != null) {
610 this.authServer._release();
611 this.authServer = null;
612 }
613 if (this.xmlBlaster != null) {
614 this.xmlBlaster._release();
615 this.xmlBlaster = null;
616 }
617 if (this.orb != null) {
618 boolean wait_for_completion = false;
619 try {
620 this.orb.shutdown(wait_for_completion);
621 this.orb = null;
622 }
623 catch (Throwable ex) {
624 log.warning("shutdown: Exception occured during orb.shutdown("+wait_for_completion+"): " + ex.toString());
625 }
626 }
627 }
628
629 /**
630 * @return true if you are logged in
631 */
632 public boolean isLoggedIn() {
633 return this.xmlBlaster != null;
634 }
635
636 /**
637 * Enforced by I_XmlBlasterConnection interface (failsafe mode).
638 * see explanations of subscribe() method.
639 * @see <a href="http://www.xmlBlaster.org/xmlBlaster/src/java/org/xmlBlaster/protocol/corba/xmlBlaster.idl" target="others">CORBA xmlBlaster.idl</a>
640 */
641 public final String subscribe(String xmlKey, String qos) throws XmlBlasterException {
642 if (log.isLoggable(Level.FINER)) log.finer("subscribe() ...");
643 try {
644 return getXmlBlaster().subscribe(xmlKey, qos);
645 } catch(org.xmlBlaster.protocol.corba.serverIdl.XmlBlasterException e) {
646 throw OrbInstanceFactory.convert(glob, e); // transform Corba exception to native exception
647 } catch(Throwable e) {
648 throw new XmlBlasterException(glob, ErrorCode.COMMUNICATION_NOCONNECTION, ME, "subscribe", e);
649 }
650 }
651
652 /**
653 * Enforced by I_XmlBlasterConnection interface (failsafe mode)
654 * @see <a href="http://www.xmlBlaster.org/xmlBlaster/src/java/org/xmlBlaster/protocol/corba/xmlBlaster.idl" target="others">CORBA xmlBlaster.idl</a>
655 */
656 public final String[] unSubscribe(String xmlKey, String qos) throws XmlBlasterException {
657 if (log.isLoggable(Level.FINER)) log.finer("unSubscribe() ...");
658 try {
659 return getXmlBlaster().unSubscribe(xmlKey, qos);
660 } catch(org.xmlBlaster.protocol.corba.serverIdl.XmlBlasterException e) {
661 throw OrbInstanceFactory.convert(glob, e); // transform Corba exception to native exception
662 } catch(Throwable e) {
663 throw new XmlBlasterException(glob, ErrorCode.COMMUNICATION_NOCONNECTION, ME, "unSubscribe", e);
664 }
665 }
666
667
668 /**
669 * Publish fault-tolerant the given message.
670 * <p />
671 * This is a wrapper around the raw CORBA publish() method
672 * If the server disappears you get an exception.
673 * This call will not block.
674 * <p />
675 * Enforced by I_XmlBlasterConnection interface (failsafe mode)
676 * @see <a href="http://www.xmlBlaster.org/xmlBlaster/src/java/org/xmlBlaster/protocol/corba/xmlBlaster.idl" target="others">CORBA xmlBlaster.idl</a>
677 */
678 public final String publish(MsgUnitRaw msgUnit) throws XmlBlasterException {
679 if (log.isLoggable(Level.FINER)) log.finer("Publishing ...");
680 try {
681 return getXmlBlaster().publish(OrbInstanceFactory.convert(msgUnit));
682 } catch(org.xmlBlaster.protocol.corba.serverIdl.XmlBlasterException e) {
683 if (log.isLoggable(Level.FINE)) log.fine("XmlBlasterException: " + e.getMessage());
684 throw OrbInstanceFactory.convert(glob, e); // transform Corba exception to native exception
685 } catch(Throwable e) {
686 throw new XmlBlasterException(glob, ErrorCode.COMMUNICATION_NOCONNECTION, ME, "publish() failed", e);
687 }
688 }
689
690
691 /**
692 * @see <a href="http://www.xmlBlaster.org/xmlBlaster/src/java/org/xmlBlaster/protocol/corba/xmlBlaster.idl" target="others">CORBA xmlBlaster.idl</a>
693 */
694 public String[] publishArr(MsgUnitRaw [] msgUnitArr) throws XmlBlasterException
695 {
696 if (log.isLoggable(Level.FINER)) log.finer("publishArr() num of Entries: " + msgUnitArr.length);
697 try {
698 return getXmlBlaster().publishArr(OrbInstanceFactory.convert(msgUnitArr));
699 } catch(org.xmlBlaster.protocol.corba.serverIdl.XmlBlasterException e) {
700 if (log.isLoggable(Level.FINE)) log.fine("XmlBlasterException: " + e.getMessage());
701 throw OrbInstanceFactory.convert(glob, e); // transform Corba exception to native exception
702 } catch(Throwable e) {
703 throw new XmlBlasterException(glob, ErrorCode.COMMUNICATION_NOCONNECTION, ME, "publishArr", e);
704 }
705 }
706
707 /**
708 * @see <a href="http://www.xmlBlaster.org/xmlBlaster/src/java/org/xmlBlaster/protocol/corba/xmlBlaster.idl" target="others">CORBA xmlBlaster.idl</a>
709 */
710 public void publishOneway(MsgUnitRaw[] msgUnitArr) throws XmlBlasterException {
711 if (log.isLoggable(Level.FINER)) log.finer("publishOneway() ...");
712 try {
713 getXmlBlaster().publishOneway(OrbInstanceFactory.convert(msgUnitArr));
714 } catch(Throwable e) {
715 throw new XmlBlasterException(glob, ErrorCode.COMMUNICATION_NOCONNECTION, ME, "publishOneway", e);
716 }
717 }
718
719 /**
720 * @see <a href="http://www.xmlBlaster.org/xmlBlaster/src/java/org/xmlBlaster/protocol/corba/xmlBlaster.idl" target="others">CORBA xmlBlaster.idl</a>
721 */
722 public final String[] erase(String xmlKey, String qos) throws XmlBlasterException {
723 if (log.isLoggable(Level.FINER)) log.finer("erase() ...");
724 if (xmlKey==null) xmlKey = "";
725 if (qos==null) qos = "";
726 try {
727 return getXmlBlaster().erase(xmlKey, qos);
728 } catch(org.xmlBlaster.protocol.corba.serverIdl.XmlBlasterException e) {
729 throw OrbInstanceFactory.convert(glob, e); // transform Corba exception to native exception
730 } catch(Throwable e) {
731 log.severe("IO exception: " + e.toString() + " sessionId=" + this.sessionId);
732 throw new XmlBlasterException(glob, ErrorCode.COMMUNICATION_NOCONNECTION, ME, "erase", e);
733 }
734 }
735
736
737 /**
738 * @see <a href="http://www.xmlBlaster.org/xmlBlaster/src/java/org/xmlBlaster/protocol/corba/xmlBlaster.idl" target="others">CORBA xmlBlaster.idl</a>
739 */
740 public final MsgUnitRaw[] get(String xmlKey, String qos) throws XmlBlasterException {
741 if (log.isLoggable(Level.FINER)) log.finer("get() ...");
742 try {
743 return OrbInstanceFactory.convert(glob, getXmlBlaster().get(xmlKey, qos));
744 } catch(org.xmlBlaster.protocol.corba.serverIdl.XmlBlasterException e) {
745 throw OrbInstanceFactory.convert(glob, e); // transform Corba exception to native exception
746 } catch(Throwable e) {
747 throw new XmlBlasterException(glob, ErrorCode.COMMUNICATION_NOCONNECTION, ME, "get", e);
748 }
749 }
750
751 /**
752 * Register a listener for to receive information about the progress of incoming data.
753 * Only one listener is supported, the last call overwrites older calls. This implementation
754 * does nothing here, it just returns null.
755 *
756 * @param listener Your listener, pass 0 to unregister.
757 * @return The previously registered listener or 0
758 */
759 public I_ProgressListener registerProgressListener(I_ProgressListener listener) {
760 log.fine("This method is currently not implemeented.");
761 return null;
762 }
763
764 /**
765 * @see <a href="http://www.xmlBlaster.org/xmlBlaster/src/java/org/xmlBlaster/protocol/corba/xmlBlaster.idl" target="others">CORBA xmlBlaster.idl</a>
766 * @see org.xmlBlaster.client.protocol.I_XmlBlasterConnection#ping(String)
767 */
768 public String ping(String qos) throws XmlBlasterException {
769 if (this.xmlBlaster == null && this.authServer != null) {
770 return this.authServer.ping(qos); // low level ping without having connect() to xmlBlaster
771 }
772
773 try {
774 return getXmlBlaster().ping(qos);
775 } catch(Throwable e) {
776 throw new XmlBlasterException(glob, ErrorCode.COMMUNICATION_NOCONNECTION, ME, "ping", e);
777 }
778 }
779
780 /**
781 * Command line usage.
782 * <p />
783 * These variables may be set in xmlBlaster.properties as well.
784 * Don't use the "-" prefix there.
785 */
786 public static String usage()
787 {
788 String text = "\n";
789 text += "CorbaConnection 'IOR' options:\n";
790 text += " -bootstrapHostname <hostname or IP>\n";
791 text += " The host where to find xmlBlaster internal HTTP IOR download [localhost]\n";
792 text += " -bootstrapPort <port>\n";
793 text += " The bootstrap port where xmlBlaster publishes its IOR [" + Constants.XMLBLASTER_PORT + "]\n";
794 text += " -dispatch/connection/plugin/ior/iorString <IOR:00459...>\n";
795 text += " The IOR string from the running xmlBlaster server.\n";
796 text += " -dispatch/connection/plugin/ior/iorFile <fileName>\n";
797 text += " A file with the xmlBlaster IOR.\n";
798 text += " -dispatch/connection/plugin/ior/useNameService <true/false>\n";
799 text += " Try to access xmlBlaster through a naming service [true]\n";
800 text += " -dispatch/callback/plugin/ior/hostname <ip>\n";
801 text += " Allows to set the callback-server's IP address for multi-homed hosts.\n";
802 text += " -dispatch/callback/plugin/ior/port <port>\n";
803 text += " Allows to set the callback-server's port number.\n";
804 text += " For JacORB only:\n";
805 text += " java -DOAIAddr=<ip> Use '-dispatch/callback/plugin/ior/hostname'\n";
806 text += " java -DOAPort=<nr> Use '-dispatch/callback/plugin/ior/port'\n";
807 text += " java -Djacorb.log.default.verbosity=3 Switch CORBA debugging on\n";
808 text += " java ... -ORBInitRef NameService=corbaloc:iiop:localhost:7608/StandardNS/NameServer-POA/_root\n";
809 text += " java -DORBInitRef.NameService=corbaloc:iiop:localhost:7608/StandardNS/NameServer-POA/_root\n";
810 text += "\n";
811 return text;
812 }
813 } // class CorbaConnection
syntax highlighted by Code2HTML, v. 0.9.1