Skip to main content
July 23, 2025
Solved

Is it possible to extract(as xml) a Maintenance Unit and it's components using extensibility rule?

  • July 23, 2025
  • 4 replies
  • 0 views

Hello OneStream experts, 

We are trying to extract a maintenance unit and all it's components underneath it using a BR/Extensibility rule with the latest OS version - 9.0.1. 

But, however after the run we could able to see a empty xml in the fileshare folder. 

Below is the snippet of code which we are using. 

Any suggestions or help would be greatly appreciated. Thanks!

Public Function Main(ByVal si As SessionInfo, ByVal globals As BRGlobals, ByVal api As Object, ByVal args As ExtenderArgs) As Object
			Try
				Select Case args.FunctionType
					Case Is = ExtenderFunctionType.ExecuteDataMgmtBusinessRuleStep, ExtenderFunctionType.Unknown
						'Get Configuration Settings
							Dim configSettings As AppServerConfigSettings = AppServerConfig.GetSettings(si)
							'Data Management extract location
							Dim folderPath As String = FileShareFolderHelper.GetDataManagementExportUsernameFolderForApp(si, True, configSettings.FileShareRootFolder,
							 si.AppToken.AppName
							 ) & "\" & DateTime.UtcNow.ToString("yyyyMMdd") & "\Extracts"  'If the directory does not exist create
						If Not Directory.Exists(folderPath) Then Directory.CreateDirectory(folderPath)
							'Full path and file name for extract
							Dim filePath As String = folderPath & "\MaintainanceUnitBkp " & DateTime.UtcNow.ToString("yyyyMMdd") & ".xml"
						'If file already exist
						If File.Exists(filePath) Then File.Delete(filePath)
						'Extract Options
'						Dim xmlOptions As New XmlExtractOptions
'						xmlOptions.ExtractAllItems = False
						
						Dim xmlOptions As New XmlExtractOptions
						Dim dashboardOptions As New DashboardMaintUnit
						
						xmlOptions.ExtractAllItems = False


'Extract Maintainance Unit
Dim extractDict As New Dictionary(Of XmlExtractItemPk, Boolean)

Dim strMaintUnit As String = "DataExtract_Main" 'Maintenance Unit
extractDict.Add(New XmlExtractItemPk(XmlExtractItemType.DashboardMaintUnit, strMaintUnit), True)

'Execute the Metadata Extract
						Using dbConnFW As DbConnInfo = BRApi.Database.CreateFrameworkDbConnInfo(si)
							Using dbConnApp As DbConnInfo = BRApi.Database.CreateApplicationDbConnInfo(si)
								'Extract XML metadata to target location
								File.WriteAllText(filePath, MetadataExtract.ExtractXml(dbConnFW, dbConnApp, xmlOptions, extractDict))
								File.WriteAllText(filePath,XmlExtractController.ExtractXML(dbConnFW,dbConnApp,Nothing,xmlOptions,extractDict,XmlLoadExtractType.ApplicationWorkspaces))
							End Using
						End Using
Best answer by RobbSalzmann

The way to do this is to "build up" your xml file with the things you add to the extractDict. If you want a maintenance unit, you need to first add types DashboardWorkspaces, DashboardWorkspace, and DashboardMaintUnits.  If you look at the XML for an ApplicationWOrkspace export, it has these types on the outside enclosing the maintenance units.  

Look at how the xml file is composed when you export Application Workspaces through the Load/Extract screen.  The use that as your pattern to build up your extract dict.  Here I'm extracting a maintenance unit with a Workspace Assembly.  Use this pattern...

This code will extract the maintenance unit, its assembly, components, adapters, and groups within that maintenance unit:
modify it using this pattern to get what you want out of your maintenance unit.

Dim xmlOptions As New XmlExtractOptions() With {
    .ExtractAllItems = False
}

' Define the maintenance unit to extract
Dim extractDict As New Dictionary(Of XmlExtractItemPk, Boolean)()
Dim maintUnitId As New Guid("A76AC44C-88E0-4115-BE03-B6B29F890998")
Dim workspaceId As New Guid("BA09DD97-F470-4865-A4C8-F5B55EC7E03B")
Dim assemblyId As New Guid("0ACA5739-73A1-44B5-BE57-A8235B7C9F82")

extractDict.Add(New XmlExtractItemPk(XmlExtractItemType.DashboardWorkspaces, SharedConstants.Unknown), True)
extractDict.Add(New XmlExtractItemPk(XmlExtractItemType.DashboardWorkspace, workspaceId), True)
extractDict.Add(New XmlExtractItemPk(XmlExtractItemType.DashboardMaintUnits, workspaceId), True)
extractDict.Add(New XmlExtractItemPk(XmlExtractItemType.DashboardMaintUnit, maintUnitId), True)
extractDict.Add(New XmlExtractItemPk(XmlExtractItemType.WorkspaceAssemblies, maintUnitId), True)
extractDict.Add(New XmlExtractItemPk(XmlExtractItemType.WorkspaceAssembly, assemblyId), True)
extractDict.Add(New XmlExtractItemPk(XmlExtractItemType.DashboardAdapters, maintUnitId), True)
extractDict.Add(New XmlExtractItemPk(XmlExtractItemType.DashboardComponents, maintUnitId), True)
extractDict.Add(New XmlExtractItemPk(XmlExtractItemType.Groups, maintUnitId), True)

' Execute the metadata extract
Using dbConnFW As DbConnInfo = BRApi.Database.CreateFrameworkDbConnInfo(si)
    Using dbConnApp As DbConnInfo = BRApi.Database.CreateApplicationDbConnInfo(si)
        Dim xmlContent As String = XmlExtractController.ExtractXml(
            dbConnFW,
            dbConnApp,
            Nothing,
            xmlOptions,
            extractDict,
            XmlLoadExtractType.ApplicationWorkspaces
        )

        BRApi.ErrorLog.LogMessage(si, xmlContent)

        ' Write output to file
        File.WriteAllText(filePath, xmlContent)
    End Using
End Using

 

4 replies

July 23, 2025

The way to do this is to "build up" your xml file with the things you add to the extractDict. If you want a maintenance unit, you need to first add types DashboardWorkspaces, DashboardWorkspace, and DashboardMaintUnits.  If you look at the XML for an ApplicationWOrkspace export, it has these types on the outside enclosing the maintenance units.  

Look at how the xml file is composed when you export Application Workspaces through the Load/Extract screen.  The use that as your pattern to build up your extract dict.  Here I'm extracting a maintenance unit with a Workspace Assembly.  Use this pattern...

This code will extract the maintenance unit, its assembly, components, adapters, and groups within that maintenance unit:
modify it using this pattern to get what you want out of your maintenance unit.

Dim xmlOptions As New XmlExtractOptions() With {
    .ExtractAllItems = False
}

' Define the maintenance unit to extract
Dim extractDict As New Dictionary(Of XmlExtractItemPk, Boolean)()
Dim maintUnitId As New Guid("A76AC44C-88E0-4115-BE03-B6B29F890998")
Dim workspaceId As New Guid("BA09DD97-F470-4865-A4C8-F5B55EC7E03B")
Dim assemblyId As New Guid("0ACA5739-73A1-44B5-BE57-A8235B7C9F82")

extractDict.Add(New XmlExtractItemPk(XmlExtractItemType.DashboardWorkspaces, SharedConstants.Unknown), True)
extractDict.Add(New XmlExtractItemPk(XmlExtractItemType.DashboardWorkspace, workspaceId), True)
extractDict.Add(New XmlExtractItemPk(XmlExtractItemType.DashboardMaintUnits, workspaceId), True)
extractDict.Add(New XmlExtractItemPk(XmlExtractItemType.DashboardMaintUnit, maintUnitId), True)
extractDict.Add(New XmlExtractItemPk(XmlExtractItemType.WorkspaceAssemblies, maintUnitId), True)
extractDict.Add(New XmlExtractItemPk(XmlExtractItemType.WorkspaceAssembly, assemblyId), True)
extractDict.Add(New XmlExtractItemPk(XmlExtractItemType.DashboardAdapters, maintUnitId), True)
extractDict.Add(New XmlExtractItemPk(XmlExtractItemType.DashboardComponents, maintUnitId), True)
extractDict.Add(New XmlExtractItemPk(XmlExtractItemType.Groups, maintUnitId), True)

' Execute the metadata extract
Using dbConnFW As DbConnInfo = BRApi.Database.CreateFrameworkDbConnInfo(si)
    Using dbConnApp As DbConnInfo = BRApi.Database.CreateApplicationDbConnInfo(si)
        Dim xmlContent As String = XmlExtractController.ExtractXml(
            dbConnFW,
            dbConnApp,
            Nothing,
            xmlOptions,
            extractDict,
            XmlLoadExtractType.ApplicationWorkspaces
        )

        BRApi.ErrorLog.LogMessage(si, xmlContent)

        ' Write output to file
        File.WriteAllText(filePath, xmlContent)
    End Using
End Using

 

July 23, 2025

You will have to go one by one and get everything under that maintenance unit. All items will get you all the maintenance units. You can then probably edit the XML and get what you want. But if it is just a backup, I would go with all options and back up all the maintenance units.

July 24, 2025

Does it have to be a BR? This is exactly what XFProject files solve: the export and import of full maintenance units with as little as 5 lines of xml.

July 25, 2025

RobbSalzmann​ , ckattookaran​ , db_pdx​ - Thank you all for your valuable responses.

Robb - I wrote the below code to extract entire maintenance unit without specifying each objects and it is working as expected. Here, I made "isExtractAllItems = True". The code isolates the desired maintenance unit from the extracted XML, reconstructs a minimal XML structure containing just this unit (and its workspace context), and saves the result as a new XML file for backup or migration purposes. And both the methods were tested and both works as expected. 

Thanks everyone for the inputs!
Cheers!

Case Is = ExtenderFunctionType.Unknown, ExtenderFunctionType.ExecuteDataMgmtBusinessRuleStep
					
						
						'Get Configuration Settings
							Dim configSettings As AppServerConfigSettings = AppServerConfig.GetSettings(si)
							'Data Management extract location
							Dim folderPath As String = FileShareFolderHelper.GetDataManagementExportUsernameFolderForApp(si, True, configSettings.FileShareRootFolder,
							 si.AppToken.AppName
							 ) & "\" & DateTime.UtcNow.ToString("yyyyMMdd") & "\Extracts"  'If the directory does not exist create
						If Not Directory.Exists(folderPath) Then Directory.CreateDirectory(folderPath)
							'Full path and file name for extract
							Dim filePath As String = folderPath & "\Dashboards " & DateTime.UtcNow.ToString("yyyyMMdd") & ".xml"
						'If file already exist
						If File.Exists(filePath) Then File.Delete(filePath)
						
							Dim isExtractAllItemsTrue = True
							Dim isExtractUniqueIdsTrue = True 
							Dim xmlOptions As New XmlExtractOptions(isExtractAllItemsTrue, isExtractUniqueIdsTrue) 
							Dim xmlString As String = String.Empty
							Dim maintUnitToExtract As String = "YourMaintenanceUnit"							
							
							
							' extract specified items doesn't seem to work, but we need it
							Dim extractDict As New Dictionary(Of XmlExtractItemPk, Boolean) From {
								{New XmlExtractItemPk(XmlExtractItemType.DashboardMaintUnit, maintUnitToExtract), True}
																								}	
							
							'Execute the Metadata Extract
							Using dbConnFW As DBConnInfo = BRAPi.Database.CreateFrameworkDbConnInfo(si)
								Using dbConnApp As DBConnInfo = BRAPi.Database.CreateApplicationDbConnInfo(si)
									xmlString = XmlExtractController.ExtractXML(dbConnFW, dbConnApp, Nothing, xmlOptions, extractDict, XmlLoadExtractType.ApplicationWorkspaces)
								End Using
							End Using	
							
							Dim xmlDoc As XDocument = XDocument.Parse(xmlString)
							Dim extractedMaintUnitElement As XElement = xmlDoc.Descendants("maintenanceUnit").Where(Function(mu) mu.Attribute("name").Value = maintUnitToExtract).FirstOrDefault()
							
							If extractedMaintUnitElement IsNot Nothing Then
							    Dim workspaceElement = extractedMaintUnitElement.Ancestors("workspace").FirstOrDefault()
							    Dim newWorkspaceElement As New XElement("workspace", workspaceElement.Attributes())
							    newWorkspaceElement.Add(New XElement("maintenanceUnits", extractedMaintUnitElement))
						
							    Dim newXmlDoc As New XDocument(
							        New XElement("OneStreamXF", xmlDoc.Root.Attributes(),
							            New XElement("applicationWorkspacesRoot",
							            	New XElement("workspaces", newWorkspaceElement)
							            )
							        )
							    )
							    newXmlDoc.Save(filePath)
							
							End If		
				End Select