:: Version 2.7.0 ::

Prevent duplicates

Prerequisite: You must be familiar with the Syntax used in Tutorials and have already created an extension.

learning:
Configure uniqueness rules
level:
Beginner
domains:
XML, Constrain, Dictionary
min version:
2.6.0

By customizing iTop, you can specify on a class, uniqueness rules, to prevent duplicate entries.
In this Tutorial we will see:

  • How uniqueness rules behave from a user perspective
  • How to define new uniqueness rules
  • Uniqueness rules defined on Person class in iTop out of the box
  • Removing an existing uniqueness rule

Behavior

  • A rule would specify the scope of objects on which the uniqueness must be checked. For example, you don't want to have two persons with the same employee number, unless that number is empty. The scope would then be every Person with employee_number not empty.
  • During a single creation or modification made on the console or the portal, a rule can either
    • block the creation/update of the object

  • or just display a warning message after the creation/update.

  • A uniqueness rule applies on one or multiple fields of the class (including ExternalFields)
  • Uniqueness on attribute types such as File, Image, Dashboard, Stopwatch,… are not supported (incomplete list).
If you want a Uniqueness Rule for a Person on Organization and Employee number, but this rule only applies to your company, then you define the scope of the rule to be “Only Persons of organization XXX”

Default rules

In Standard Data Model, we have added those rules:
  • Class Brand, id=name, field name must be unique.
  • Class Model, id=name_brand, fields: name + brand_id must be unique.
  • Class Person, id=employee_number fields: org_id + employee_number must be unique only if employee_id is defined.
  • Class Person, id=name, fields: org_id + first_name + name should be unique (warning only).

Defining your own rule

For defining Uniqueness rules we only need to write XML.

Unique name within sub-classes

In this usecase we want to prevent any FunctionalCI to have the same name as another FunctionalCI only if they both belong to the same sub-class. For example a NetworkDevice and a Server can have the same name, but two Servers must not have the same name.

itop-design / classes / class@FunctionalCI / properties
        <uniqueness_rules>
          <rule id="functionalci_name" _delta="define">
            <!-- field or combination of "FunctionalCI" fields which must be unique -->
            <attributes>
              <attribute id="name"/>
              <attribute id="finalclass"/>
            </attributes>
          <!-- ... -->
itop-design / dictionaries / dictionary@EN US / entries
<entry id="Class:FunctionalCI/UniquenessRule:functionalci_name">
  <![CDATA[there is already a '$this->finalclass$' with the same name]]>
</entry>
Note the use of the placeholder '$this->finalclass$' within the error message

This could also have been done as separate uniqueness rule on each an every sub-class, but that's more work.

FYI: finalclass is a magic attribute which only exist on classes which are abstract or have a parent other than cmdbAbstractObject or DBObject.

Unique name across sub-classes

In this use case we want to prevent two FunctionalCIs to have the same name. Except if the FunctionalCI is in fact a SoftwareInstance, a MiddlewareInstance, a DatabaseSchema or an ApplicationSolution, in which case, we don't care.

Let's assume we have just two FunctionalCI in our iTop:

  • a NetworkDevice named “test.combodo.com”
  • and a ApplicationSolution named “iTop”

What we can and cannot do:

  • This rule will prevent creation of a Server named “test.combodo.com” as a NetworkDevice exists already with that same name
  • It will prevent the rename of a Server into “test.combodo.com” as a NetworkDevice exists already with that same name
  • It will allow creation of a Server named “iTop” as the existing ApplicationSolution named “iTop” is part of the final classes which are filtered out
itop-design
  <classes>
    <class id="FunctionalCI" _delta="must_exist">
      <properties>
        <uniqueness_rules>
          <!-- For the "id" it must be a single word without special character but underscore -->
          <rule id="functionalci_name" _delta="define">
            <!-- field or combination of "FunctionalCI" fields which must be unique -->
            <attributes>
              <attribute id="name"/>
            </attributes>
            <!-- Define an OQL WHERE clause with condition on FunctionalCI fields -->
            <!-- It will be combined this way "SELECT FunctionalCI WHERE " + <filter> -->
            <filter><![CDATA[
               finalclass NOT IN ('DBServer','Middleware',
              'OtherSoftware','WebServer','PCSoftware','MiddlewareInstance',
              'DatabaseSchema','ApplicationSolution')]]>
            </filter>
            <!-- This flag allow you to keep the rule in the XML but desactivate it -->
            <disabled>false</disabled>
            <!-- If true or ommitted, a duplicate is blocking the creation/update -->
            <!-- otherwise it displays a warning message after creation/update -->
            <is_blocking>true</is_blocking>
          </rule>
        </uniqueness_rules>
      </properties>
    </class>
  </classes>
  <dictionaries>
    <dictionary id="EN US" _delta="must_exist">
      <entries>
        <entry id="Class:FunctionalCI/UniquenessRule:functionalci_name" _delta="define">
          <![CDATA[There are already a Functional CI with that name, please use another name.]]>
        </entry>
        <entry id="Class:FunctionalCI/UniquenessRule:functionalci_name+" _delta="define">
          <![CDATA[FunctionalCI name should be unique]]>
        </entry>
      </entries>
    </dictionary>
  </dictionaries>
Note the syntax of a dictionary entry “Class:” + class-name + “/UniquenessRule:” + rule_id
  • This entry is used for the error message related to the Uniqueness rule.
  • The same code with a + at the end, correspond to a description of the Uniqueness rule, not yet displayed anywhere, but probably one day, it will be displayed in the Datamodel viewer.

Existing Rules on Person

Let's look at the existing uniqueness rules on Person, provided by default in iTop. There are 2 rules:

employee_number

  • It's a blocking rule, it will prevent creation/update in case of error
  • It will prevent two persons belonging to the same organization to have the same employee number,
  • An empty employee number is allowed and will not generate an error, even if other persons exist with an empty employee number in the same organization.
  • Two persons can have the same non-empty employee number only if they belongs to two different organizations.

name

  • This rule is just a warning, it does not prevent creation/update, it just display a message.
  • It is generated if there is an homonym within the same organization

Here is how they have been defined:

itop-design / classes / class@Person / properties
   <uniqueness_rules>
      <rule id="employee_number">
         <attributes>
            <attribute id="org_id"/>
            <attribute id="employee_number"/>
         </attributes>
         <!-- Empty employee_number is allowed and will not be treated as a duplicate -->
         <filter><![CDATA[employee_number != '']]></filter>
         <disabled>false</disabled>
         <is_blocking>true</is_blocking>
       </rule>
       <rule id="name">
          <attributes>
             <attribute id="org_id"/>
             <attribute id="name"/>
             <attribute id="first_name"/>
          </attributes>
          <filter/>
          <disabled>false</disabled>
          <is_blocking>false</is_blocking>
       </rule>
     </rules>
   </uniqueness_rules>

Removing a Rule

In this example we will remove an existing uniqueness rule, which is in the default iTop datamodel. In order to remove a uniqueness rule, you need to know two things:

  • on which class it has been declared, here “Person”
  • and its rule_id here ''employee_number

Removing a rule requires a piece of XML embedded in an extension, just like adding a rule. The important piece here is _delta=“delete” within the upper node which must be removed with all its sub-nodes

itop-design / classes
    <class id="Person" _delta="must_exist">
      <properties>
        <uniqueness_rules>
          <rule id="employee_number" _delta="delete"/>
        </uniqueness_rules>
        </properties>
      </class>

Partially disabling a rule

In this usecase we suppose that this rule was defined on FunctionalCI:

classes / class@FunctionalCI / properties
        <uniqueness_rules>
          <rule id="functionalci_name" _delta="define">
            <!-- field or combination of "FunctionalCI" fields which must be unique -->
            <attributes>
              <attribute id="name"/>
              <attribute id="finalclass"/>
            </attributes>
          <!-- ... -->

and we want to change it for DatacenterDevice (which is a child class of FunctionalCI), for which we want a different behavior with a uniqueness of name across all sub-classes of DatacenterDevice.

For this we disable the parent class rule “functionalci_name” and define a new rule, here “datacenterdevice_name”.

classes / class@DatacenterDevice / properties
        <uniqueness_rules>
          <!-- here we use the same rule_id as the rule we want to stop -->
          <!-- We are on a child class, so the node is new, which explain the _delta="define" -->
          <rule id="functionalci_name" _delta="define">
            <!-- 'disabled' is the only tag supported when overwriting an existing rule_id -->
            <!-- It disables the 'functionalci_name' rule that for DatacenterDevices -->
            <disabled>true</disabled>
          </rule>
          <!-- then we can add another rule or not... -->                    
          <rule id="datacenterdevice_name" _delta="define">
            <attributes>
              <attribute id="name"/>
            </attributes>
          <!-- ... -->
A rule id must be unique within each branch of the class hierarchy!
Reusing one within a branch is only allowed to disable the parent rule
2_7_0/customization/uniqueness-rules.txt · Last modified: 2020/04/15 15:23 (external edit)
Back to top
Contact us