N°9604 - add "flowmaps" as a new neighbour (#914)

* Set DataFlow as FunctionalCI
* Use class name for Badge ID on DataFlow and Container classes including Typology
* Improve DataFlow summary
---------
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
This commit is contained in:
Vincent Dumas
2026-05-21 11:22:10 +02:00
committed by GitHub
parent 48e6203869
commit ba2af7ed63
4 changed files with 137 additions and 282 deletions

View File

@@ -1480,19 +1480,19 @@
<cell id="1" _delta="must_exist">
<rank>1</rank>
<dashlets>
<dashlet id="container_43" xsi:type="DashletBadge" _delta="define">
<dashlet id="ContainerApplication" xsi:type="DashletBadge" _delta="define">
<rank>5</rank>
<class>ContainerApplication</class>
</dashlet>
<dashlet id="container_44" xsi:type="DashletBadge" _delta="define">
<dashlet id="ContainerHost" xsi:type="DashletBadge" _delta="define">
<rank>6</rank>
<class>ContainerHost</class>
</dashlet>
<dashlet id="container_45" xsi:type="DashletBadge" _delta="define">
<dashlet id="ContainerCluster" xsi:type="DashletBadge" _delta="define">
<rank>7</rank>
<class>ContainerCluster</class>
</dashlet>
<dashlet id="container_46" xsi:type="DashletBadge" _delta="define">
<dashlet id="ContainerImage" xsi:type="DashletBadge" _delta="define">
<rank>8</rank>
<class>ContainerImage</class>
</dashlet>
@@ -1507,11 +1507,11 @@
<cell id="0">
<rank>0</rank>
<dashlets>
<dashlet id="container_21" xsi:type="DashletBadge" _delta="define">
<dashlet id="ContainerType" xsi:type="DashletBadge" _delta="define">
<rank>21</rank>
<class>ContainerType</class>
</dashlet>
<dashlet id="container_22" xsi:type="DashletBadge" _delta="define">
<dashlet id="ContainerImageType" xsi:type="DashletBadge" _delta="define">
<rank>22</rank>
<class>ContainerImageType</class>
</dashlet>

View File

@@ -2,7 +2,7 @@
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.3">
<classes>
<class id="DataFlow" _delta="define">
<parent>cmdbAbstractObject</parent>
<parent>FunctionalCI</parent>
<properties>
<category>bizmodel,searchable</category>
<abstract>false</abstract>
@@ -14,6 +14,10 @@
<attributes>
<attribute id="name"/>
</attributes>
<complementary_attributes>
<attribute id="source_id"/>
<attribute id="destination_id"/>
</complementary_attributes>
</naming>
<reconciliation>
<attributes>
@@ -32,23 +36,9 @@
</fields_semantic>
</properties>
<fields>
<field id="name" xsi:type="AttributeString">
<sql>name</sql>
<default_value/>
<is_null_allowed>false</is_null_allowed>
</field>
<field id="org_id" xsi:type="AttributeExternalKey">
<sql>org_id</sql>
<filter/>
<dependencies/>
<is_null_allowed>false</is_null_allowed>
<target_class>Organization</target_class>
<on_target_delete>DEL_MANUAL</on_target_delete>
<tracking_level>all</tracking_level>
</field>
<field id="source_id" xsi:type="AttributeExternalKey">
<sql>source_id</sql>
<filter/>
<filter><![CDATA[SELECT FunctionalCI WHERE finalclass != 'DataFlow']]></filter>
<dependencies/>
<is_null_allowed>false</is_null_allowed>
<target_class>FunctionalCI</target_class>
@@ -74,7 +64,7 @@
</field>
<field id="destination_id" xsi:type="AttributeExternalKey">
<sql>destination_id</sql>
<filter/>
<filter><![CDATA[SELECT FunctionalCI WHERE finalclass != 'DataFlow']]></filter>
<dependencies/>
<is_null_allowed>false</is_null_allowed>
<target_class>FunctionalCI</target_class>
@@ -107,12 +97,6 @@
<on_target_delete>DEL_MANUAL</on_target_delete>
<tracking_level>all</tracking_level>
</field>
<field id="description" xsi:type="AttributeHTML">
<sql>description</sql>
<default_value/>
<is_null_allowed>true</is_null_allowed>
<tracking_level>all</tracking_level>
</field>
<field id="status" xsi:type="AttributeEnum">
<sql>status</sql>
<values>
@@ -141,27 +125,6 @@
<display_style>list</display_style>
<tracking_level>all</tracking_level>
</field>
<field id="business_criticity" xsi:type="AttributeEnum">
<sort_type>rank</sort_type>
<values>
<value id="high">
<code>high</code>
<rank>10</rank>
</value>
<value id="medium">
<code>medium</code>
<rank>20</rank>
</value>
<value id="low">
<code>low</code>
<rank>30</rank>
</value>
</values>
<sql>business_criticity</sql>
<default_value>low</default_value>
<is_null_allowed>false</is_null_allowed>
<display_style>list</display_style>
</field>
<field id="execution_frequency" xsi:type="AttributeEnum">
<sort_type>rank</sort_type>
<values>
@@ -199,24 +162,36 @@
<is_null_allowed>false</is_null_allowed>
<display_style>list</display_style>
</field>
<field id="contacts_list" xsi:type="AttributeLinkedSetIndirect">
<linked_class>lnkContactToDataFlow</linked_class>
<ext_key_to_me>dataflow_id</ext_key_to_me>
<count_min>0</count_min>
<count_max>0</count_max>
<ext_key_to_remote>contact_id</ext_key_to_remote>
<duplicates/>
</field>
<field id="documents_list" xsi:type="AttributeLinkedSetIndirect">
<linked_class>lnkDocumentToDataFlow</linked_class>
<ext_key_to_me>dataflow_id</ext_key_to_me>
<count_min>0</count_min>
<count_max>0</count_max>
<ext_key_to_remote>document_id</ext_key_to_remote>
<duplicates/>
</field>
</fields>
<methods/>
<event_listeners>
<event_listener id="evtCheckSourceAndDestination">
<event>EVENT_DB_CHECK_TO_WRITE</event>
<rank>10</rank>
<callback>evtCheckSourceAndDestination</callback>
</event_listener>
</event_listeners>
<methods>
<method id="evtCheckSourceAndDestination" _delta="define">
<comment> /**
* Ensure that the source and destination of a data flow are not DataFlow themselves
*
*/</comment>
<static>false</static>
<access>public</access>
<type>EventListener</type>
<code><![CDATA[ public function evtCheckSourceAndDestination(Combodo\iTop\Service\Events\EventData $oEventData)
{
$oSource = MetaModel::GetObject(FunctionalCI::class, $this->Get('source_id'), false, true);
$oDestination = MetaModel::GetObject(FunctionalCI::class, $this->Get('destination_id'), false, true);
if ($oSource instanceof DataFlow) {
$this->AddCheckIssue(Dict::Format('Class:DataFlow/Error:CheckSource', $oSource->GetName()));
}
if ($oDestination instanceof DataFlow) {
$this->AddCheckIssue(Dict::Format('Class:DataFlow/Error:CheckDestination', $oDestination->GetName()));
}
} ]]></code>
</method>
</methods>
<presentation>
<list>
<items>
@@ -257,7 +232,7 @@
<items>
<item id="col:col1">
<items>
<item id="fieldset:DataFlow:baseinfo">
<item id="fieldset:ConfigMgmt:baseinfo">
<items>
<item id="name">
<rank>10</rank>
@@ -302,14 +277,25 @@
</item>
<item id="col:col2">
<items>
<item id="fieldset:DataFlow:otherinfo">
<item id="fieldset:ConfigMgmt:dates">
<items>
<item id="description">
<item id="move2production">
<rank>10</rank>
</item>
</items>
<rank>10</rank>
</item>
<item id="fieldset:ConfigMgmt:otherinfo">
<items>
<item id="description">
<rank>10</rank>
</item>
<item id="groups_list">
<rank>20</rank>
</item>
</items>
<rank>20</rank>
</item>
</items>
<rank>20</rank>
</item>
@@ -342,12 +328,18 @@
</default_search>
<summary>
<items>
<item id="org_id">
<item id="business_criticity">
<rank>10</rank>
</item>
<item id="description">
<item id="source_id">
<rank>20</rank>
</item>
<item id="destination_id">
<rank>30</rank>
</item>
<item id="execution_frequency">
<rank>40</rank>
</item>
</items>
</summary>
</presentation>
@@ -365,178 +357,17 @@
</neighbour>
</neighbours>
</relation>
<relation id="dataflows">
<neighbours>
<neighbour id="functionalci">
<query_down><![CDATA[SELECT FunctionalCI WHERE id = :this->destination_id]]></query_down>
<query_up><![CDATA[SELECT DataFlow AS f WHERE f.destination_id = :this->id]]></query_up>
<direction>both</direction>
</neighbour>
</neighbours>
</relation>
</relations>
</class>
<class id="lnkDocumentToDataFlow" _delta="define">
<parent>cmdbAbstractObject</parent>
<properties>
<is_link>1</is_link>
<category>bizmodel</category>
<abstract>false</abstract>
<key_type>autoincrement</key_type>
<db_table>lnkdocumenttodataflow</db_table>
<db_key_field>id</db_key_field>
<db_final_class_field/>
<naming>
<attributes>
<attribute id="document_id_friendlyname"/>
<attribute id="dataflow_id_friendlyname"/>
</attributes>
</naming>
<style>
<icon/>
</style>
<reconciliation>
<attributes>
<attribute id="dataflow_id"/>
<attribute id="document_id"/>
</attributes>
</reconciliation>
<uniqueness_rules>
<rule id="no_duplicate">
<attributes>
<attribute id="document_id"/>
<attribute id="dataflow_id"/>
</attributes>
<filter><![CDATA[]]></filter>
<disabled>false</disabled>
<is_blocking>true</is_blocking>
</rule>
</uniqueness_rules>
</properties>
<fields>
<field id="dataflow_id" xsi:type="AttributeExternalKey">
<sql>dataflow_id</sql>
<target_class>DataFlow</target_class>
<is_null_allowed>false</is_null_allowed>
<on_target_delete>DEL_AUTO</on_target_delete>
</field>
<field id="document_id" xsi:type="AttributeExternalKey">
<sql>document_id</sql>
<target_class>Document</target_class>
<is_null_allowed>false</is_null_allowed>
<on_target_delete>DEL_AUTO</on_target_delete>
</field>
</fields>
<methods/>
<presentation>
<details>
<items>
<item id="document_id">
<rank>10</rank>
</item>
<item id="dataflow_id">
<rank>20</rank>
</item>
</items>
</details>
<search>
<items>
<item id="dataflow_id">
<rank>10</rank>
</item>
<item id="document_id">
<rank>20</rank>
</item>
</items>
</search>
<list>
<items>
<item id="dataflow_id">
<rank>10</rank>
</item>
<item id="document_id">
<rank>20</rank>
</item>
</items>
</list>
</presentation>
</class>
<class id="lnkContactToDataFlow" _delta="define">
<parent>cmdbAbstractObject</parent>
<properties>
<is_link>1</is_link>
<category>bizmodel</category>
<abstract>false</abstract>
<key_type>autoincrement</key_type>
<db_table>lnkcontacttodataflow</db_table>
<db_key_field>id</db_key_field>
<db_final_class_field/>
<naming>
<attributes>
<attribute id="contact_id_friendlyname"/>
<attribute id="dataflow_id_friendlyname"/>
</attributes>
</naming>
<style>
<icon/>
</style>
<reconciliation>
<attributes>
<attribute id="dataflow_id"/>
<attribute id="contact_id"/>
</attributes>
</reconciliation>
<uniqueness_rules>
<rule id="no_duplicate">
<attributes>
<attribute id="contact_id"/>
<attribute id="dataflow_id"/>
</attributes>
<filter><![CDATA[]]></filter>
<disabled>false</disabled>
<is_blocking>true</is_blocking>
</rule>
</uniqueness_rules>
</properties>
<fields>
<field id="dataflow_id" xsi:type="AttributeExternalKey">
<sql>dataflow_id</sql>
<target_class>DataFlow</target_class>
<is_null_allowed>false</is_null_allowed>
<on_target_delete>DEL_AUTO</on_target_delete>
</field>
<field id="contact_id" xsi:type="AttributeExternalKey">
<sql>contact_id</sql>
<target_class>Contact</target_class>
<is_null_allowed>false</is_null_allowed>
<on_target_delete>DEL_AUTO</on_target_delete>
</field>
</fields>
<methods/>
<presentation>
<details>
<items>
<item id="contact_id">
<rank>10</rank>
</item>
<item id="dataflow_id">
<rank>20</rank>
</item>
</items>
</details>
<search>
<items>
<item id="dataflow_id">
<rank>10</rank>
</item>
<item id="contact_id">
<rank>20</rank>
</item>
</items>
</search>
<list>
<items>
<item id="dataflow_id">
<rank>10</rank>
</item>
<item id="contact_id">
<rank>20</rank>
</item>
</items>
</list>
</presentation>
</class>
<class id="DataFlowType" _delta="define">
<parent>Typology</parent>
<properties>
@@ -554,6 +385,16 @@
<attribute id="finalclass"/>
</attributes>
</reconciliation>
<uniqueness_rules>
<rule id="name">
<attributes>
<attribute id="name"/>
</attributes>
<filter><![CDATA[]]></filter>
<disabled>false</disabled>
<is_blocking>true</is_blocking>
</rule>
</uniqueness_rules>
</properties>
<fields/>
<methods/>
@@ -629,6 +470,15 @@
</neighbour>
</neighbours>
</relation>
<relation id="dataflows" _delta="define">
<neighbours>
<neighbour id="flow">
<query_down><![CDATA[SELECT DataFlow WHERE source_id = :this->id]]></query_down>
<query_up><![CDATA[SELECT FunctionalCI AS ci JOIN DataFlow AS f ON f.source_id = ci.id WHERE f.id = :this->id]]></query_up>
<direction>both</direction>
</neighbour>
</neighbours>
</relation>
</relations>
</class>
<class id="ApplicationSolution" _delta="must_exist">
@@ -726,7 +576,7 @@
<cells>
<cell id="3" delta="if_exists">
<dashlets>
<dashlet id="DataFlow_20" xsi:type="DashletBadge" _delta="define">
<dashlet id="DataFlow" xsi:type="DashletBadge" _delta="define">
<rank>20</rank>
<class>DataFlow</class>
</dashlet>
@@ -735,6 +585,21 @@
</cells>
</definition>
</menu>
<menu id="Typology" xsi:type="DashboardMenuNode" _delta="must_exist">
<definition>
<cells>
<cell id="0">
<rank>0</rank>
<dashlets>
<dashlet id="DataFlowType" xsi:type="DashletBadge" _delta="define">
<rank>23</rank>
<class>DataFlowType</class>
</dashlet>
</dashlets>
</cell>
</cells>
</definition>
</menu>
</menus>
<user_rights>
<groups>

View File

@@ -9,21 +9,25 @@
Dict::Add('EN US', 'English', 'English', [
'Relation:dataflows/Description' => 'DataFlows between CIs',
'Relation:dataflows/DownStream' => 'Outbound flows...',
'Relation:dataflows/DownStream+' => 'Outbound flows map from',
'Relation:dataflows/UpStream' => 'Inbound flows...',
'Relation:dataflows/UpStream+' => 'Inbound flows map to',
'Class:FunctionalCI/Attribute:dataflows' => 'Data flows',
'Class:FunctionalCI/Attribute:dataflows+' => 'Data flows for which this object is the source or the destination',
'FunctionalCI:DataFlow:Title' => 'Data flows',
'FunctionalCI:DataFlow:Inbound' => 'Inbound flows',
'FunctionalCI:DataFlow:Outbound' => 'Outbound flows',
'DataFlow:baseinfo' => 'General information',
'DataFlow:otherinfo' => 'Other information',
'DataFlow:moreinfo' => 'Flow specifics',
'Class:DataFlow' => 'Flow',
'Class:DataFlow+' => 'For application flow for example',
'Class:DataFlow/Name' => '%1$s',
'Class:DataFlow/ComplementaryName' => '%1$s - %2$s',
'Class:DataFlow/Attribute:name' => 'Name',
'Class:DataFlow/Attribute:name_id+' => 'Data that are transferred',
'Class:DataFlow/Attribute:name+' => 'Identify the transferred data flow',
'Class:DataFlow/Attribute:source_id' => 'Source',
'Class:DataFlow/Attribute:source_id+' => 'Source Ci of the flow',
'Class:DataFlow/Attribute:source_impact' => 'Source impacts?',
@@ -42,22 +46,10 @@ Dict::Add('EN US', 'English', 'English', [
'Class:DataFlow/Attribute:destination_impact/Value:no+' => 'If the flow stops, the destination is not impacted',
'Class:DataFlow/Attribute:dataflowtype_id' => 'Flow type',
'Class:DataFlow/Attribute:dataflowtype_id+' => 'Typology of Flow.',
'Class:DataFlow/Attribute:description' => 'Description',
'Class:DataFlow/Attribute:description+' => '',
'Class:DataFlow/Attribute:status' => 'Status',
'Class:DataFlow/Attribute:status+' => '',
'Class:DataFlow/Attribute:status/Value:active' => 'active',
'Class:DataFlow/Attribute:status/Value:inactive' => 'inactive',
'Class:DataFlow/Attribute:org_id' => 'Organization',
'Class:DataFlow/Attribute:org_id+' => '',
'Class:DataFlow/Attribute:business_criticity' => 'Business criticality',
'Class:DataFlow/Attribute:business_criticity+' => '',
'Class:DataFlow/Attribute:business_criticity/Value:high' => 'high',
'Class:DataFlow/Attribute:business_criticity/Value:high+' => '',
'Class:DataFlow/Attribute:business_criticity/Value:low' => 'low',
'Class:DataFlow/Attribute:business_criticity/Value:low+' => '',
'Class:DataFlow/Attribute:business_criticity/Value:medium' => 'medium',
'Class:DataFlow/Attribute:business_criticity/Value:medium+' => '',
'Class:DataFlow/Attribute:execution_frequency' => 'Execution frequency',
'Class:DataFlow/Attribute:execution_frequency+' => 'How often the data flow is executed',
'Class:DataFlow/Attribute:execution_frequency/Value:realtime' => 'real-time',
@@ -74,10 +66,13 @@ Dict::Add('EN US', 'English', 'English', [
'Class:DataFlow/Attribute:execution_frequency/Value:monthly+' => '',
'Class:DataFlow/Attribute:execution_frequency/Value:yearly' => 'yearly',
'Class:DataFlow/Attribute:execution_frequency/Value:yearly+' => '',
'Class:DataFlow/Attribute:documents_list' => 'Documents',
'Class:DataFlow/Attribute:documents_list+' => 'Eg: technical specifications, runbooks, etc.',
'Class:DataFlow/Attribute:contacts_list' => 'Contacts',
'Class:DataFlow/Attribute:contacts_list+' => 'Eg: flow owner, technical support, etc.',
'Class:DataFlow/Error:CheckSource' => 'The source of a data flow cannot be a data flow itself. Choose another source CI than %1$s',
'Class:DataFlow/Error:CheckDestination' => 'The destination of a data flow cannot be a data flow itself. Choose another destination CI than %1$s',
'Class:DataFlowType' => 'Data Flow Type',
'Class:DataFlowType+' => 'Typology of Data Flow',
/*
'Class:DataFlow/Attribute:source_id_friendlyname' => 'source_id_friendlyname',

View File

@@ -9,21 +9,25 @@
Dict::Add('FR FR', 'French', 'Français', [
'Relation:dataflows/Description' => 'Flux de données entre CIs',
'Relation:dataflows/DownStream' => 'Flux sortants...',
'Relation:dataflows/DownStream+' => 'Carte des flux sortants depuis',
'Relation:dataflows/UpStream' => 'Flux entrants...',
'Relation:dataflows/UpStream+' => 'Carte des flux entrants vers',
'Class:FunctionalCI/Attribute:dataflows' => 'Flux de données',
'Class:FunctionalCI/Attribute:dataflows+' => 'Flux de données dont cet objet est la source ou la destination',
'FunctionalCI:DataFlow:Title' => 'Flux de données',
'FunctionalCI:DataFlow:Inbound' => 'Flux entrants',
'FunctionalCI:DataFlow:Outbound' => 'Flux sortants',
'DataFlow:baseinfo' => 'Informations générales',
'DataFlow:otherinfo' => 'Autres informations',
'DataFlow:moreinfo' => 'Spécificités du flux',
'Class:DataFlow' => 'Flux de Données',
'Class:DataFlow+' => 'Modélise les données transférées entre instances d\'application',
'Class:DataFlow/Name' => '%1$s',
'Class:DataFlow+' => 'Modélise les données transférées entre instances d\'application ou plus généralement entre CIs.',
'Class:DataFlow/ComplementaryName' => '%1$s - %2$s',
'Class:DataFlow/Attribute:name' => 'Nom',
'Class:DataFlow/Attribute:name_id+' => 'Type de données transferées',
'Class:DataFlow/Attribute:name+' => 'Identifie le flux de données',
'Class:DataFlow/Attribute:source_id' => 'Source',
'Class:DataFlow/Attribute:source_id+' => 'Instance d\application à la source du flux de données',
'Class:DataFlow/Attribute:source_impact' => 'Source impactante ?',
@@ -42,22 +46,10 @@ Dict::Add('FR FR', 'French', 'Français', [
'Class:DataFlow/Attribute:destination_impact/Value:no+' => 'Si le flux s\'arrête, le destinataire n\'est pas impacté',
'Class:DataFlow/Attribute:dataflowtype_id' => 'Type de flux',
'Class:DataFlow/Attribute:dataflowtype_id+' => 'Typologie du flux',
'Class:DataFlow/Attribute:description' => 'Description',
'Class:DataFlow/Attribute:description+' => '',
'Class:DataFlow/Attribute:status' => 'Etat',
'Class:DataFlow/Attribute:status+' => '',
'Class:DataFlow/Attribute:status/Value:active' => 'actif',
'Class:DataFlow/Attribute:status/Value:inactive' => 'inactif',
'Class:DataFlow/Attribute:org_id' => 'Organisation',
'Class:DataFlow/Attribute:org_id+' => '',
'Class:DataFlow/Attribute:business_criticity' => 'Criticité',
'Class:DataFlow/Attribute:business_criticity+' => '',
'Class:DataFlow/Attribute:business_criticity/Value:high' => 'haute',
'Class:DataFlow/Attribute:business_criticity/Value:high+' => '',
'Class:DataFlow/Attribute:business_criticity/Value:low' => 'basse',
'Class:DataFlow/Attribute:business_criticity/Value:low+' => '',
'Class:DataFlow/Attribute:business_criticity/Value:medium' => 'moyenne',
'Class:DataFlow/Attribute:business_criticity/Value:medium+' => '',
'Class:DataFlow/Attribute:execution_frequency' => 'Fréquence d\'exécution',
'Class:DataFlow/Attribute:execution_frequency+' => 'À quelle fréquence le transfert de données est-il exécuté',
'Class:DataFlow/Attribute:execution_frequency/Value:realtime' => 'temps réel',
@@ -74,10 +66,13 @@ Dict::Add('FR FR', 'French', 'Français', [
'Class:DataFlow/Attribute:execution_frequency/Value:monthly+' => '',
'Class:DataFlow/Attribute:execution_frequency/Value:yearly' => 'annuelle',
'Class:DataFlow/Attribute:execution_frequency/Value:yearly+' => '',
'Class:DataFlow/Attribute:documents_list' => 'Documents',
'Class:DataFlow/Attribute:documents_list+' => 'Eg: technical specifications, runbooks, etc.',
'Class:DataFlow/Attribute:contacts_list' => 'Contacts',
'Class:DataFlow/Attribute:contacts_list+' => 'Eg: flow owner, technical support, etc.',
'Class:DataFlow/Error:CheckSource' => 'La source d\'un flux de données ne peut pas être un flux de données elle-même. Choisissez un autre CI source que %1$s',
'Class:DataFlow/Error:CheckDestination' => 'La destination d\'un flux de données ne peut pas être un flux de données elle-même. Choisissez un autre CI destination que %1$s',
'Class:DataFlowType' => 'Type de flux',
'Class:DataFlowType+' => 'Typologie des flux de données',
/*
'Class:DataFlow/Attribute:source_id_friendlyname' => 'source_id_friendlyname',