3

I've got some Java code that uses the Java Domino API (using the NCSO.jar) to connect with Domino databases over IIOP. A new requirement now is that if the server being connected to is clustered, it should be possible to take advantage of this and switch to a failover server in the cluster should the one currently connected to fail.

Unfortunately the Domino Java API is downright arcane, with subtle differences between using the API locally and remotely over IIOP, few really clear explanations and weird differences depending on the arguments that you feed the methods.

Some information I managed to glean from here... Does the openWithFailoverMethod work?

I've also checked the documentation on the IBM infocenter.

First thing I tried was this:

Session session = NotesFactory.createSession(host + ":" + port, user, password);
Database db = session.getDatabase(null, databaseName, false);
db.openWithFailover(host, databaseName);

The first argument of getDatabase, the server name, apparently must be null for IIOP operations. I was rather mystified by how it would be necessary to specify the server name again in the openWithFailover method when it's already in the session, but I suppose you can connecto to a cluster with the session and then specify the primary server in the open method. Why you needed to provide a database name twice wasn't quite clear, however. That last argument states the database should not be created if it can't be accessed (omit that and it's default true; how wonderful).

Unfortunately this spat the exception NotesException: This database object is already open as E:\Lotus\Domino\data\mail-in\EDITEST.nsf in my face. It occurs on the line with the openWithFailover method.

So apparently that first call to getDatabase already opens it, and there's no close method or an option to only get the object without actually opening it. The Database class is an interface, so no static methods to obtain such an object or a way of instantiating it otherwise. I checked around and the only alternative I find is using openDatabase in class DbDirectory. Guess what that does. Now that method does have an alternative with a boolean that states if you wish to use failover, but according to the documentation it is always false for IIOP oprations.

According to this page, you can get an empty Database object by calling getDatabase with two null arguments. So I tried this:

Session session = NotesFactory.createSession(host + ":" + port, user, password);
Database db = session.getDatabase(null, null, false);
db.openWithFailOver(host, databaseName);

Which prompty gives me exception NotesException: A database name must be provided. Changing the second line to Database db = session.getDatabase(null, null); doesn't make a difference.

I can only assume that a database name is mandatory for remote operations? But then how can failover be used at all when connecting remotely? Or am I doing this incorrectly? Maybe I should connect to the cluster instead of the server itself and the failover gets handled automatically? Or is failover plainly impossible for remote connections? The Notes client can do it, so I'd expect it to be possible in your own Java code.

Somebody please help me out here, because the documentation just doesn't provide enough info.

G_H
  • 11,739
  • 3
  • 38
  • 82
  • P.S.: I've tried `Database db = session.getDbDirectory(null).openDatabase(databaseName);` to see if I could actually connect without failover, and that works fine. – G_H Jan 16 '13 at 16:30

1 Answers1

6

There's nothing wrong with the API. It's simply the case that cluster failover in Lotus Notes and Domino is designed for Domino's proprietary network protocol (NRPC). The Notes client uses NRPC. That's why it can do failover. Java code that uses notes.jar instead of NCSO.jar can do it, too, because it also uses NRPC -- and some under-the-covers Notes client config info.

But it is not going to work with NCSO.jar, because that's using IIOP.

Here's why this is the case. In general, standard protocols don't know anything about any type of clustering. Solutions for clustering those standard protocols pretty much all rely on some sort of high-availability network device to direct traffic to the various servers in the cluster. But unlike clustering solutions for standard protocols, Domino clustering works without any external load balancer/failover device on the network. So if the Domino server is in a cluster, but it's not responding, how does the Notes client know the address of another server to fail over to? There's no traffic-cop device to talk to, and it obviously can't ask the server because it's not responding. So it has to look at configuration information that has already been stored locally to tell it what other servers with replicas of the target database are available! That information is maintained by the Notes core DLLs that are part of the Notes client installation, so you have to have the Notes client installed for it to have any chance of working. But when you are using NCSO.jar, there is no assumption that there is a local Notes client. Even if you do have a Notes client installed, NCSO.jar is unaware of it. So there's no way for the IIOP-based Notes Java API classes to know where to look up any information about the available servers in the Domino cluster.

There is something called Domino Internet Cluster Manager that works for Domino HTTP failover, but I don't think that supports IIOP either. I'm not sure about that, though, so you might want to look into it. But I think that if you want IIOP failover, you will probably have to add a 3rd party load balance/clustering solution to your network. The good news there, though, is that you probably won't need any special APIs to take advantage of that. Or, if you don't have a clustering solution that supports IIOP on your network and you can't add one, then you can just program your code to work with multiple servers. Write your code so that instead of just having one server name/address programmed into it, it has several, and try opening your database on them in order until you succeed.

Richard Schwartz
  • 14,463
  • 2
  • 23
  • 41
  • Superb answer! Too bad that clustering over remote connections isn't possible here, but at least now I'm no longer on a wild goose chase. I guess the easiest thing for me to do now is allow a failover server to be specified and connect to that in case of failure. Thank you! – G_H Jan 16 '13 at 17:28
  • 1
    You're welcome. I see, by the way, that you had found my blog post about the problem I had with openWithFailover. Just as an FYI, here's a link to the follow-up post that explained what I was doing wrong! http://www.poweroftheschwartz.com/web/blog/poweroftheschwartz.nsf/d6plinks/RSCZ-8J34PJ It turns out that when OpenWithFailover checks the local configuration information to find which servers have replicas of the database, an extra backslash in the filename causes the lookup to fail! – Richard Schwartz Jan 16 '13 at 17:34
  • I had seen that in the comments on the first post, indeed. Wrong filenames have bitten me too in the past. – G_H Jan 16 '13 at 17:36
  • Thinking about this further, one could wrap the NCSO.jar NotesFactory class, and the wrapper class could open its own session to the Domino server and pull down some cluster configuration info (you could create your own IIOPCluster.nsf database on the server to configure the server names/IPs, or you could figure it out from the existing Domino cluster configuration) and store it locally. On subsequent connection attempts using openWithFailover, the wrapper class could detect failures, read the previously retrieved config info, and try the other server. Maybe a project for the future. :-) – Richard Schwartz Jan 17 '13 at 19:24
  • We're using connectors within some sort of programmable framework, which includes a try-catch mechanism. Basically I could just have a connection with the primary server in the try and one with an alternative in the catch. Minimal work, and since there's only two servers in this cluster and it's only really being used in two places throughout our config, it'll do. Not as advanced as your suggestion, but functionally it'll kind of come down to the same. – G_H Jan 17 '13 at 19:37