I am trying to get a betting understanding of the Corteza module structures and created a simply python script to create a plantuml diagram for the fields and relationships for all the modules.
Enjoy!
I am trying to get a betting understanding of the Corteza module structures and created a simply python script to create a plantuml diagram for the fields and relationships for all the modules.
Enjoy!
@HSorensen Quite cool; is the code publicly available? People may be interested in visualising their custom configurations.
Do you have a repo for this ?
I don’t claim any price for beauty, but this works for me:
# type: ignore
# Read properties from spike.properties file
# - Connect to Corteza server
# - Use JWT as authentication
#
# Generate ER diagram (will take some time):
# python3 corteza_entites.py > corteza_entities.plantuml
# java -jar plantuml.jar -progress -nbthread auto -verbose -o ./diagram corteza_entities.plantuml
#
import sys
import configparser
import json
import requests
from sortedcontainers import SortedList
def read_config(cfg_file):
"""a simple function to read an array of configuration files into a config object
"""
if cfg_file is not None:
config = configparser.ConfigParser()
config.read_file(cfg_file)
return config
def getNamespaceID(slug="crm"):
data = getNamespace(slug)
return data['response']['set'][0]['namespaceID']
def getNamespace(slug="crm"):
return queryCompose("namespace/?slug="+slug)
def getModules(namespaceID):
return queryCompose("namespace/"+namespaceID+"/module/")
def queryCompose(query):
CZA_URL = "http://" + CORTEZA_IP
CZA_URI = CZA_URL + "/api/compose/" + query
#print(CZA_URI)
CZA_HDR = {"Authorization": "Bearer " + CORTEZA_JWT}
response = requests.get(CZA_URI, None, headers=CZA_HDR)
if response.status_code == 200:
try:
dataJson = response.json()
# print(json.dumps(dataJson, indent=2, sort_keys=True))
except Exception as err:
print(response.text)
raise err
else:
print(response.status_code, response.text)
raise RuntimeError("REQUESTS ERROR "+CZA_URI+ " "+ response.status_code +" "+ response.text)
return dataJson
def buildUmlEntity(module,eid,refs):
l1 = SortedList() # required
l2 = SortedList() # optional fields
mid = module['moduleID']
if mid in refs:
print('ERRROR: module ' + module['name'] + ', already processed')
return ""
refs[mid] = {}
refs[mid]['eid']=eid
refs[mid]['refs'] = []
out='entity "' + module['name'] + '" as E' + str(eid) +' {\n'
for f in module['fields']:
if f['isRequired']:
l1.add(' *' + f['name'] + ' : ' + f['kind'])
else:
l2.add(' ' + f['name'] + ' : ' + f['kind'])
if f['kind'] == "Record":
refs[mid]['refs'].append(f['options']['moduleID'])
if len(l1)>0:
out += '\n'.join(l1)
out += '\n --\n'
out += '\n'.join(l2)
out += '\n}\n'
return out
def buildUmlEntityRelations(entityRefs):
rel="}o--||"
out = ""
# print(len(entityRefs))
for er in entityRefs.keys():
# print (er, entityRefs[er]['eid'])
if len(entityRefs[er]['refs'])>7:
dummy=None
# print("Too many refs: " + er + ":" + str(entityRefs[er]['refs']))
else:
for r in entityRefs[er]['refs']:
out += "E" + str(entityRefs[er]['eid']) + ' ' + rel + ' ' + "E" + str(entityRefs[r]['eid']) + "\n"
return out
def main(argv):
if len(argv) > 1:
variant = argv[1]
else:
variant = ""
#
# property file must have a section and properties:
# [spike-dev]
# CORTEZA_JWT=.....
# CORTEZA_IP=x.x.x.x
global CORTEZA_JWT
global CORTEZA_IP
spike_config = read_config(open("spike.properties"))
CORTEZA_JWT = spike_config["spike" + variant]["CORTEZA_JWT"]
CORTEZA_IP = spike_config["spike" + variant]["CORTEZA_IP"]
# Map module ID to entity
# { <moduleid> : { eid:"Enn", refs:[<moduleid>,...] }
# }
moduleidRefs = {}
# Keep track of entity count to create relationship
entitycnt = -1
out_entity_uml = "@startuml\nleft to right direction\n"
NAMESPACEID=getNamespaceID("crm")
modules=getModules(NAMESPACEID)
# print(json.dumps(modules, indent=2, sort_keys=True))
for m in modules['response']['set']:
entitycnt += 1
out_entity_uml += buildUmlEntity(m,entitycnt,moduleidRefs)
out_entity_uml += buildUmlEntityRelations(moduleidRefs)
out_entity_uml += "\n@enduml\n"
print(out_entity_uml)
return
if __name__ == "__main__":
main(sys.argv)
I don’t think we have a repository for such things (\cc @darh).
You can open a public GitHub repository and we can reference this tool from the documentation.