Home for HMNL Enterprise Computing

Manageable Extensions in Domino

Ian Tree  08 May 2012 10:11:36

Domino Extensions


The Domino Extension Manager (and DSAPI) functionality can be extremely useful, it provides a mechanism for intercepting NSF calls in the Domino Server or Notes Client. The code of an Extension Manager runs as a part of the Server or workstation and can perform low-level manipulation of a wide range of Domino functions. Because the Extension Manager code is loaded and unloaded as part of the Server or Workstation core functionality they tend to be very rigidly constructed and configured only through changes to their code. The following presents a model for constructing an Extension Manager that is dynamically configurable and controllable and sharing common code paths between an Extension Manager and a DSAPI.

Design Pattern

The Domino Extension Manager is constructed following the usual pattern, except, all control and configuration variables are stored in a shared memory segment in the DLL and are exposed through a series of additional entry points in the DLL so that they can be read and written to. A Server AddIn task is written that manipulates all of the control and configuration settings on-demand, via calls to the DLL entry points. Using this pattern functionality in the extension manager can be enabled, disabled and re-configured at any time without even restarting the Domino Server.

Simple eh! A little more detail follows.

1. Dynamically Configurable and Controllable Extension Manager and DSAPI Modules

Extension Manager and DSAPI modules are implemented in Domino as DLL's (Shared Libraries in UNIX). These are usually coded in a quite rigid manner often with all of the variable environmental data hard-coded in the DLL. This rigid pattern does not meet the needs for the XAM implementation where a set of filter rules needs to be dynamically changed. It is also useful to be able to modify the operating state of such modules on-the-fly, traditionally this involves changing ini settings and restarting the HTTP task or the entire server.

Design Pattern

a. The Extension Manager or DSAPI DLL is implemented along with a "paired" controller add-in task.

b. All stateful control variables in the DLL are implemented as static variables in a shared data segment, this ensures that all copies of the DLL loaded into different processes all access a common set of control variables.

NOTE: all static variables in the shared data segment MUST have an initial value assigned, this forces the addresses to be fixed in the shared data segment at compile time.

c. The DLL exposes access to the shared control variables to the Add-In task through a collection of public getter and setter functions.

d. Control variables that have a variable memory size requirement should be set in memory allocated through Domino and marked as shared. The address of these memory areas are stored in the static shared memory segment used by the DLL.

e. The Add-In can now detect necessary state or configuration changes through console commands or changes in the content of a configuration database and reflect these changes in the state or configuration of the DLL by using the appropriate setter functions in the DLL.

2. Common Logic for Extension Manager and DSAPI Modules

With the increasing emphasis on web enabling applications special logic that is deployed through an Extension Manager may also need to be implemented in the web access path i.e. in a DSAPI, this is the case with XAM. In cases where this duality is necessary it would be preferable to implement the logic in a shared code path.

Design Pattern

a. There is no conflict between the entry points through which an Extension Manager and a DSAPI are invoked, therefore, it is possible for Extension Manager and DSAPI functionality to coexist in the same DLL.

b. Implement the core logic underlying the Extension Manager and DSAPI functionality as private functions in the DLL, map calls to the invocation entry points in the extension manager and DSAPI into calls to the appropriate common private functions.