Written by

Question Adam Lees · Jun 18, 2021

Export production documentation to Archimate model?

I'm aware of the function to export a Production documentation to PDF or HTML format https://docs.intersystems.com/healthconnect20201/csp/docbook/DocBook.UI.PortalHelpPage.cls?KEY=Ensemble%2C%20Production%20Configuration#ECONFIG_production_documentation

What I'm looking for is the easiest way to export to an architecture model in the Archimate format.  Specifically to create files in the CSV Import/Export format supported by the open source Archi tool.  This would be high level information of primarily Business Services and Business Operations, with basic metadata like the Adapter class, and information on the source or target system (IP address, URL, file folder etc).  If possible it would be able to infer some relationships between systems such as "system A" has an HL7 feed to MyProduction which routes to "System B".  

Archimate import has 3 files. "elements.csv", "relations.csv" and "properties.csv"

So it should be possible to populate elements (from the services and operations) and properties (from Settings) and relations from inferred links.  

Before I start reinventing any wheels are there any open source or inexpensive COTS tools to do this kind of thing or has anybody attempted this before able to share any learning.

Comments

André-Claude Gendron · Jun 18, 2021

I would be very much interested in your findings. I already started something that is producing a CSV  file with a summary of a production. Perhaps this could be helpful to the community, contact me in private since I can't attach a file. This is not ment for Archi mate but perhaps you can be inspired by it. 

0
Adam Lees  Jun 18, 2021 to André-Claude Gendron

André-Claude, thank you very much, that would be a great starting point.  I will message you. 

If you have code that you are willing to share with the community, it's worth considering putting it into a public repo on Github.

0
Eduard Lebedyuk · Jun 18, 2021

I had a similar requirement (only for automatic docs generation).

As each BH setting is also a class property, you can query %Dictionary for them. And build your CSVs from these queries.

 

Queries

/// Settings common for all Interoperability BH
Query defaultSettings() As %Query
{
SELECT
   prop.name "Setting",
   TRIM('"' FROM MAX(prop.InitialExpression)) "Default value",
   LIST(prop.parent) "Class",
   MAX(prop.Description) "Description"
FROM "%Dictionary".PropertyDefinition prop
JOIN "%Dictionary".CompiledParameter par ON par.parent = prop.parent AND par.Name = 'SETTINGS'
JOIN "%Dictionary".CompiledClass cls ON prop.parent = cls.Name
WHERE (cls.Super LIKE '%Ens.Host%' OR cls.Name = 'Ens.Host' OR cls.Name = 'Ens.BusinessProcessBPL') AND
       par."_Default" LIKE '%' || prop.Name || '%'
GROUP BY prop.Name
ORDER BY 1
}

/// User BH classes
Query productionClasses() As %Query
{
SELECT
   Name "Class",
   Description "Description"
FROM "%Dictionary".CompiledClass cls
WHERE Name LIKE '%'
       AND Super In ('Ens.BusinessProcessBPL', 'Ens.BusinessService', 'Ens.BusinessOperation', 'Ens.BusinessProcess')
ORDER BY 1
}

/// Settings for User BH
Query productionClassesSettings() As %Query
{
SELECT
   prop.parent "Class",
   prop.name "Setting",
   TRIM('"' FROM prop.InitialExpression) "Default value",
   prop.Description "Description"
FROM "%Dictionary".PropertyDefinition prop
JOIN "%Dictionary".CompiledParameter par ON par.parent = prop.parent AND par.Name = 'SETTINGS'
JOIN "%Dictionary".CompiledClass cls ON prop.parent = cls.Name
WHERE cls.Name LIKE '%' AND par."_Default" LIKE '%' || prop.Name || '%'
ORDER BY 1,2
}


/// Production elements
Query productionItems(production) As %Query
{
SELECT
   Name,
   ClassName
   /*,Comment*/
FROM Ens_Config.Item
WHERE Production = :production
}

/// Get settings of production item
Query productionItemsSettingsCall(production) As %Query
{
SELECT *
FROM User_util.productionItemsSettings(:production)
}

/// Custom query - get settings for production items
Query productionItemsSettings(production As %String) As %Query(CONTAINID = 0, ROWSPEC = "Element:%String,Setting:%String,Host:%String,Value:%String") [ SqlName = productionItemsSettings, SqlProc ]
{
}

ClassMethod productionItemsSettingsExecute(ByRef qHandle As %Binary, production As %String) As %Status
{
    set obj = ##class(Ens.Config.Production).%OpenId(production,,.sc)
    quit:$$$ISERR(sc) sc
    do ..clearProductionItems(.obj)
    set qHandle("production") = obj
    set qHandle("item") = 1
    set qHandle("itemCount") = qHandle("production").Items.Count()

    set qHandle("setting") = 1
    set qHandle("settingCount") = qHandle("production").Items.GetAt(qHandle("item")).Settings.Count()
    quit sc
}

ClassMethod productionItemsSettingsFetch(ByRef qHandle As %Binary, ByRef Row As %List, ByRef AtEnd As %Integer = 0) As %Status [ PlaceAfter = productionItemsSettingsExecute ]
{
        #dim sc As %Status = $$$OK
        #dim item As Ens.Config.Item = qHandle("production").Items.GetAt(qHandle("item"))
        #dim setting As Ens.Config.Setting = item.Settings.GetAt(qHandle("setting"))

        set AtEnd = 0
        set Row = $lb(item.Name, setting.Name, setting.Target, setting.Value)
       
        if qHandle("setting")<qHandle("settingCount") {
                set qHandle("setting") = qHandle("setting") + 1
        } else {
                if qHandle("item")<qHandle("itemCount") {
                        set qHandle("item") = qHandle("item") + 1
                        set qHandle("setting") = 1
                        set qHandle("settingCount") = qHandle("production").Items.GetAt(qHandle("item")).Settings.Count()
                } else {
                        set AtEnd = 1
                }
        }
       
     quit sc
}

/// Remove production items without settings.
ClassMethod clearProductionItems(ByRef production As Ens.Config.Production)
{
    #dim item As Ens.Config.Item
    for i = production.Items.Count():-1:1 {
        set item = production.Items.GetAt(i)
        do:item.Settings.Count()=0 production.Items.RemoveAt(i)
    }
}
0