ドミノディレクトリに登録するグループでは、そのメンバーに他のグループ名を指定することができます。
グループ文書のメンバー欄は他のテキストフィールドと同様に文字数制限があります。その制限を超えて多くのメンバー名を登録したい等の理由でグループから別のグループを参照する「グループの入れ子」を行うことがあります。
分かりづらいですが、次に例を示します。「Grp1」のメンバーに「Grp2」を指定しています。そして「Grp2」のメンバーに「Grp3」を指定、「Grp3」のメンバーに「Grp4」を指定...と続きます。
Grp1
└Grp2
└Grp3
└Grp4
├Grp2
└Grp5
└Grp6
入れ子のグループ自体は結構なのですが、気が付くと2つのグループが互いに参照しあって、参照のループを起こしていることがあります。
上の例では「Grp4」のメンバーに「Grp2」を指定していて、Grp2 から Grp4 の間で参照のループを起こしています。
私はこういった参照のループが運用上問題になることは最近はほとんど経験していません。が、新機能のベータ版で不具合を引き起こしたことがありました。
そんなときに参照のループをチェックするツールが欲しいな、ということで作ったコードがありますのでご紹介します。
Dim nab As NotesDatabase
Dim vw As NotesView
Dim groupsInThread% List
Dim loopGroups$ List
Sub Initialize
Dim ss As New NotesSession
Dim dc As NotesDocumentCollection
Dim currentGroup As NotesDocument
Dim searchFormula$
Set nab = New NotesDatabase( ss.Currentdatabase.Server, "names.nsf" )
Set vw = nab.Getview( "Groups" )
searchFormula = |Form="Group"|
If Not nab.Isopen Then Call nab.Open("", "")
Set dc = nab.Search( searchFormula, Nothing, 0 )
Set currentGroup = dc.Getfirstdocument()
While Not currentGroup Is Nothing
Call isLoop( currentGroup, 0 )
Erase groupsInThread
Set currentGroup = dc.Getnextdocument( currentGroup )
Wend
ForAll o In loopGroups
Print ListTag( o ), o
End ForAll
End Sub
Function isLoop( currentGroup As NotesDocument, nestLevel% ) As String
Dim childGroup As NotesDocument
Dim members, groupName$, loopingMember$
isLoop = ""
groupName = currentGroup.Getfirstitem( "ListName" ).Text
'Existing check for group name
If IsElement( loopGroups( groupName ) ) Then Exit Function
If IsElement( groupsInThread( groupName ) ) Then
loopGroups( groupName ) = ""
isLoop = groupName
Exit Function
Else
groupsInThread( groupName ) = False
End If
'Check group members
If "" = currentGroup.Getfirstitem( "Members" ).Text Then Exit Function
members = currentGroup.Getfirstitem( "Members" ).Values
ForAll member In members
If "cn=" <> LCase( Left( member, 3 ) ) Then
Set childGroup = vw.Getdocumentbykey( member, True )
If Not childGroup Is Nothing Then
loopingMember = isLoop( childGroup, nestLevel + 1 )
if "" <> loopingMember Then
If groupName <> loopingMember Then
isLoop = loopingMember
End If
If Not IsElement( loopGroups( member ) ) Then
loopGroups( member ) = loopingMember
End If
End If
End If
End If
End ForAll
Erase groupsInThread( groupName )
End Functionこれをエージェントにして実行すると、参照のループが始まるグループ(上の例では Grp2)はそのグループ名だけ表示します。そして、参照のループの途中にあるグループ(Grp4)と参照のループの最後のグループ(Grp5)には、そのグループ名に加えて参照のループが始まるグループ名を一緒に表示します。
下図は私の環境でテストした結果です。print文の出力が Notes クライアントの通知ウィンドウ内に表示されています。参照のループが始まっているのは「Nested Group 05」と「Nested Group 15」です。
HCL Domino 12.0 に「Entitlement Scan」という機能があります。この機能でサーバー上にあるアプリケーションを定期的にスキャンするのですが、そのときグループに参照のループがあるとコンソールにメッセージ「Groups cannot be nested more than 100 levels deep.」を記録します。このメッセージにグループ名は記録されません(下図)。
このメッセージが表示される場合、上のようなコードを使って参照のループを調べてみてはいかがでしょうか。


0 件のコメント:
コメントを投稿