Friday, October 22, 2010

DXL To The Rescue



The other day I came across an issue in a lotus notes application that was kind of weird.  The user was getting the ***** error when trying to edit a group in the ACL. 

The first thing that came to mind was to check the users access, but they had Manager access to the application.  They just wanted to remove a \ that was put in the name of a group by mistake, so I tried to make the change myself, but I also got the same error.  I also tried to remove the entry from the ACL, but also got the same error.  The next thing that came to mind was to code an agent to remove the entry by using the back-end lotusscript objects. 

So this is what I came up with:

    Dim targetDB As NotesDatabase
    Dim targetACL As NotesACL
    Dim targetEntry As NotesACLEntry
   
    Set targetDB = New NotesDatabase("", "")
   
    If(targetDB.Open("Server", "db.nsf"))Then
        Set targetACL = targetDB.Acl
        Set targetEntry = targetACL.Getentry("Group With / in its name")
        If(Not(targetEntry Is Nothing))Then
            'targetEntry.Name = "TestEntry"
            Call targetEntry.Remove()
            Call targetACL.Save()
        Else
            Print "Entry not found in ACL"
        End If
    Else
        Print "Not able to open db"
    End If


But when I tried running the agent I got the same error when trying to execute the line Call targetACL.Save().  I then did some searching on the web and found a few people with the same error, but most of them suggested the ACL was corrupt and that the way they solved the issue was to create a new application and copy the data over, but this would only be an option for me as a last resort.  Since it seemed like the cause was the ACL had become corrupt I thought I'd export the ACL to DXL and verify if there was anything strange in the XML. 

I created the following agent to export the ACL:

    Dim s As New NotesSession
    Dim targetDB As NotesDatabase
    Dim fileName As String
   
    Set targetDB = New NotesDatabase("", "")
   
    If(targetDB.Open("Server", "db.nsf"))Then
        REM Open xml file named after target database
        Dim stream As NotesStream
        Set stream = s.CreateStream()
        fileName = "c:\temp\" & Left(targetDB.FileName, Len(targetDB.FileName) - 3) & "xml"
        If Not stream.Open(fileName) Then
            Print "Cannot open " & fileName
            Exit Sub
        End If
        Call stream.Truncate
         
        Dim exporter As NotesDXLExporter
        Set exporter = s.CreateDXLExporter
       
        REM Create note collection of actions
        Dim nc As NotesNoteCollection
        Set nc = targetDB.CreateNoteCollection(False)
        nc.Selectacl = true
        Call nc.BuildCollection
       
        Set exporter = s.CreateDXLExporter(nc)
       
        Call exporter.SetInput(nc)
        Call exporter.SetOutput(stream)

        ' Stops the from being added to output.
        exporter.OutputDOCTYPE = False

        Call exporter.Process
    Else
        Print "Could not open db"
    End If


After running this agent the following content was generated in the Test.xml:



 replicaid='852574830021CC9F' path='CN=Test/OU=Test/OU=Server/O=Test!!db.nsf'
 title='Test DB' usejavascriptinpages='false'>

 percentused='97.7727051598594' numberofdocuments='39'>
 dst='true'>20101006T162213,08-04

>20101007T094423,47-04



 writepublicdocs='false'/>


 deletedocs='true'/>


 level='editor' deletedocs='true' createpersonalagents='false' createpersonalviews='false'
 createsharedviews='false' createlsjavaagents='false'/>
10/06/2010 04:20:38 PM Test User/Test/Test updated Test Admins
10/06/2010 04:20:31 PM Test User/Test/Test added Test Admins


Since I did not see anything strange in the ACL DXL I decided to create an agent that would import the ACL DXL after removing the group with the / in it's name from the DXL.  This is what the agent looked like:

    Dim s As New NotesSession
    Dim targetDB As NotesDatabase
    Dim fileName As String
   
    Set targetDB = New NotesDatabase("", "")

    If(targetDB.Open("Server", "db.nsf"))Then
        REM Open xml file named after target database
        Dim stream As NotesStream
        Set stream = s.CreateStream()
        fileName = "c:\temp\" & Left(targetDB.FileName, Len(targetDB.FileName) - 3) & "xml"
        If Not stream.Open(fileName) Then
            Print "Cannot open " & fileName
            Exit Sub
        End If

        If stream.Bytes = 0 Then
            Print "File did not exist or was empty"
            Exit Sub
        End If
        
        'Import DXL into new database
        Dim importer As NotesDXLImporter
        Set importer = s.CreateDXLImporter(stream, targetDB)
        importer.ReplicaRequiredForReplaceOrUpdate = False
        importer.ACLImportOption = DXLIMPORTOPTION_REPLACE_ELSE_IGNORE

        Call importer.Process
    Else
        Print "Could not open db"
    End If



After running this agent I verified the ACL of the application and the group was no longer there.  I also tested that new entries could be added and modified without issues.

Has anybody run into similar issues before, where you had to resort to DXL for a fix?

0 comments: