出直し!! ヘルプ

連載中

連載 終了

2023/07/31

Project KEEP:Domino REST API アップグレードインストール

2023 年 7 月 14 日に Domino REST API 1.0.6 がリリースされました。

HCL Domino REST API リリース情報


以前、『Project KEEP 体験』で構築した環境は、1.0.5 でした。良い機会ですので、アップグレードする手順の確認をしてみました。


まずは、インストーラの準備です。

1.0.6 も 1.0.5 同様の形式で提供されていますので、Domino_REST_API_V1.0.6_Installer.tar.gz ファイルを入手し、解凍します。


続いて、アップグレード手順の情報収集です。

HCL Domino REST API Documentation の Installation and configuration セクションの Windows を確認してみました。

Install on Windows


Upgrade に関するセクションはなかったこと、ざっと見た感じ、以前参照したチュートリアルのインストール手順やオプションと大差ないと感じました。Domino サーバのように単純に上書きインストールでよいのではないかと考え、前回と同じコマンドでインストールしてみました。

>C:\Domino\jvm\bin\java -jar restapiInstall.jar -d="C:\Domino\Data" -i="C:\Domino\notes.ini" -p="C:\Domino" -r="C:\Domino\restapi" –a


LICENSE AGREEMENT が表示された後のログが、次の通りとなりました。

License accepted, determining installation type
7 30, 2023 11:12:21 午前 com.hcl.domino.keep.install.KeepInstaller returnInstallationType
情報: Installation type discovered: DOMINO_WINDOWS
Check if rest API directory exists or can be created
7 30, 2023 11:12:21 午前 com.hcl.domino.keep.install.KeepInstaller checkOrCreateKeepDir
情報: Directory is present : C:\Lotus\Domino\restapi
Check if the directories exist / create missing
7 30, 2023 11:12:21 午前 com.hcl.domino.keep.install.KeepInstaller checkNotesDirectories
情報: Checking for C:\Lotus\Domino\nserver.exe and C:\Lotus\Domino\Data\names.nsf
Existing Domino Rest API installation has been detected.

[A]ccept [Enter] to upgrade, or [Q]uit [Enter] to abort

インストーラが環境をチェックして、インストール済みであることを検出した上で、アップグレードするかを確認してくれています。

ここで "A" と返答すると、アップグレードが開始されました。

しばらく待つと次のメッセージが表示され、インストーラが終了します。成功のようですね。

Installation: success (Exit code 0)


終了後、ログを確認すると、 "A" と返答した直後に次のような出力がありました。

installerFiles.txt found. Deleting its contents.
Finished deleting files from previous version.

Extracting binaries and JARs
JAR Path :file:/C:/KEEP106/restapiInstall.jar
Copy /installer/keep-admin-ui-1.23.2.jar -> C:\Lotus\Domino\restapi\keep-admin-ui-1.23.2.jar
  …

過去のインストールログからいったんアンインストールした上で、1.0.6 をインストールしているようですね。


最後に、あらためて、Install on Windows を確認したところ、アップグレードに関するオプションを発見しました。

-u オプションをつけて、もう一度インストールを実行したところ、アップグレードの確認プロンプトもなしに、インストーラが最後まで実行され、成功しました。

>>C:\Domino\jvm\bin\java -jar restapiInstall.jar -d="C:\Domino\Data" -i="C:\Domino\notes.ini" -p="C:\Domino" -r="C:\Domino\restapi" –a -u

-a は『利用規約に自動的に同意します』です。すべてオプションの通りだったため、確認なしにインストールを実行し、初回はアップグレードの指定がなかったためあえて確認したと想定できます。よくできたインストーラですね。


ちなみに、2回目のインストールは 1.0.6 から 1.0.6 のアップグレードインストールとなっています。アンインストールしてからインストールするというインストーラの挙動から判断して、検証としては問題ないと考えていますが、完全な検証となっていない点はご了承くださいませ。


まとめ

インストールの手順については、新規もアップグレードもほぼ同じ手順とがわかりました。

違いといえば、-u オプションでアップグレードを明示的に指定することだけでしたが、これも必須ではありませんでした。


インストール完了後、Domino サーバを起動すると、次の通り、バージョンの表記が更新されいました。

2023/07/30 11:47:20 {
2023/07/30 11:47:20 "name" : "HCL Domino REST API core API",
2023/07/30 11:47:20 "desc" : "Next generation APIs for HCL Domino",
2023/07/30 11:47:20 "version" : "v1.0.6 (Build 1.23.2-17)",
2023/07/30 11:47:21 "vendor" : "HCL Labs",
2023/07/30 11:47:21 "image-build" : "2023-07-12T20:15:51Z",
2023/07/30 11:47:21 "Verticles loaded" : 10,
2023/07/30 11:47:21 "Active handler classes" : 110,
2023/07/30 11:47:21 "active requests" : 0,
2023/07/30 11:47:21 "active agents" : 0,
2023/07/30 11:47:22 "apiPlatform" : "server",
2023/07/30 11:47:22 "runtime" : "0 days, 0 hours, 0 minutes, 7 seconds."
2023/07/30 11:47:22 }
2023/07/30 11:47:23 Domino Rest API Initialization complete.


また、Domino REST API のトップページも次の通り、1.0.6 と更新されていました。もちろん、以前のバージョンで定義した設定はそのまま保持されておりました。

2023/07/30

Notes - Excel 連携:#14)グラフの種類

グラフを作成する場合、Excel がグラフ化するデータを確認し、自動的にグラフを決定してくれます。これまで作成したグラフが折れ線グラフとなったのはこの機能によります。

今回は、このグラフの種類を指定する方法についてです。


グラフの種類を明示的に指定するには、Chart オブジェクトの ChartType プロパティを利用します。

Chart.ChartType プロパティ (Excel)

試しに ChartType をメッセージボックスで表示してみると 4 と表示されました。

   MsgBox "ChartType = " & CStr(oChart.ChartType)

ChartType プロパティの記述によると、グラフの種類は XlChartType に定義されています。たくさんのグラフが定義されていますね。

XlChartType 列挙 (Excel)


では、抜粋して実際にグラフを指定してましょう。

グラフ化する対象をユーザ数だけに設定したうえで、ChartType を以下の順で変更します。

グラフの種類 定数名
4 折れ線 xlLine
65 マーカー付き折れ線 xlLineMarkers
52 積み上げ縦棒 xlColumnStacked
1 xlArea
-4100 3-D 縦棒 xl3DColumn
-4120 ドーナツ xlDoughnut

それぞれの結果は以下にまとめて添付しますが、さまざまな形式のグラフが指定できることがわかります。また、出力サンプルから Excel が自動で選択したグラフは折れ線(xlLine = 4)だったことが確認できます。

的確かつ自由に使いこなせるようになれば、ノーツからでも様々がグラフが出力できるようになりますね。


出力サンプル

折れ線(Excel が選択したグラフ)

マーカ付き折れ線

積み上げ縦棒


3-D 縦棒

ドーナツ

前回 Notes - Excel 連携 次回

2023/07/28

ACLの優先順位

今回は ACL の判定に関してまとめます。

ACL のエントリは、個人名やグループ、使用経験はないのですがワイルドカードで指定できます。そして、そのどれにも属さない場合にデフォルト(-Default-)の権限が適用されます。

実際にアプリケーションを運用していると、あるユーザが複数のグループに所属するなど、1ユーザに対して1ACL エントリではない場合に遭遇します。このような状況になったときに、ACL がどのように判定されるか、実験したのでレポートします。


検証環境と準備

まず、検証は ”User01 Training/Domino” ユーザが存在し、DJX で別名 "講習会 ユーザ01/ドミノ" が付与されている環境を使用しました。

次に検証用に3つのグループを作成しました。すべて、今回の検証で使用する ”User01 Training/Domino” ユーザ所属するグループで、GroupA と GroupA_Sub は階層化されたグループとなっています。

グループ名 メンバー
GroupA GroupA_Sub
GroupA_Sub User01 Training/Domino
GroupB User01 Training/Domino

確認用のアプリケーションには、[RoleA] と [RoleB] の2つのロールを準備しています。


ACL の判定方法

付与された ACL のレベルは、『アクセス制御リスト』ダイアログの [有効なアクセス権] ボタンを使用して確認しました。

この画面を使用すると、指定したユーザの ACL レベルやオプション、付与されたロールが確認できます。


ユーザ vs 別名

通常のユーザ名(英字)と DJX で付与した別名での優先度の確認です。

まずは、同じアクセスレベルで、ロールとオプションを変化させてみました。

ACL エントリ レベル ロール その他
User01 Training/Domino 作成者 [RoleA] 文書の作成
講習会 ユーザ01/ドミノ 作成者 [RoleB] 文書の削除

結果は、次のように双方の設定を合算したようになっており、文書の作成と削除のオプション、両方のロールが付与された状態でした。


続いて、ACL レベルが違う場合です。

ACL エントリレベルロールその他
User01 Training/Domino作成者[RoleA]文書の作成
講習会 ユーザ01/ドミノ編集者なし個人エージェントの作成

別名側の ACL を編集者に設定し、ロールは付与せず、別のオプションを選択してみました。その結果は次の通りでした。

ACL は権限が高いほうの”編集者”が付与されました。ロールやオプションは双方の設定が合算された状態となっています。


ユーザ vs グループ

続いてユーザ名とグループの優先度を確認します。

ACL エントリレベルロールその他
User01 Training/Domino作成者[RoleA]文書の作成
GroupB作成者[RoleB]文書の削除

結果は次の通りとなり、ユーザの設定で権限が付与され、グループの設定は無視されているようです。

ためしに、GroupB の ACL を管理者に変更し、すべてのオプションとロールを付与してみましたが、結果は同じでした。

ユーザとグループで ACL 設定がかち合った場合、ユーザの設定が優先されるようです。


グループ vs グループ

次は、グループ同士の優先度の確認です。

ACL エントリレベルロールその他
GroupA_Sub作成者[RoleA]
[RoleB]
文書の削除
GroupB管理者なし文書の削除なし

結果は次の通りとなりました。ユーザ vs 別名と同様に合算されたような状態でした。

いろいろ検証した結果、階層化されたグループの影響もなく、グループとして設定されたすべてのエントリから、最大の ACL レベルを採用。オプションとロールは合算して付与されていることが確認できました。


まとめ

ここから先は冗長になるので、個人名 vs ワイルドカード、グループ vs ワイルドカードなどのレポートは割愛します。

検証の結果、ACL の優先度の決定は、次の順位で決定され、その順位の ACL 設定が有効となり、それ以下の順位の ACL エントリは無視されます。

   ユーザ > グループ > ワイルドカード > デフォルト

ユーザ別名やグループなど同じ順位で複数の有効なエントリがあった場合には、ACL レベルは高い方を採用し、オプションやロールはすべてのエントリを合算させた設定となります。

なお、今回の検証は、12.0.2 FP1 を使用して確認しました。以前同様の検証をしたのは、約 20 年前の R5 だったかと思います。もちろん結果は一切変わっていません。基本的な機能とは言え、Notes の互換性ってすごいですね。

2023/07/25

DXL ことはじめ:#4)LotusScript で DXL を参照するには?

DXL を操作するための LotusScript の NotesClass を確認しましょう。


NotesDOMParser クラス

Parse とは、解析するという意味です。IT のエリアでは、一定のルールに従って記述されたデータを解析し、プログラムで操作できるよう構造化されたデータに変換することを言います。Parser はそのような変換を行うソフトウェアということになりますね。

今回の事例の場合、NotesDOMParser クラスは、NotesDXLExporter が出力した DXL を解析し、LotusScript で扱えるよう変換する役割を担います。よって、DXL と LotusScript の橋渡し的な役割を果たす裏方さんということになります。

NotesDOMParser (LotusScript®)


では、具体的な利用方法です。サンプルコードは次のようになります。

Dim dexp As NotesDXLExporter
Dim dprs As NotesDOMParser

'Dominoデータ を DXL に変換する準備
Set dexp = xns.CreateDXLExporter
Call dexp.SetInput(vnd)

'パーサーに変換する DXL をセット
Set dprs = xns.CreateDOMParser()
Call dprs.SetInput(dexp)

'DXL 変換を実行
Call dexp.Process()

まず、NotesDXLExporter のオブジェクトを作成し、DXL 化するオブジェクトである文書 vnd を SetInput メソッドで設定します。次に、NotesDOMParser のオブジェクトを作成し、先に定義した NotesDXLExporter のオブジェクトを入力として定義します。最後に、NotesDXLExporter クラスの Process メソッドを実行し、DXL の変換を実行します。

これで、文書が DXL に変換され、それがパーサーに渡されて解析、LotusScript で扱えるという一連の流れを構築できます。


NotesDOM?????Node クラス

パーサーが解析したデータには、NotesDOM?????Node クラス経由でアクセスし、操作します。ヘルプを見ると似たような名前のクラスが多数あります。一部を抜粋すると次の通りです。

クラス名 用途(Designer ヘルプより抜粋)
NotesDOMDocumentNode XML 文書全体を表します。文書ツリーのルートです。
NotesDOMElementNode XML 文書の要素を表します。
NotesDOMCharacterDataNode DOM ノードの文字データを表します。
NotesDOMTextNode 要素または属性の Text 形式の内容を表します。

それぞれのヘルプを確認すると、これらのプロパティやメソッドを確認するとかなりの部分が重複していることがわかります。なかなか、難解ですね。

これは、各クラスが NotesDOMNode クラスを継承して定義されているためです。NotesRichTextItem クラスが、NotesItem クラスを継承しており、NotesRichTextItem のオブジェクトでも NotesItem クラスのプロパティやメソッドが使えるのと同じですね。

この基底クラス(NotesDOMNode)の機能が、このシリーズのクラスの基本機能であり、違いがある部分が、各クラスの特徴ということになります。ヘルプからプロパティとメソッド、継承元を抜粋すると次の表のようになりました。

いかがですか? 違いがよくわかりますね。

NotesDOMDocumentNode には、Create?????Node というメソッドが多数ありますね。このクラスは各種 Node を作成する機能を担当するようです。また、GetElementsByTagName というメソッドを持つので、配下のノードを検索する機能を持ちます。

NotesDOMElementNode も GetElementsByTagName メソッドを持ちます。この2つのクラスは、きっと多数の配下を持つノードを想定したクラスということでしょう。

NotesDOMElementNode では、GetAttribute や RemoveAttribute などアットリビュート(属性)に対するメソッドを持っています。また、TagName というプロパティも持っていますね。

NotesDOMTextNode は、その名の通り文字列を扱うノードを定義しています。SplitText や SubstringData のように文字列を操作するメソッドを持ちます。


次回からは、これらのクラスを使って、DXL にアクセスしてみましょう。

前回 DXL ことはじめ 次回

2023/07/23

Notes - Excel 連携:#13)グラフ化するデータの指定

これまでのグラフでは、シート内のデータを Excel が自動で判別していました。今回は、LotusScript から明確に指示する方法を整理します。

Excel でグラフの右クリックメニューに [データの選択] があり、これを開くと『データソースの選択』という画面が表示されます。これが実際にグラフとして表示されているデータの設定です。

これと同様の操作を行うメソッドが、Chart オブジェクトの SetSourceData メソッドです。

SetSourceData メソッド

『データソースの選択』画面はなかなか複雑なのですが、このメソッドの引数は2つだけといたってシンプルです。ポイントは Source という引数の指定の仕方ということのようです。

この Source 引数は Range オブジェクトを指定する仕様となっています。具体的に指定方法を探っていきましょう。


単純な場合

まずは、グラフ化するセルが長方形(矩形)で構成される例です。

この場合は、単純に範囲の Range オブジェクトを引数に SetSourceData メソッドをコールするだけです。

例えば、

   Call oChart.SetSourceData(oSheet.Range("A1:B31"))

と設定すると、ユーザ数だけのグラフとなります。

次のように設定すると、

   Call oChart.SetSourceData(oSheet.Range("A1:C31"))

Excel が自動でセットしたのと同じ状態になります。


X 軸と Y 軸を明確に指定する場合

それでは、A 列を横軸(日付)、C 列だけを Y 軸に表示するためにはどうすればよいのでしょうか?

Excel で実際に操作をするとそのヒントが掴めます。グラフの右クリップメニューから『データソースの選択』画面を開きます。「グラフデータの範囲」の右のアイコンをクリックし、シートから A 列と C 列を選択します(A 列をクリックしてから Ctrl キーを押しながら C 列をクリック)。すると範囲の指定がカンマ区切りで表示されます。

このようにカンマ区切りで指定すると、離れた列を1つのグラフにすることができます。

Lotus Script で記述すると次のようになります。

   Call oChart.SetSourceData(oSheet.Range("A1:A31, C1:C31"))

実行すると、増減の列だけがグラフとして表示されます。

SetSourceData メソッドを利用するときには、横軸と縦軸のカラムが隣接しているかにかかわらず、カンマ区切りで指定すると汎用的だと思います。私は通常以下のように記述しています。

   Call oChart.SetSourceData(oSheet.Range("A:A, B:C"))

ちなみに Range オブジェクトの指定は、列だけをコロンでつなげることにより、行の指定を省略することができます。


前回 Notes - Excel 連携 次回

2023/07/21

Project KEEP:アクセス権限の動作確認

Domino REST API(Project KEEP)をアプリケーションに組み込むことを前提に、ACL と 読者フィールドの検証をしてみました。

検証に使用したアプリは、『Project KEEP 体験』シリーズで作成した郵便番号検索を再利用しました。利用する RestAPI は、Swagger UI の [data] セクションの /query を使用します。以下のリンクと同じ手順で、郵便番号を検索します。

Project KEEP 体験:#5)郵便番号検索 - Swagger UI によるテスト


ACL の検証

まずは、ACL により API のレスポンスがどのように変化するか調査します。RestAPI で接続するアプリケーションである『郵便番号マスタ』の ACL を変化させながら /query API をコールして、結果を確認します。

”管理者” から順に下げたところ、”読者” までは、正常にレスポンスが JSON で帰ってきました。

”投稿者” に設定すると、結果はエラーとなりました。レスポンスの JSON の message には ”Insufficient access, need READER (current level: DEPOSITOR)” と表示されており、エラーの原因がアクセス権限の不足であることがわかります。

次に、ACL を ”なし” に設定すると、エラーメッセージが ”Failed to open database: 操作を実行する権限がありません” と変化しました。

この結果より、認証で使用したユーザ ID に付与された ACL で動作していることが確認できました。また、エラーの原因は、JSON で確認できることがわかりました。

ちなみに、今回のテストは Swagger UI 上部の [Authorize] ボタンで Bearer を入力し認証したまま、Notes クライアントから ACL を変更しながら確認しました。それでも、即座に ACL が反映されましたので、Bearer が同じままでも、API コールのたびに ACL を判定していることがわかります。


読者フィールドの検証

続いて、セキュアなアプリでよく使用する ”読者フィールド” についてです。

今回は、郵便番号マスタの文書内に読者フィールドを作成し、”[Reader]” ロール保持者だけが文書を参照できるように設定しました。

まず、API をコールするユーザに ”[Reader]” ロールを保持させて実行したところ、問題なく検索できました。当たり前ですね...

次に、”[Reader]” ロールを外して検索したところ、次のような結果になりました。

エラーは出なかったのですが、レスポンスの JSON が空の配列となっていました。接続はできても、文書が見えないのですから、空の配列を返すという結果になったということですね。


まとめ

Domino REST API(Project KEEP)では、接続ユーザの権限でレスポンスを返すことがわかりました。ノーツのセキュリティモデルに沿っているのでとても理解しやすいですね。

今回のテストで、ACL 権限不足と読者権限がない場合の挙動が明確になりましたので、アプリケーションに組み込む際には、この結果に合わせたコーディングが必要ですね。

2023/07/18

DXL ことはじめ:#3)DXL を見やすく整形

前回は、ノーツの文書を DXL に変換する処理を紹介しました。出力結果は、次のようになっていました。

見やすく整形されていないので、タグの開始と終了、階層構造が把握しづらいですね。今回は、この DXL を見やすく整形する方法について整理します。


使用するのは、Microsoft が提供する Visual Studio Code(VSCode)です。VSCode は、開発用エディタで定番のツールといえる存在ですので、ご存じの方も多いかと思います。

VSCode は、次のような特徴があります。

  • 無償
  • 使い勝手が良い
  • 機能拡張が可能
  • 様々な言語やデータ形式に対応
  • macOS や Linux にも対応


無償のツールですのでインターネットからダウンロードしてすぐに使えます。

Visual Studio Code

ちなみに、日本語化は、左ツールバーにある Extensions アイコンをクリックし、”Japanese Language Pack”で検索すると見つかりますので、必要に応じてインストールしてください。


VSCode の全般的な操作で特徴的なのが、テキストファイル1つを開くのではなく、フォルダを開く点です。Web 開発では、HTML や CSS、JavaScript ライブラリなど様々なファイルを同時に編集するための配慮かと思います。


では、適当なフォルダを作って、そのフォルダを VSCode で開きます。新しいファイルを作成し、前回出力した DXL を貼りつけます。

ウィンドウ右下の『言語モードの選択』で "XML" を選択します。これでタグなどが色付けされます。これは、シンタックスハイライトと言って、予約語や区切り記号、タブ名や属性値などを着色し、可読性を上げる機能です。

続いて、右クリックして [ドキュメントのフォーマット] を選択します(もしくは、Shift+Alt+F)。

これで、タグに合わせてインデントされ、階層構造が容易に把握できるようになります。


なお、フォーマッタがない場合には候補の一覧と選択画面が表示されます。適当な XML のフォーマッタを選択し、インストールしてください。

前回 DXL ことはじめ 次回

2023/07/16

リッチテキスト:#8)文字フォントの設定

前回は、フォントの設定の中でもノーツ標準のデフォルトフォントの指定について紹介しました。今回は、フォント名を明示的に指定する方法についてまとめます。


リッチテキストのフォントの管理

NotesFont プロパティのヘルプに「Obtain additional values, starting at 5, with GetNotesFont.」とあります。GetNotesFont を使用して、5 から始まる値を取得できるようです。デフォルトフォント以外を指定するには、このメソッドを使うということですね。

NotesFont (NotesRichTextStyle - LotusScript®)

GetNotesFont (NotesRichTextItem - LotusScript®)

構文は次の通りで、引数で指定したフォントのフォント番号を返します。この番号を NotesFont プロパティに設定して使うということのようです。

   notesFont% = notesRichTextItem.GetNotesFont(faceName$, addOnFail)

  • faceName$

OS 上で定義されているフォントの名前です。

  • addOnFail

文書内でフォント番号が定義されていない場合の動作について設定します。 True の場合強制的に番号を割り当てます。False の場合、0 を返します。


サンプルプログラム

GetNotesFont を使用したサンプルプログラムです。

変数 s にセットしたフォント名を GetNotesFont してフォント番号を取得、NotesFont にセットして、そのフォントで付与された番号とフォント名を表示します。

   Set ndb = ns.CurrentDatabase
   Set nd = ndb.CreateDocument()

   nd.Form = "RichText"
   nd.Title = "リッチテキスト:#8)文字フォントの設定"

   Set nrti = nd.CreateRichTextItem("Body")
   Set nrts = ns.CreateRichTextStyle()
   nrts.FontSize = 24

   s = "メイリオ"
   nrts.NotesFont = nrti.GetNotesFont(s, True)
   Call nrti.AppendStyle(nrts)
   Call nrti.AppendText(CStr(nrts.NotesFont) & " <= " & s)
   Call nrti.Addnewline(1)

   s = "HGP創英角ポップ体"
   nrts.NotesFont = nrti.GetNotesFont(s, True)
   Call nrti.AppendStyle(nrts)
   Call nrti.AppendText(CStr(nrts.NotesFont) & " <= " & s)
   Call nrti.Addnewline(1)

   Call nd.Save(True, False)

実行結果は次の通りで、5 と 6 が付与され、そのフォントで文字が表示されています。


addOnFail の挙動

上記のリストで、2つ目の引数 addOnFail を False とした場合、番号はすべて 0 となりデフォルトフォントの Default Serif で表示されます。

addOnFail を True として、同じフォントを何度 GetNotesFont しても最初に付与した番号が返されます。

また、addOnFail を True にして、間違ったフォントを指定するとそのフォント名のまま出力されます。下図では、あり得ないフォント『出直し!! ドミノ塾』をセットしてみました。

ちなみに、存在しないフォントの場合、ノーツクライアントの機能で Default Sans Serif で表示されるようです。


ヘルプによると、フォント番号の管理は文書内との記述があります。ただ、NotesRichTextItem のメソッドであることから、リッチテキストフィールド単位かもしれませんね。どちらにしろ、ノーツにはデフォルトフォントという機能があるので、フォントを明示的に指定する機会は少ないかと思います。

指定するにしても、開発者はそのフォントにセットしたいわけですし、フォント名を間違えても、初回は True でコールするのでエラー判定に使用できるわけでもないです。そもそも、実行する PC と 参照する PC でフォントが違う可能性がありますし、OS が違う可能性もあります。エラー判定にこだわる必要はないですね。

たとえ存在しないフォント名であっても、デフォルトフォントで表示してくれる機能があるんですから、このオプションは『必ず True にする』でいいような気がします...

前回 リッチテキストの基本操作 次回

2023/07/12

DXL ことはじめ:#2)文書を DXL で表示してみよう!

前回は DXLの概要について説明しました。今回は LotusScript で既存文書を DXL に変換する方法を説明します。


サンプルプログラムの紹介

このサンプルプログラムは、ビューで選択した文書を DXL に変換し、同じ DB 内に文書として保存します。その文書は、Form が "DXL" で、Body というリッチテキスト内に変換した DXL を保存します。

なお、変換元の文書は、『Project KEEP 体験』シリーズで使用した郵便番号マスタをサンプルとして使用しています。


◇ 処理の実行

変換したい文書を開き、エージェント(後述)を実行します。


◇ 実行結果

次のような文書が新規に作成され、変換された DXL を確認できます。

前回デザイナーで DXL を確認した際には、GUI で階層化されて表示されていたので、XML らしくありませんでしたが、この結果を見ると、マークアップランゲージらしくタグで構造化されたテキストデータということがよくわかります。

DXL の中身をざっと見ると、文書のプロパティで確認できるような情報のみとなっています。項目のラベルやフォームのタイトルなどはフォームの設計ですので、含まれていません。ノーツは文書とフォームは別管理であることがよくわかりますね。


サンプルプログラム

次のプログラムで DXL 変換を実行します。エージェントとして記述し、選択文書に対して実行する設定とします。

Option Declare

Private xns As NotesSession
Private xndb As NotesDatabase

Sub Initialize
   Dim ndc As NotesDocumentCollection
   Dim nd As NotesDocument
   Dim sDXL As String

   Set xns = New NotesSession
   Set xndb = xns.CurrentDatabase
   Set ndc = xndb.UnprocessedDocuments

   Set nd = ndc.GetFirstDocument '1文書目を処理
   sDXL = xGetDXL(nd) 'DXL に変換
   Call xSaveDXL(sDXL) 'DXL を文書に保存
End Sub

Function xGetDXL(vnd As NotesDocument) As String
   Dim dexp As NotesDXLExporter

   'Dominoデータ → DXL
   Set dexp = xns.CreateDXLExporter
   xGetDXL = dexp.Export(vnd) 'DXL をテキストで取得
End Function

Function xSaveDXL(vsDXL As String) As Boolean
   Dim nd As NotesDocument
   Dim nrti As NotesRichTextItem

   Set nd = xndb.CreateDocument()
   nd.Form = "DXL"
   nd.Title = "DXL #2"
   Set nrti = nd.CreateRichTextItem("Body")
   Call nrti.AppendText(vsDXL)

   xSaveDXL = nd.Save(True, False)
End Function

DXL に変換する部分は、関数 xGetDXL にまとめられています。使用しているクラスやメソッドを確認しましょう。


NotesDXLExporter クラス

このクラスは、Domino データ(文書や設計要素)を DXL に変換(エクスポート)するためのオブジェクトです。

NotesDXLExporter (LotusScript®)

このクラスは、DXL に関して様々な機能を提供するのですが、単に Domino データを DXL 化するだけであれば、Export メソッドを使用するだけです。

このメソッドは、引数で指定した Domino データ(今回は文書)を DXL に変換して、その結果を文字列で返します。

Export (NotesDXLExporter - LotusScript®)

前回 DXL ことはじめ 次回

2023/07/11

ドミノクラスタ:可用性の設定

ドミノクラスタは、負荷分散や可用性向上が目的で導入しますが、これらの実現にかかわる基本的な設定についてまとめます。


◇ 負荷分散の仕組み

ドミノクラスタでは、各サーバごとに可用性限界値を設定できます。サーバのステータスがこの限界値を超えた場合、他のメンバーサーバに接続が振り替えられます。これをフェイルオーバーといい、サーバの負荷を分散することができます。


◇ 可用性向上の仕組み

サーバを稼働系と待機系に分けて運用する方法です。通常は稼働系がサービスし、障害発生時のみ待機系が応答させ、可用性を向上させることができます。

設定は、上記負荷分散の仕組みを利用して、待機系の可用性限界値を最大に設定し、稼働系に接続を振り返えさせるという方法になります。


可用性インデックス

ドミノサーバは、現在のワークロードを可用性インデックスで表します。この値は、サーバコンソールで "show server" コマンドを投入すると確認できます。

[18C8:0006-2B9C] HCL Domino (r) Server (64 Bit) (Release 12.0.2FP1 for Windows/64) 2023/07/11 19:13:35

[18C8:0006-2B9C] Server name: Server1/Domino
[18C8:0006-2B9C] Domain name: Domain
[18C8:0006-2B9C] Server directory: C:\Lotus\Domino\Data1
[18C8:0006-2B9C] Partition: C.Lotus.Domino.Data1
[18C8:0006-2B9C] Elapsed time: 00:11:13
[18C8:0006-2B9C] Transactions/minute: Last minute: 8; Last hour: 15; Peak: 64
[18C8:0006-2B9C] Peak # of sessions: 3 at 2023/07/11 19:04:57
[18C8:0006-2B9C] Transactions: 160 Max. concurrent: -1
[18C8:0006-2B9C] ThreadPool Threads: 100 (TCPIP Port)
[18C8:0006-2B9C] Member of cluster: Cluster
[18C8:0006-2B9C] Availability Index: 100 (state: AVAILABLE)
[18C8:0006-2B9C] Mail Tracking: Not Enabled
[18C8:0006-2B9C] Mail Journalling: Not Enabled
[18C8:0006-2B9C] Number of Mailboxes: 1
    ・・・

可用性インデックスは、0 ~ 100 の数値で表され、100 が負荷が軽い状態で、0 が負荷が高い状態を表します。値はドミノサーバが定期的に算出し更新されます。

Administrator ヘルプによると、このインデックスは、使用可能なサーバのリソースの比率と同等だそうです。例えば 65 の場合、まだ 65% の余裕があると判断できるとのことです。


サーバステータスとフェイルオーバー

インデックスの横にはサーバステータスが表示されます。ステータスは、"AVAILABLE" と "BUSY" が存在します。

可用性インデックスの値が、サーバの可用性限界値以下になるとサーバのステータスが "BUSY" となります。ビジー状態になり、他のクラスタメンバーで "AVAILABLE" なサーバがあれば、そちらに接続が振り替えられます。これをフェイルオーバーと呼びます。


可用性限界値の設定

各サーバの notes.ini に以下のパラメータを設定します。

SERVER_AVAILABILITY_THRESHOLD=n

n は設定する限界値としたい可用性インデックスの値を設定します。

限界値に 0 を設定すると、可用性インデックスの値にかかわらず、サーバステータスは "AVAILABLE" となります。DB が存在しない場合やサーバがダウンしている場合などを除き、フェイルオーバーせず接続します。

逆に 100 を設定すると、絶えず "BUSY" となり、通常の接続は受け付けず他のクラスタメンバーにフェイルオーバーすることになります。


ドミノクラスタの一般的な設定

アプリケーションサーバの場合、接続が分散すると競合文書の発生原因となります。それを抑制するため、アプリサーバは、稼働系と待機系に分けて運用します。この場合、SERVER_AVAILABILITY_THRESHOLD の設定は、稼働系:待機系 = 0:100 に設定します。

メールの場合は、同じ文書を複数人で更新する可能性は低いといえます。よって、メール専用サーバの場合は、0:100 以外の設定で負荷分散をさせることもあります。


2025.2.19 更新

SERVER_AVAILABILITY_THRESHOLD に関する記述が逆となっておりました。
正しくは、稼働系は 0、待機系は 100 を設定します。
不正確な情報を記載して申し訳ありませんでした。お詫びいたします。

なお、本文は修正済みです。


ドミノクラスタの構築

ドミノクラスタは、複数台のドミノサーバで構成され、サーバ間の負荷分散や可用性向上を目的とした機能です。

ドミノ標準のタスクで構成されており、追加のインストールなどは発生せず利用できます。今回は、ドミノクラスタの新規構築を材料に、基本的なセットアップ方法をまとめます。


ドミノクラスタの概要

ドミノクラスタは、複数台のドミノサーバで構成されたクラスタグループで連携して動作する機能です。それぞれは、個別のドミノサーバとなりますので、別々のサーバ名で運用されます。

複数台のドミノサーバを運用する場合、通常、複製(レプリケーション)により、定期的に整合性を維持します。ドミノクラスタでは、文書の作成や更新などのイベントを検知すると、即時に他のクラスタメンバーにプッシュします。この動作をクラスタ複製と呼びます。

複製はスケジュール駆動型で、ドミノクラスタはイベント駆動型の複製となります。サーバ停止時など、何らかの理由でイベントが検知できない場合はクラスタ複製されません。よって、ドミノクラスタ環境であっても、通常の複製タスクは必要となる点に注意が必要です。


評価環境

今回ドミノクラスタを構築する環境は、先の記事でパーティションサーバとして構築した2台のサーバをドミノクラスタ化してみます。1台の PC でドミノクラスタまで評価できるのは、ありがたいですね。


セットアップ

Administrator クライアントを起動して、[設定] - [サーバー] - [すべてのサーバー] ビューを開きます。クラスタ化するサーバにチェックを入れて [クラスタへ追加] アクションボタンをクリックします。確認メッセージが表示されるので [はい] を選択します。


『クラスタ名』という画面が表示されるので、"*新規クラスタの作成" を選択し、[OK] をクリックします。続いて、新規クラスタ名を入力する画面が表示されるので、クラスタグループ名を入力します。


続いて、実行の確認画面が表示されます。[はい] を選択します。この場合、サーバ文書が即座に更新されます。


[いいえ] を選択すると次のようなシステム管理プロセスのリクエストが作成され、AdminP がサーバ文書を更新します。サーバ文書の更新なので、競合が発生する確率は少ないとは思うのですが、それでもしっかり配慮されているようです。



どちらにしろ、結果的にはサーバ文書のクラスタ名欄にクラスタグループ名がセットされます。


セットアッププロセスの流れ

サーバ文書にクラスタ名が設定されたことを検知して起動するのだと思いますが、しばらく待つとドミノクラスタのセットアッププロセスが実行されます。

まず、サーバ文書が更新されたサーバ(Server1/Domino)で処理が開始されます。コンソールログには次のようなログが出力されます。

処理開始のメッセージの後、Cluster Directory タスクが起動します。初回なので、管理データベースである cldbdir.nsf を作成します。

直後に cldbdir.nsf を複製しようとしていますが、他のクラスタメンバーにはまだ存在しないので空振りしているようです。

[4294:0092-1058] 2023/07/10 20:53:48 Adding server to cluster Cluster
[2E54:0002-1038] 2023/07/10 20:53:48 Cluster Database Directory started
[2E54:0002-1038] 2023/07/10 20:53:48 Created database Cluster Database Directory: cldbdir.nsf
[2E54:0002-1038] 2023/07/10 20:53:48 Finished initialization of Cluster Database Directory
[2E54:0002-1038] 2023/07/10 20:53:48 Replicating Cluster Database Directory with Server2/Domino
[2E54:0002-1038] 2023/07/10 20:53:48 Starting replication with server Server2/Domino
[2E54:0002-1038] 2023/07/10 20:53:49 Unable to replicate with server Server2/Domino: 選択したサーバーにレプリカがありません
[2E54:0002-1038] 2023/07/10 20:53:49 Unable to update Cluster Database Directory: 選択したサーバーにレプリカがありません

続いて、Cluster Replicater が起動されます(一部不明なログがありますが...)。その後、再度複製タスクが起動されています。2文書を更新しているので、このタイミングで、クラスタ名がセットされたサーバ文書を反映しているようです。

[0C54:0007-3170] SaveSCRState: Error deleting file C:\Lotus\Domino\Data1\scrstate.dat. 103
[0C54:0002-4248] 2023/07/10 20:53:58 Cluster Replicator started
[0C54:0002-4248] 2023/07/10 20:53:58 RestoreSCRState: Starting SCR restore at 2023/07/10 20:53:58
[0C54:0002-4248] 2023/07/10 20:53:58 Cluster Replicator is set to Ignore Database Quotas
[4294:0092-1058] 2023/07/10 20:54:08 Starting replication with server Server2/Domino
[4294:0092-1058] 2023/07/10 20:54:08 Pushing names.nsf to Server2/Domino names.nsf
[4294:0092-1058] 2023/07/10 20:54:08 レプリケータは 2 文書を Server2/Domino names.nsf へ names.nsf から更新しました
[4294:0092-1058] 2023/07/10 20:54:08 Finished replication with server Server2/Domino

最後にクラスタ環境用の空き時間検索データベースの clbusy.nsf を作成しています。不要となる busytime.nsf の削除は、この時点では失敗しているようですね。

[39F0:0002-4790] 2023/07/10 20:54:18 SchedMgr: clubusy.nsf was successfully created, Error cleaning up busytime.nsf: データベースは現在使用中です
[39F0:0002-4790] 2023/07/10 20:54:18 WARNING: No clustermates found for this server. If ANY should exist stop this task and check the cluster configuration or risk busytime integrity!
[2048:0002-2184] 2023/07/10 20:54:57 Rooms and Resources Manager shutdown complete


続いて、もう一方のサーバ(Server2/Domino)です。

まず、Server1 の2回目の複製の時刻に、Server1 がセッションを開いたメッセージが出ています。このタイミングで、Server2 のサーバ文書が更新されたと想定できます。

[255C:008E-123C] 2023/07/10 20:54:08 Opened session for Server1/Domino (Release 12.0.2FP1)

ここから先の挙動は Server1 と同様です。まず、Cluster Directory タスクが起動します。

ただ、Server2 は後追いの実行になり、Server1 にはすでに cldbdir.nsf が出来上がっているので、複製に成功しています。

[255C:008E-123C] 2023/07/10 20:54:08 Opened session for Server1/Domino (Release 12.0.2FP1) [255C:0092-3F00] 2023/07/10 20:55:01 Adding server to cluster Cluster
[442C:0002-1548] 2023/07/10 20:55:01 Cluster Database Directory started
[442C:0002-1548] 2023/07/10 20:55:01 Created database Cluster Database Directory: cldbdir.nsf
[442C:0002-1548] 2023/07/10 20:55:01 Finished initialization of Cluster Database Directory
[442C:0002-1548] 2023/07/10 20:55:01 Replicating Cluster Database Directory with Server1/Domino
[442C:0002-1548] 2023/07/10 20:55:01 Starting replication with server Server1/Domino
[442C:0002-1548] 2023/07/10 20:55:01 Pulling cldbdir.nsf from Server1/Domino cldbdir.nsf
[442C:0002-1548] 2023/07/10 20:55:01 レプリケータは 125 文書を cldbdir.nsf へ Server1/Domino cldbdir.nsf から追加しま した
[442C:0002-1548] 2023/07/10 20:55:01 Pushing cldbdir.nsf to Server1/Domino cldbdir.nsf
[442C:0002-1548] 2023/07/10 20:55:01 レプリケータは 119 文書を Server1/Domino cldbdir.nsf へ cldbdir.nsf から追加しま した
[442C:0002-1548] 2023/07/10 20:55:01 レプリケータは 2 文書を Server1/Domino cldbdir.nsf へ cldbdir.nsf から更新しまし た
[442C:0002-1548] 2023/07/10 20:55:01 Finished replication with server Server1/Domino

続いて、Cluster Replicater の起動です。このタスクのID(1404:0002-2488)と同じログで、複製が記録されていますので、いきなりクラスタ複製が動作しているようですね。

[1404:0002-2488] 2023/07/10 20:55:11 Cluster Replicator started
 [1404:0008-1D08] SaveSCRState: Error deleting file C:\Lotus\Domino\Data2\scrstate.dat. 103
[1404:0002-2488] 2023/07/10 20:55:11 RestoreSCRState: Starting SCR restore at 2023/07/10 20:55:11
[1404:0002-2488] RTRFindPushDbs: Startup replication: dbs to be pushed 3 at 2023/07/10 20:55:11
[1404:0002-2488] 2023/07/10 20:55:11 Cluster Replicator is set to Ignore Database Quotas
[1404:0002-2488] 2023/07/10 20:55:11 Pushing admin4.nsf to Server1/Domino admin4.nsf
[1404:0002-2488] 2023/07/10 20:55:11 Pushing ddm.nsf to Server1/Domino ddm.nsf
[1404:0002-2488] 2023/07/10 20:55:11 レプリケータは 1 文書を Server1/Domino ddm.nsf へ ddm.nsf から追加しました
[1404:0002-2488] 2023/07/10 20:55:11 Pushing names.nsf to Server1/Domino names.nsf
[255C:0092-3F00] 2023/07/10 20:55:21 Starting replication with server Server1/Domino
[255C:0092-3F00] 2023/07/10 20:55:21 Pulling cldbdir.nsf from Server1/Domino cldbdir.nsf
[255C:0092-3F00] 2023/07/10 20:55:21 Pushing cldbdir.nsf to Server1/Domino cldbdir.nsf
[255C:0092-3F00] 2023/07/10 20:55:21 Finished replication with server Server1/Domino

最後に、空き時間検索データベースの clbusy.nsf の作成です。こちらは、作成に失敗しており、Server1 より状況はよくなさそうです。

[46E0:0002-096C] 2023/07/10 20:55:56 RnRMgr: Error switching busy time database from busytime.nsf to clubusy.nsf: RnRMgr: Error switching cluster busy time database
[46E0:0002-096C] 2023/07/10 20:55:56 Rooms and Resources Manager shutdown complete

ですが、直後の複製が正常に実行されたログを発見しました。ログの表示はさておき、正常に作成は終わっているようです。

[40FC:0002-0574] 2023/07/10 20:56:05 Starting replication with server Server1/Domino
[40FC:0002-0574] 2023/07/10 20:56:05 Pulling clubusy.nsf from Server1/Domino clubusy.nsf
[40FC:0002-0574] 2023/07/10 20:56:05 レプリケータは 2 文書を clubusy.nsf へ Server1/Domino clubusy.nsf から追加しました
[40FC:0002-0574] 2023/07/10 20:56:05 Finished replication with server Server1/Domino
[1404:0002-2488] 2023/07/10 20:56:12 Pushing clubusy.nsf to Server1/Domino clubusy.nsf
[1404:0002-2488] 2023/07/10 20:56:12 レプリケータは 1 文書を Server1/Domino clubusy.nsf へ clubusy.nsf から追加しました
[1404:0002-2488] 2023/07/10 20:56:12 レプリケータは 2 文書を Server1/Domino clubusy.nsf へ clubusy.nsf から更新しました


セットアップ結果

先ほどは、処理の流れを記載しましたが、ここでは、処理結果をまとめます。クラスタ環境を構築すると次のように環境が更新されます。


◇ サーバ文書の更新

クラスタ環境が構築されるとサーバ文書のクラスタ名にセットアップで指定したクラスタグループ名が表示されます。

また、ドミノディレクトリの [設定] - [クラスタ] ビューでメンバーのサーバを確認できます。


◇ クラスタタスクの起動

ドミノクラスタ環境では、クラスタタスクが自動的に起動されます。

起動されるタスクは、Cluster Directory(cldbdir)と Cluster Replication(clrepl)の2種類です。

Cluster Directory は、クラスタ対象の DB を管理するタスクです。結果は、『Cluster Directory』データベース(cldbdir.nsf)に登録され、クラスタ対象の DB の確認や DB 単位でのクラスタの停止設定が可能です。

Cluster Replication は、発生したイベントを即座にクラスタメンバーのサーバに反映するタスクです。


◇ notes.ini の更新

セットアップでクラスタを有効にするとサーバの notes.ini に次のエントリが追加されます。

SERVER_CLUSTER_ON=1

この設定により、次回サーバ起動時から、Cluster Directory(cldbdir)と Cluster Replication(clrepl)が自動的に起動されます。


◇ 空き時間検索 DB の再作成

標準の空き時間検索 DB は busytime.nsf ですが、クラスタ環境では clbusy.nsf とファイル名が変化します。

ファイル名の置き換えは、サーバタスクが自動で行いますので、意識する必要はありません。ただ、ファイル名が変化することを知らないと、空き時間検索のトラブル対応時に混乱するので、ご注意ください。


基本的なセットアップ作業については、以上です。