Thursday, November 02, 2023

Configuring Entitlement Tracking in Domino 12

In the realm of HCL Domino Server 12.0, the feature of "Entitlement Tracking" has become a vital component for organizations.

While comprehensive information regarding Entitlement Tracking is available through HCL, I needed to know some practical management aspects, such as disabling the feature and adjusting intervals etc.

Disabling Entitlement Tracking:

To disable entitlement tracking, add the following entry and restart the server:

DISABLE_ENTITLEMENT_TRACKING=1

Debugging for Entitlement Tracking Issues:

Debug settings can be incredibly useful for troubleshooting any issues related to Entitlement Tracking. Here's how to configure debugging options:

DEBUG_ENTITLEMENT_AGGREGATOR_INTERVAL=60
DEBUG_UPDATE_ENTITLEMENT_TRACKING=2
ES_OPT_TIMING=1
DEBUG_DIRCAT=3

Hope that will help somebody.

Friday, October 27, 2023

Overcoming Domino's Agent Scheduling Limitations with JavaAddin

If you're frustrated with Domino's limitations on scheduling agents to run more frequently than once every 5 minutes, you're not alone. As a programmer, you understand the need for flexibility and control in your applications. In this article, we'll discuss a practical solution: creating a JavaAddin for Domino that can trigger agents at shorter intervals, allowing you to gain more fine-grained control over your scheduled tasks.

Understanding the Domino Agent Scheduler


Domino provides a robust environment for running scheduled agents. However, it imposes a minimum time gap of 5 minutes between consecutive runs of the same agent. This limitation can be a roadblock for applications that require more frequent execution.


The Power of JavaAddins


JavaAddins offer a way to extend Domino's functionality using Java code. This opens up a world of possibilities, including overcoming the 5-minute scheduling restriction. Here's how you can do it:

1. Setting Up Your JavaAddin

To get started, you'll need to create a JavaAddin. This involves writing Java code to interface with Domino. The code should enable you to trigger agents at shorter intervals than what Domino's native scheduling allows.

2. Utilizing Timers

One of the most effective ways to bypass the 5-minute limitation is to use timers in your JavaAddin. With timers, you can execute your agent at precise intervals, even down to seconds. Here's a simplified example of how this could look in your Java code:
import lotus.domino.*;
public class CustomScheduler extends JavaServerAddin {
    public void runNotes() {
        try {
            Session session = NotesFactory.createSession();
            Database database = session.getDatabase("", "YourDatabase.nsf");
            Agent agent = database.getAgent("YourAgent");

            // Set the execution interval in milliseconds
            int interval = 30000; // 30 seconds

            while (true) {
                agent.runWithDocumentContext(null);
                sleep(interval);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
This code defines a Java thread that runs your specified agent every 30 seconds, effectively bypassing Domino's 5-minute restriction.

3. Deploying Your JavaAddin

Once you've created your JavaAddin, you need to deploy it within your Domino environment. Ensure that the necessary permissions and access controls are in place.

4. Monitoring and Maintenance

Regularly monitor the execution of your custom scheduling solution. Ensure that it's working as expected and doesn't place undue stress on your Domino server.


Conclusion


By creating a JavaAddin for Domino that can trigger agents more frequently, you can take control of your scheduling needs. This solution empowers you to run your agents at shorter intervals, achieving the level of precision your applications require. While this approach requires some development effort, the benefits of fine-grained agent scheduling can greatly enhance your Domino-based applications.

In summary, if you're tired of being constrained by Domino's 5-minute scheduling limitation, consider the power of JavaAddins to break free and gain control over your scheduled agents.

I have also created a bit more advanced setup which you can get on github: DominoAgentsHelper 

Stay tuned for more technical insights, delivered directly to the point, in future articles.

Monday, September 25, 2023

Change Database ReplicaID programmatically

Here is a solution that change ReplicaId of NotesDatabase. Since native capabilities of LotusScript/Java classes do not allow such operation (at least yet), there is a way to do it using C Notes API. Our envrionment consists of both: Windows and Linux servers therefore I had to make a solution that cover both OS.

Declare

Public Const W32_LIB = {nnotes.dll}
Public Const LINUX_LIB = {libnotes.so}

Type TIMEDATE
	Innards(0 to 1) As Long
End Type

Type DBREPLICAINFO
	ID As TIMEDATE			'ID that is same for all replica files
	Flags As Integer		'Replication flags
	CutoffInterval As Integer	'Automatic Replication Cutoff
	Cutoff As TIMEDATE		'Replication cutoff date
End Type

Declare sub W32_OSCurrentTimeDate Lib W32_LIB Alias "OSCurrentTIMEDATE"(Ret As TIMEDATE)
Declare Function W32_NSFDbOpen Lib W32_LIB Alias "NSFDbOpen" (ByVal dbName As String, hdb As Long) As Integer
Declare Function W32_NSFDbClose Lib W32_LIB Alias "NSFDbClose" (ByVal hdb As Long) As Integer
Declare Function W32_NSFDbReplicaInfoGet Lib W32_LIB Alias "NSFDbReplicaInfoGet" (ByVal hdb As Long, hdbr As DBREPLICAINFO) As Integer
Declare Function W32_NSFDbReplicaInfoSet Lib W32_LIB Alias "NSFDbReplicaInfoSet" (ByVal hdb As Long, hdbr As DBREPLICAINFO) As Integer

Declare Sub LINUX_OSCurrentTimeDate Lib LINUX_LIB Alias "OSCurrentTIMEDATE"(Ret As TIMEDATE)
Declare Function LINUX_NSFDbOpen Lib LINUX_LIB Alias "NSFDbOpen" (ByVal dbName As String, hdb As Long) As Integer
Declare Function LINUX_NSFDbClose Lib LINUX_LIB Alias "NSFDbClose" (ByVal hdb As Long) As Integer
Declare Function LINUX_NSFDbReplicaInfoGet Lib LINUX_LIB Alias "NSFDbReplicaInfoGet" (ByVal hdb As Long, hdbr As DBREPLICAINFO) As Integer
Declare Function LINUX_NSFDbReplicaInfoSet Lib LINUX_LIB Alias "NSFDbReplicaInfoSet" (ByVal hdb As Long, hdbr As DBREPLICAINFO) As Integer

Code C API (main part of it)

'GET CURRENT TIMEDATE (TO BUILD NEW REPLICAID): OSCurrentTimeDate
If IS_WINDOWS Then
	Call W32_OSCurrentTimeDate(ReplicaID)
Else
	Call LINUX_OSCurrentTimeDate(ReplicaID)
End If
ReplicaInfo.ID = ReplicaID
	
'SET NEW REPLICAID: NSFDbReplicaInfoSet
If IS_WINDOWS Then
	rc = W32_NSFDbReplicaInfoSet(hDb, replicaInfo)
Else
	rc = LINUX_NSFDbReplicaInfoSet(hDb, replicaInfo)
End If

You can find all solution on GitHub: DominoChangeDatabaseReplicaID

Thursday, September 08, 2022

Java Freemarker with Domino

There are plenty of different Java template engines but for last years I used to stick to FreeMarker. It's open sourced and licensed under the Apache License, Version 2.0.

Here I only want to demonstrate how to integrate it with Domino nicely as it requires to write TemplateLoader class.

Build result based on tempalte "page"
Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
cfg.setDefaultEncoding("UTF-8");
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
cfg.setLogTemplateExceptions(false);

Get the template (uses cache internally)
DominoTemplateLoader dominoLoader = new DominoTemplateLoader(getDatabase());
cfg.setTemplateLoader(dominoLoader);

Template template = cfg.getTemplate("page");

/* Merge data-model with template */
HashMap tags = new HashMap();
tags.put("title", "hellow world");
tags.put("description", "Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit.");
			
Writer out = new StringWriter();
template.process(tags, out);
String html = out.toString();
The most important part was actually to build DominoTemplateLoader class and below you can see it
public class DominoTemplateLoader implements TemplateLoader {
	private View m_view;

	public DominoTemplateLoader(Database database) throws NotesException {
		m_view = database.getView("($Template)");
	}

	public void closeTemplateSource(Object templateSource) throws IOException {
		Document doc = (Document) templateSource;
		try {
			doc.recycle();
		} catch (NotesException e) {
			e.printStackTrace();
		}
	}

	public Object findTemplateSource(String id) throws IOException {
		try {
			return m_view.getDocumentByKey(id, true);
		} catch (NotesException e) {
			e.printStackTrace();
		}

		return null;
	}

	public long getLastModified(Object templateSource) {
		Document doc = (Document) templateSource;

		try {
			return doc.getLastModified().toJavaDate().getTime();
		} catch (NotesException e) {
			e.printStackTrace();
		}

		return 0;
	}

	public Reader getReader(Object templateSource, String encoding) throws IOException {
		if (templateSource == null) return null;
		
		Document doc = (Document) templateSource;
		try {
			return doc.getFirstItem("Body").getReader();
		} catch (NotesException e) {
			e.printStackTrace();
		}
		return null;
	}
}
As you can see the Loader class get document form a view and simply get data from item Body.

Friday, December 10, 2021

Journalize email from Exchange to Domino using Addin

One of my customer moves to Office 365 and also wants to move to to Exchange/Outlook 356 during next year while keeping Domino app running as it is of now.

They have customized mail boxes with few actions which allow to journalize emails into their Domino applications and that is quite critical functionality so that would need to be mirrored.

We have decided to built Outlook Add-in (works in web, client and also with mobile devices).

Here are a few advises to those who would need to developer similar functionality.

1. Create a outlook add-in project and define manifest

You would have to create a project with manifest and needed html, css, js elementets. You can easily find information how to do that on MS sites (not going to provide any links as they could change in future). That will allow you to define UI, see my example.


2. Send memo ID to Domino

We need to get information about email from Outlook Add in and send those items to Domino (you would have to build REST API on Domino side that can receive data from Outlook).

Office.context.mailbox.getCallbackTokenAsync(function(result) {

  ...

  var token = result.value;
  var ewsurl = Office.context.mailbox.restUrl;
  var ewsItemId = Office.context.mailbox.item.itemId;
  const itemId = Office.context.mailbox.convertToRestId(ewsItemId,Office.MailboxEnums.RestVersion.v2_0);

  // send token, ewsurl and itemId to Domino endpoint
  ...

}

Having those keys (token url and itemId) you can pull email in Mime format

3. Convert Mime to Notes email

So at this point Domino received data from Add in and can finally do another request to Exchange server (using token, ewsurl and itemId) to read the memo MIME

Dim http As NotesHTTPRequest
Dim enpoint As string
		
Set http = m_app.NotesSession.Createhttprequest()
Call http.Setheaderfield("Authorization", "Bearer " + token)
enpoint = ewsurl + |/v2.0/me/messages/| + itemId + |/$value|
		
getItemMIME = http.get(enpoint)

There is no native Domino LS/Java Mime Parser however I found working example by Stephan: Importing EML files into Notes (lots of them). It worked well, but seems it does not handle inline images (need to do more testing etc).

Alternatively I was told that there is MimeMessageParser.java that writes MIME to a Notes document. This class is part of the XPages Extension Library. So it has sense to compare them.