Slides for my siession at DNUG46 in Essen, Germany. 04.-05-MAY-2019.
The session was all about the new classes added in V10.x of Notes/Domino. FP2 changes are included.
8. IBM Domino Community Client
& Server (English only)
Type OS Description Size Part # Download
Client Windows IBM Notes Community Client for Non-Production
10.0.1 Windows English
IBMNotesDesignerAdminCommunityClientforNonProduction
10.0.1Windows.exe
1 GB CNY0UEN Start HERE
Server Windows IBM Domino Community Server for Non-Production
10.0.1 Windows English
IBMDominoCommunityServerforNonProduction10.0.1Windo
ws.exe
665 MB CNXK0EN Start HERE
Server Linux IBM Domino Community Server for Non-Production
10.0.1 Linux English
IBMDominoCommunityServerforNonProduction10.0.1Linux.t
ar
791MB CNXK1EN Start HERE
14. New Classes in 10.0.0 and 10.0.1
• (Notes)DominoQuery class – DQL support from Lotusscript/Java
• parse, explain, execute queries
• (re)setNamedVariable – to address SQL Insertion security exposure
• (Notes)HTTPRequest – REST support from the Domino backend
• NotesJSON* – (Lotusscript only) to process JSON payloads
• (Notes)ViewEntryCollection intersect and substract methods has new
maintainOrder argument for sorted results
• (Notes)IdVault & (Notes)UserId ( also JavaScript )
17. LotusScript node.js
Public Class HttpRequestWrapper
Private m_session As NotesSession
Private m_url As String
Private m_class As String
Private m_json As String
Private m_httpRequest As NOTESHTTPREQUEST
%REM
Sub New
%END REM
Public Sub New()
Set m_session = New NotesSession
Set m_httpRequest = _
me.m_session.CreateHttpRequest()
m_httpRequest.preferStrings = True
m_url = BASE_URL_PORT
m_class = CLASS_CUSTOMER
End Sub
https://github.com/eknori/nodejs-restApi
18. .preferStrings = TRUE
• By DEFAULT, NotesHttpRequest returns variant content as JSON UTF8
byte array.
• Use the preferstrings property to return Unicode rather than UTF8
byte array.
21. .ResponseCode
Private Function getResponseCode() As String
getResponseCode = m_httpRequest.ResponseCode
End Function
https://www.assono.de/blog/http-status-code-200-oder-401-
fuer-login-seite-jetzt-haben-wir-die-wahl
DOMINO_FORCE401_WITH_HTML_LOGIN_PAGE=1
22. .getResponseHeaders
Private Function getResponseHeaders() As String
Dim vHeaders As Variant
Dim sHeaders As String
vHeaders = m_httpRequest.getResponseHeaders()
ForAll h In vHeaders
sHeaders = sHeaders+ CStr(h)_
+ Chr(10)+Chr(13)
End ForAll
getResponseHeaders = sHeaders
End Function
Returns Variant array of the response headers.
Each value contains the header field and value.
23. .setHeaderFields (Authentication)
Dim user As String
Dim password As String
user = "firstname.lastname@tld.de"
password = "#dominoforever"
Call httpReq.SetHeaderField("Authorization", "Basic" + _
EncodeBase64 (user + ":" + password))
24. .setHeaderFields (Authentication)
Function EncodeBase64 (StrIn As String) As String
Dim session As New NotesSession
Dim stream As NotesStream
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim body As NotesMIMEEntity
Set stream = session.CreateStream
Call stream.WriteText (StrIn)
Set db = session.CurrentDatabase
Set doc = db.CreateDocument
Set body = doc.CreateMIMEEntity
Call body.SetContentFromText (stream, "", ENC_NONE)
Call body.EncodeContent (ENC_BASE64)
EncodeBase64 = body.ContentAsText
Call stream.Close
Set doc = Nothing
End Function
http://blog.nashcom.de/nashcomblog.nsf/dx/domino
v10-http-requests-from-Lotus-Script.htm
Debug_NotesHTTPRequest=1
26. View JSON
URL = https://server/db.nsf/view?readviewentries&outputformat=JSON&Count=10000
without count parameter, only 30 items are returned
&Count=-1 to return ALL view entries
27. View JSON Sample
Dim session As New NotesSession
Dim httpreq As NotesHTTPRequest
Dim jsonNav as NotesJSONNavigator
Dim response as Variant
Set httpreq = session.CreateHTTPRequest()
response = httpreq.get("http://my.testapi.com/endpoint")
Set jsonNav = session.CreateJSONNavigator(response)
Dim jsonElem as NotesJSONElement
Set jsonElem = jsonNav.getFirstElement()
28. View JSON Sample
Dim session As New NotesSession
Dim httpreq As NotesHTTPRequest
Dim jsonNav as NotesJSONNavigator
Dim response as Variant
Set httpreq = session.CreateHTTPRequest()
response = httpreq.get("http://my.testapi.com/endpoint")
Set jsonNav = session.CreateJSONNavigator(response)
Dim jsonElem as NotesJSONElement
Set jsonElem = jsonNav.getFirstElement()
29. View JSON Sample
Dim session As New NotesSession
Dim httpreq As NotesHTTPRequest
Dim jsonNav as NotesJSONNavigator
Dim response as Variant
Set httpreq = session.CreateHTTPRequest()
response = httpreq.get("http://my.testapi.com/endpoint")
Set jsonNav = session.CreateJSONNavigator(response)
Dim jsonElem as NotesJSONElement
Set jsonElem = jsonNav.getFirstElement()
30. View JSON Sample (10.0.1 FP2)
Dim session As New NotesSession
Dim httpreq As NotesHTTPRequest
Dim jsonNav as NotesJSONNavigator
Set httpreq = session.CreateHTTPRequest()
httpreq.PreferJSONNavigator = True
Set jsonNav = httpreq.get("http://my.testapi.com/endpoint")
Dim jsonElem as NotesJSONElement
Set jsonElem = jsonNav.getFirstElement()
Technote: Limitations of NotesHTTPRequest and NotesJSONNavigator with future considerations https://www-
01.ibm.com/support/docview.wss?uid=ibm10875724
36. NotesJsonNavigator
• To create a new NotesJsonNavigator object, use
createNotesJsonNavigator.
Public Sub NotesJSONNavigator_1
Dim sesssion As New NotesSession
Dim jsnav As NotesJSONNavigator
Dim json As String
Set jsnav = session.CreateJsonNavigator(json)
End Sub
39. NSD – DEBUG_LS_DUMP=1
• https://www-01.ibm.com/support/docview.wss?uid=swg21499034
• When enabled, an NSD dump will include a LotusScript Interpreter
section, which shows a stack trace for all LotusScript that was running
at the time NSD was called, for all threads in all Notes/Domino
processes.
40. NotesJsonNavigator
• Tracked under SPR #DCONBB44T4
• Will be fixed in 10.0.1 FP2
• At least, check json string
Public Sub NotesJsonNavigator_1
Dim session As New NotesSession
Dim jsnav As NotesJsonNavigator
Dim json As String
If (json <> "") then
Set jsnav = session.CreateJsonNavigator(json)
End If
End Sub
41. NotesJSONNavigator (cont.)
Public Sub NotesJsonNavigator_2
Dim session As New NotesSession
Dim jsnav As NotesJSONNavigator
Dim json As String
json = |{"color": "black"}|
'json = |{"color1": "black","color2": "blue"}|
'json = |{"colors": {"color": "black","color": "blue"}}|
'json = |{"color": "white", "category": "value",
"code": {"rgba": [255,0,0,1],"hex": "#FFF"}}|
'json = |{"numbers:" : [1,2,3,4,5]}|
'json = |[1,2,3,4,5]|
If (json <> "") then
Set jsnav = session.CreateJSONNavigator(json)
End If
End Sub
42. NotesJsonNavigator ( 10.0.1 FP2 )
• SPR# DCONBB44T4 - LotusScript - Fixed a crash
when using Session.createJSONNavigator.
• SPR# DCONBB2KNR - LotusScript - Fixed a
problem in NotesJSONNavigator package
parsing when parsing empty strings.
Public Sub NotesJsonNavigator_1
Dim session As New NotesSession
Dim jsnav As NotesJsonNavigator
Dim json As String
Set jsnav = session.CreateJsonNavigator(json)
End Sub
43. NotesJSONNavigator (cont.)
• Issue with special characters in JSON
• Tracked under SPR# VRARB8WkPB.
• Will be fixed in an upcoming release ( not FP1 )
Public Sub NotesJsonNavigator_3
Dim s As New NotesSession
Dim jsnav As NotesJSONNavigator
Dim json As String
json = |{"device":"Apple iPad 2 with Wi-Fi - 16GB"}|
Set jsnav = s.CreateJSONNavigator(json)
json = |{"device":"Apple® iPad® 2 with Wi-Fi - 16GB"}|
Set jsnav = s.CreateJSONNavigator(json)
End Sub
46. NotesJSONNavigator (cont.)
• Issue with CRLF in JSON
• Tracked under SPR# ASHEB95LFR.
• Will be fixed in an upcoming release
Const colors2 = |{
"colors": [
{
"color": "black",
"category": "hue",
"type": "primary",
"code": {
"rgba": [255,255,255,1],
"hex": "#000"
}
},
{
"color": "white",
"category": "value",
"code": {
"rgba": [0,0,0,1],
"hex": "#FFF"
}
}
]
}|
47. NotesJSONNavigator (cont.)
• Workaround – remove CRLF
Public Function removeCRLF(json As String) As String
removeCRLF = Replace(Replace(json, Chr(13), ""),Chr(10),"")
End Function
Public Sub NotesJsonNavigator_1
Dim session As New NotesSession
Dim jsnav As NotesJSONNavigator
Dim json As String
json = removeCRLF(colors2)
Set jsnav = session.CreateJSONNavigator(json)
End Sub
48. NotesJSONNavigator 10.0.1 FP2
• SPR# ASHEB95LFR - LotusScript - Fixed a problem where
NotesJSONNavigator was unable to navigate a string which contained
new lines and carriage returns.
49. NotesJSONNavigator (cont.)
• Issue with JSON larger than 64k
• Tracked under SPR# DCONB8VMAV
• Will be fixed in an upcoming release
public Sub streamBigJson()
Dim session As New NotesSession
Dim jsnav As NotesJSONNavigator
Dim stream As NotesStream
Dim fileName As String
fileName = "c:Tempbig.json“
Set stream = session.CreateStream
stream.Position = 0
Set jsnav = session.CreateJSONNavigator(stream.ReadText)
Call stream.Close
End Sub
50. NotesJSONNavigator 10.0.1 FP2
• SPR# DCONB8VMAV - LotusScript - Fixed a problem where
NotesJSONNavigator was unable to parse json content that was
greater than 64K.
51. .getNthElement(index)
Public Sub jsonNavigatorGetNthElement
Dim s As New NotesSession
Dim jsnav As NotesJSONNavigator
Dim json As String
json = |[1,2,3,4,5]|
Set jsnav = s.CreateJSONNavigator(json)
Dim el As NotesJsonElement
Set el = jsnav.GetNthElement(4)
MsgBox "Nth element: " & el.Value
End Sub
52. .getElementByPointer()
• Retrieves a NotesJSONElement using JSON Pointer syntax* to identify
the element.
Public Sub jsonNavigatorGetElementByPointer()
Dim session As New NotesSession
Dim jsnav As NotesJSONNavigator
Dim el As NotesJSONElement
Set jsnav = session.CreateJSONNavigator(_
|{"color": "white", "cat":"ls","code": {"rgb": [255,0,0,1],"hex": "#FFF"}}|)
Set el = jsnav.GetelementByPointer("/cat")
MsgBox "cat: " + el.Value'
Set el = jsnav. GetelementByPointer("/code/hex")
MsgBox "hex: " + el.Value
Set el = jsnav. GetelementByPointer("/code/rgb/3")
MsgBox "code/rgb/3: " + el.Value
End Sub
* https://www.baeldung.com/json-pointer
53. NotesJSONArray.getNthElement
„We have documented this bug under SPR #SKSWB89MGH and are currently working on the solution.“ HCL Support.
Public Sub jsonArrayNthElement()
Dim s As New NotesSession
Dim jsnav As NotesJSONNavigator
Dim el As NotesJSONElement
Dim arr As NotesJSONArray
Set jsnav = s.CreateJSONNavigator(|{"numbers:" : [1,2,3,4,5]}|)
Set el = jsnav.GetFirstElement()
Set arr = el.value
MsgBox "Nth element: " & CStr(arr.GetNthElement(4).value)
End Sub
55. NotesJSONArray.Size()
Public Sub jsonArraySize()
Dim s As New NotesSession
Dim jsnav As NotesJSONNavigator
Dim el As NotesJsonElement
Dim arr As NotesJsonArray
Set jsnav = s.CreateJSONNavigator(|{"numbers:" : [1,2,3,4,5]}|)
Set el = jsnav.GetFirstElement()
Set arr = el.value
MsgBox "Size: " & CStr(arr.Size())
End Sub
60. Getter / Setter in LS & Java (Workaround)
• Put the following entries into the server notes.ini.
sh con QUERY*
[0C38:0009-0ADC] QUERY_MAX_DOCS_SCANNED=13000000
[0C38:0009-0ADC] QUERY_MAX_VIEW_ENTRIES_SCANNED=13000000
• The notes.ini settings are never used for property values in the LS classes.
However, the user can easily get the value from a call to
Session.getEnvironmentValue. ( John Curtis )
• getter / setter not showing DEFAULT = SPR #JCUSB8HQ36
61. Getter / Setter in LS 10.0.1 FP2
• SPR# JCORB7ENX8 - DQL: Fixed a problem where DominoQuery class
allowed for only a small number of Documents or View Entries to be
scanned. Now MaxScanDocs and MaxScanEntries properties are
Longs, allowing for many more
62.
63. DesignHarvest
• Programmatically update the DQL Design Catalog
• NSFDesignHarvest is undocumented and maybe changed. Use at own
risk.
Public Const UPDATE_DESIGN_CATALOG = 0
Public Const ADD_TO_DESIGN_CATALOG = 1
Declare Function NSFDesignHarvest (ByVal hDb As Long, ByVal flag As Long) As Integer
64. DesignHarvest – LS2CAPI
‘DECLARATIONS
Public Const UPDATE_DESIGN_CATALOG = 0
Public Const ADD_TO_DESIGN_CATALOG = 1
Const NNOTES ="nnotes.dll"
Const LIBNOTES ="libnotes.so"
Declare Public Function WIN_NSFDbOpen Lib NNOTES Alias "NSFDbOpen" _
(ByVal dbName As String, hDb As Long) As Integer
Declare Public Function LIN_NSFDbOpen Lib LIBNOTES Alias "NSFDbOpen" _
(ByVal dbName As String, hDb As Long) As Integer
Declare Public Function WIN_NSFDbClose Lib NNOTES Alias "NSFDbClose" _
(ByVal hDb As Long) As Integer
Declare Public Function LIN_NSFDbClose Lib LIBNOTES Alias "NSFDbClose" _
(ByVal hDb As Long) As Integer
Declare Public Function WIN_NSFDesignHarvest Lib NNOTES Alias "NSFDesignHarvest" _
(ByVal hDb As Long, ByVal flag As Long) As Integer
Declare Public Function LIN_NSFDesignHarvest Lib LIBNOTES Alias "NSFDesignHarvest" _
(ByVal hDb As Long, ByVal flag As Long) As Integer
65. DesignHarvest – LS2CAPI (cont.)
Function NSFDBClose (hDb As Long)
If isDefined("WINDOWS") Then
NSFDbClose = WIN_NSFDbClose(hDb)
ElseIf isDefined("LINUX") Then
NSFDbClose = LIN_NSFDbClose(hDb)
End If
End Function
Function NSFDbOpen( db As String, hDB As Long) As Integer
If isDefined("WINDOWS") Then
NSFDbOpen = WIN_NSFDbOpen(db,hDb)
ElseIf isDefined("LINUX") Then
NSFDbOpen = LIN_NSFDbOpen(db,hDb)
End If
End Function
Function NSFDesignHarvest (hDb As Long, flag As long) As Integer
If isDefined("WINDOWS") Then
NSFDesignHarvest = WIN_NSFDesignHarvest(hDb, flag)
ElseIf isDefined("LINUX") Then
NSFDesignHarvest = LIN_NSFDesignHarvest(hDb, flag)
End If
End Function
66. DesignHarvest – LS2CAPI (cont.)
Public Function catalogDesign(sDb As String, flag As Long) As Integer
Dim hDb As Long
Dim rc As Integer
If flag > 1 Then flag = 1
If flag < 0 Then flag = 0
rc = NSFDbOpen(sDb, hDb)
If rc = 0 Then
rc = NSFDesignHarvest(hDb, flag)
rc = NSFDbClose(hDb)
End If
catalogDesign = rc
End Function
68. DQL Explorer
• Everything runs in a single .nsf
• Luis Guirigay and Andrew Manby introduce DQL Explorer at Think
2019: https://youtu.be/OMjSND5cPsE
• Scott Good provides a demo that includes some configurations
aspects not shown in the stage demo:
https://youtu.be/Cfw_6Wvk8c8
• The Web application relies on Domino Access Services (DAS) being
enabled on the dqlexplorer.nsf (default), but that means there is a
need to be enable DAS on your server.
72. DQL Explorer
• https://github.com/icstechsales/dql-explorer
• ANYONE can contribute
• Bug fixes
• Enhancements
• Documentation
• Forking – copying and changing
• EVERYONE benefits
• We NEED to show the power of Domino
• Support concerns, defects are a community thing
74. NotesViewEntryCollection
https://www.ibm.com/support/knowledgecenter/en/SSVRGU_10.0.1/basic/H_NOTESVIEWENTRYCOLLECTION_9327.html
NotesViewEntryCollection
…
intersect(Doc as Variant, maintainOrder as boolean)
substract(Doc as Variant, maintainOrder as boolean)
…
maintainOrder
(Optional) Boolean. Specifies that after the intersect / substract
operation is complete, whatever order the originating view was in
when the NotesEntryCollection was created will remain in force for
subsequent entry processing.
That is, either the default view order will be used or that last set by
calling ResortView.
intersect = Removes from a view entry collection any
entries whose associated documents are not also
contained in a second collection.
substract = Removes from a view entry collection any
entries whose associated documents are also contained
in a second collection.
77. NotesIdVault Wrapper class
• https://openntf.org/XSnippets.nsf/snippet.xsp?id=programmatic-
access-to-idvault-incl.-new-v10-methods-
• The code allows programmatic access to the IDVAULT. It uses the
NotesIdVault class ( new with 901 FP9 ) and also extends the class to
extract an ID from the vault without knowing its password.
• The code also includes new features that come with V10 to archive,
revert archived Ids and to delete Ids that have been archived to
reinforce sync.
78. .archiveIdFile ( sample code )
Public Sub archiveIdFile
Call me.resetError()
On Error GoTo catch
If (me.m_vault_doc Is Nothing) Then
Call me.getDocumentByKey(me.UserName)
If Not (me.m_vault_doc Is Nothing) Then
Dim idOwner As String
idOwner = TILDE + me.m_vault_doc.IdOwner(0)
me.m_vault_doc.idOwner = idOwner
Call me.m_vault_doc.Save(True, False)
Call me.m_vault_view.Refresh()
Else
Error ERR_DOC_ARCHIVE,_
ERR_DOC_NOT_FOUND_OR_ARCHIVED_MSG + OPERATION_CANCELLED_MSG
End If
End If
80. JavaScript
• @UserSecretKeys() Javascript function - This convenience function is
used to obtain secret keys from a user’s ID file.
• @UserId() Javascript function - This function is to return the UserID
object stored for a given user in the ID Vault.
81. Recommended reading
• Limitations of NotesHTTPRequest and NotesJSONNavigator with future
considerations - https://www-
01.ibm.com/support/docview.wss?uid=ibm10875724
• IBM Notes®/Domino® 10.0.1 Fix Pack 2 Release Notice May 28, 2019 -
http://www-
10.lotus.com/ldd/fixlist.nsf/da28c739cc5024e9852583da006659a7/3501674bb1c
8f1e0852584080063188b?OpenDocument
• IBM Notes®/Domino® 10.0.1 Fix Pack 1 Release Notice March 30, 2019 -
http://www-
10.lotus.com/ldd/fixlist.nsf/WhatsNew/b1df4042fb8a980c852583b40067a7be?O
penDocument
• Upgrading to IBM Notes and Domino 10.x - https://www-
01.ibm.com/support/docview.wss?uid=ibm10881219&aid=1
82. Recommended reading
• Daniel Nashed, AppDevPack Security Setup explained -
http://blog.nashcom.de/nashcomblog.nsf/dx/appdevpack-security-setup-
explained.htm
• Paul Withers, Domino App Dev Pack: Understanding Scopes -
https://www.intec.co.uk/domino-app-dev-pack-understanding-scopes/
• Oliver Busse, Domino, Proton, IAM, Oauth Part 1-4 -
https://oliverbusse.notesx.net/hp.nsf/blogpost.xsp?documentId=2FEA
• Heiko Voigt, Blog - https://www.sit.de/heikos-blog
• New features for developers in IBM Domino and Domino Designer 10.0.1 -
https://www-01.ibm.com/support/docview.wss?uid=ibm10737063
83.
84.
85. About: me
• Lotus Notes und Domino seit 1993
• Entwickler / Administrator
• IBM Champion 2010 – 2019
• OpenNTF Contributor
• Let‘s Encrypt 4 Domino ( LE4D )
• Entwickler bei midpoints GmbH
Notas del editor
SPR# DCONB8VMAV - LotusScript - Fixed a problem where NotesJSONNavigator was unable to parse json content that was greater than 64K.