ShowTable of Contents
Introduction
Release 8.5.2 introduces a new API for Agents to allow them run with a Document context that can be set by the caller, either an outer Agent or an XPage.
The Agent.runWithDocumentContext() API runs an agent and passes a saved or unsaved in-memory document to the DocumentContext property of the called agent:
New Agent.run APIs
The new APIs are :
JavaScript (XPages) |
Agent.runWithDocumentContext(doc:NotesDocument) : void |
Agent.runWithDocumentContext(doc:NotesDocument, noteID:string) : void |
Java |
public void Agent.runWithDocumentContext(Document doc) |
public void Agent.runWithDocumentContext(Document doc, String noteID) |
LotusScript |
NotesAgent.RunWithDocumentContext(doc As NotesDocument, noteID As String) As Integer |
Getting the In-Memory Document
The called agent can access the in-memory document via the existing API for accessing an in-memory document context. For example
Java |
public Document AgentContext.getDocumentContext()
|
LotusScript |
Dim doc As NotesDocument
Set doc = NotesSession.DocumentContext
|
The document can be updated within the agent and when control returns to the XPage the updated values can be read from the document.
Run as Web user
Note: Domino Server-based Agent code must run in an Agent with "Run as Web user" selected on the Security tab under Properties.
Supported Configurations
The following table shows the supported scenarios in which the new Agent.runWithDocumentContext() API is allowed to run.
Caller | Inner Agent | Supported |
XPage on Client | | Allowed |
XPage on Server (run as user) | Run as Web User | Allowed |
XPage on Server (run as user) | Run as Agent signer | Disallowed |
XPage on Server (run as Agent signer) | | Disallowed |
Agent on Client (foreground) | | Allowed |
Agent on Client (background, from UI) | | Allowed |
Agent on Client(background, scheduled) | | Disallowed |
Agent on Web Run as Agent Signer | | Disallowed |
Agent on Web Run as Web User | | Allowed |
The in-memory doc will have recent unsaved updates made by the inner agent visible to the outer agent, and vice versa.
Example
The following is an example of an XPages application calling a Java agent.
-
left-hand-side, passing parameters via a profile document
-
right-hand-side, passing parameters using a profile document
Notice the code is a lot simpler and clearer using an in-memory document.
ServerSide JavaScript |
Document NoteID Parameter Passing | In-Memory Document Context |
var agentName:String = "jaParamDoc";
var compInput = getComponent("comboBox1");
var compOutput = getComponent("inputText1");
get the input parameter
var input = compInput.getValue();
var output = "None";
create a profile doc for parameter passing
var uuid = "ParameterPassing" + java.lang.System.currentTimeMillis();
var doc = database.getProfileDocument("ParameterPassing",uuid);
set the input parameter and save
doc.replaceItemValue("Input",input);
doc.replaceItemValue("ReplyID",uuid);
doc.save(true);
get the NoteID
var noteID = doc.getNoteID();
var agent:NotesAgent = database.getAgent(agentName);
if (agent != null) {
agent.run(noteID);
get the reply profile document
var reply:lotus.domino.Document = database.getProfileDocument("ResultPassing",uuid);
get the output
if (reply.hasItem("Rating")){
output = reply.getItemValueString("Rating");
} else {
output="Error (hasItem)";
}
compOutput.setValue(output);
cleanup - remove reply profile doc
reply.remove(false);
} else {
compOut.setValue("Can not find Java Agent");
}
|
var agentName:String = "jaInMemory";
var compInput = getComponent("comboBox1");
var compOutput = getComponent("inputText1");
get the input parameter
var paramIn = compInput.getValue();
create In Memory Document
var doc = database.createDocument();
doc.appendItemValue("Input",paramIn);
var agent:NotesAgent = database.getAgent(agentName);
if (agent != null) {
agent.runWithDocumentContext(doc);
compOutput.setValue(doc.getItemValueString("Rating"));
doc.recycle();
} else {
compOut.setValue("Can not find Java Agent");
}
|
Java Agent Code |
Document NoteID Parameter Passing | In-Memory Document Context |
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
(Your code goes here)
populatePresidents();
Database db = agentContext.getCurrentDatabase();
Agent agent = agentContext.getCurrentAgent();
String input, replyid, rating;
String docId = "";
docId = agent.getParameterDocID();
if (!docId.equalsIgnoreCase("")) {
Document doc = db.getDocumentByID(docId);
input = doc.getItemValueString("Input");
replyid = doc.getItemValueString("ReplyID");
rating = "Not Found";
if (presidents.get(input) != null) {
rating = (String)presidents.get(input);
}
create new reply profile document to return the output
doc.remove(true);
Document reply = db.getProfileDocument("ResultPassing",replyid);
reply.replaceItemValue("Rating", rating);
if (!reply.save(true)){
System.out.println("Document not saved in agent.");
}
} else {
System.out.println("Can't find ParameterDocId");
}
} catch(Exception e) {
e.printStackTrace();
}
}
|
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
(Your code goes here)
populatePresidents();
Document doc = agentContext.getDocumentContext();
String input =doc.getItemValueString("Input");
String rating = "Not Found";
if (presidents.get(input) != null) {
rating = (String)presidents.get(input);
}
doc.replaceItemValue("Rating", rating);
} catch(Exception e) {
e.printStackTrace();
}
}
|
Troubleshooting Common Errors
Some common agent errors and solutions.
Unsupported Trigger Error
Unsupported trigger and search in the background or embedded agent
Caused by: NotesException: Could not execute macro:
Unsupported trigger and search in the background or embedded agent
at lotus.domino.local.Agent.run(Agent.java:85)
at com.ibm.xsp.script.DominoHelper$2.run(DominoHelper.java:85)
at java.security.AccessController.doPrivileged(AccessController.java:251)
at com.ibm.xsp.script.DominoHelper.run(DominoHelper.java:82)
at com.ibm.xsp.script.WrapperDomino$fct_Agent.call(WrapperDomino.java:3511)
Unsupported Trigger Solution
In the Basic section of the Properties tab for the Agent, set Target to None.
For example,
Caller must run with user authority Error
Unable to pass doc context - Caller must run with user authority
Caused by: NotesException: Unable to pass doc context - Caller must run with user authority
at lotus.domino.local.Agent.NrunWithDocumentContext(Native Method)
at lotus.domino.local.Agent.runWithDocumentContext(Agent.java:95)
at com.ibm.xsp.script.WrapperDomino$fct_Agent.call(WrapperDomino.java:3535)
... 44 more
Caller must run with user authority Solution
In the Security section of the Properties tab for the Agent, ensure "Run as Web user" is selected.
For example,