<xsd:schema elementFormDefault="qualified"
targetNamespace="http://example.com/xml/ns/mySchema"
xmlns:tns="http://example.com/xml/ns/mySchema"
xmlns:a="http://prism.evolveum.com/xml/ns/public/annotation-3"
xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="UserExtensionType">
<xsd:annotation>
<xsd:appinfo>
<a:extension ref="c:UserType"/>
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="officeNumber" type="xsd:string" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:appinfo>
<a:indexed>true</a:indexed>
<a:displayName>office number</a:displayName>
<a:displayOrder>120</a:displayOrder>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="favoriteColor" type="xsd:string" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:appinfo>
<a:indexed>false</a:indexed>
<a:displayName>favorite color</a:displayName>
<a:displayOrder>130</a:displayOrder>
<a:help>The favorite color</a:help>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="facility" type="xsd:string" minOccurs="1" maxOccurs="1">
<xsd:annotation>
<xsd:appinfo>
<a:indexed>true</a:indexed>
<a:displayName>facility</a:displayName>
<a:displayOrder>135</a:displayOrder>
<a:help>The address of the facility where the employees office resides</a:help>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="officePhone" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<a:indexed>false</a:indexed>
<a:displayName>office telephone number</a:displayName>
<a:displayOrder>140</a:displayOrder>
<a:help>The office telephone number</a:help>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
Custom Schema Extension
MidPoint has quite a rich user schema with many attributes that are common for most IDM deployments. But if there are attributes that are not really common the best option is to extend user schema. It is quite easy. The User schema is extended by adding appropriate XSD file to the midPoint installation. The schema extension is not stored in the database because it may influence the database schema and therefore may create a chicken-egg problem.
The custom schema extension is specified in the XML Schema Description (XSD) format similar to other schemas in midPoint.
It is using XSD annotations to specify details that XSD cannot specify.
E.g. it is using an a:extension
annotation to bind the complex type definition to the midPoint object type.
Example
Following example provides a custom schema extension.
It extends the schema of UserType as is defined by the a:extension
XSD annotation.
The example defines two properties: officeNumber
and favoriteColor
.
This file is all it takes to extend the schema. It extends user with two custom attributes:
Name | Display Name | Type | |
---|---|---|---|
|
office number |
string |
Optional, single-value |
|
favorite color |
string |
Optional, multi-value |
|
facility |
string |
Mandatory, single-value |
|
office telephone number |
string |
Mandatory, single-value |
Attribute name is the name by which midPoint knows the attribute. It is used in mappings and configuration. Display name is what midPoint will display in forms and reports. Attribute type determines the type and range or attribute values. The schema may also define attribute multiplicity, whether it is mandatory or optional, define the order in which it will be displayed in forms, define a help text, etc. Most of that is defined using XSD annotations and it is optional.
Defining the schema extension is all that midPoint needs to make full use of the attribute.
Once it is defined in the schema midPoint will display the attribute in the GUI and it will be displayed
using suitable user field, checked for mandatory value, the attribute may be used in mappings, etc.
It will behave as if it was always a part of midPoint.
The small additional configuration is required only when these attributes are used in mappings.
Then you have to let configuration know in which namespace it should look for an attribute definition.
This is the namespace introduced by the attribute targetNamespace
in the header of the extension XSD file.
<user>
<name>jack</name>
<extension>
<officeNumber>001</officeNumber>
<favoriteColor>Black with white skull on it</favoriteColor>
</extension>
<fullName>Jack Sparrow</fullName>
...
</user>
A more complex schema examples are provided in the git samples/schema directory.
Installing Custom Schema Extension
Currently, the custom schema extension has to be available to midPoint at the startup time. It is not stored in the repository (database) and cannot be dynamically changed when the system is running.
The schema files have to be placed in the schema
subdirectory of midpoint.home directory.
The name of the file does not matter as long as it ends with .xsd
extension.
There also may be subdirectories.
When MidPoint starts it scans the directory and all subdirectories and loads all the schemas that it finds there.
After any change in custom schema extension definition(s), you need to restart midPoint. |
Data Types Supported
Extension items fall into two categories depending on how they are stored in midPoint repository: indexed and not indexed.
-
Not indexed items are stored in object’s XML representation only. So they are preserved by the repository, but it is not possible to select objects by their values. E.g. in the example above, it is possible to formulate a query "give me all users with extension/officeNumber = '111'" but not "give me all users with extension/favoriteColor = 'green'".
-
Indexed items are stored in object’s XML representation, as well as in extra columns that are used for querying objects based on their properties' values. So they can be used in object queries.
For non-indexed extension items, all data types are supported.
For indexed items, the following types are fully supported:
XML type (Java type) |
How is it stored in Native repository? |
How is it stored in Generic repository? |
---|---|---|
xsd:string (String) |
stored in |
table |
xsd:int (Integer) |
stored in This is not JSON/EcmaScript limited number, but virtually limitless PostgreSQL numeric value. |
table |
xsd:long (Long) |
||
xsd:integer (BigInteger) |
table |
|
xsd:boolean (Boolean) |
stored in |
table |
xsd:dateTime (XMLGregorianCalendar) |
stored in |
table |
t:PolyStringType |
stored in |
table |
c:ObjectReferenceType |
stored in |
table |
enumerations |
stored in |
table |
Java types are mentioned as well, because they are relevant when the real value of the extension item is used, for instance, in scripting expressions using Groovy.
The default value for indexed
flag (i.e. the XSD annotation) is true
for the above supported types,
and it can be switched to false
if the property is not important for searching.
For other property types, complex types or extension containers (and their content) it is false
and cannot be changed to true
.
It is only possible to search by the properties on the top level of the extension container.
Word "indexed" here means that the information is externalized in the repository in such a way that the query against that item is possible. It does not necessarily mean, that it is well indexed for all supported oprations. Indexing everything on the DB level for every possible filter type is simply not reasonable, there are always compromises and specific index can be added for critical queries as needed. But this always depends on the specific deployment and you should consult your DB admin about it. Basic cases should be reasonably well indexed out-of-the-box. See Index tuning for more information. |
The following table lists partially supported types, describing the limitations:
Type | Prism/GUI limitations | Repository support |
---|---|---|
xsd:short (Short) |
Not fully supported by Prism API, no support on GUI. |
Full support.
Native repo stores it in Generic repo stores it in |
xsd:decimal (BigDecimal) |
Not fully supported by Prism API |
Full support in the Native repo, stored in Generic repo stores it in
|
xsd:double (Double) |
No support on GUI. |
|
xsd:float (Float) |
It is recommended to use one of the fully supported types from the first table instead of these types.
Using midPoint types
It is possible to define custom attributes using midPoint types. For example, if there is a need to specify various activation status types for users in your environment, it is possible to define a custom attribute for activation using ActivationStatusType type. If there is another requirement e.g. for supporting more than one password for the user, ProtectedStringType can be used in such a case. To allow using of midPoint types, proper schemas have to be added to the extension schema definition using import element as the example below shows:
<xsd:schema elementFormDefault="qualified"
targetNamespace="http://example.com/xml/ns/mySchema"
xmlns:tns="http://example.com/xml/ns/mySchema"
xmlns:a="http://prism.evolveum.com/xml/ns/public/annotation-3"
xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="http://midpoint.evolveum.com/xml/ns/public/common/common-3"/>
<xsd:import namespace="http://prism.evolveum.com/xml/ns/public/types-3"/>
<xsd:complexType name="UserExtensionType">
<xsd:annotation>
<xsd:appinfo>
<a:extension ref="c:UserType"/>
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="customAdministrativeStatus" type="c:ActivationStatusType" minOccurs="0">
<xsd:annotation>
<xsd:appinfo>
<a:indexed>true</a:indexed>
<a:displayName>Custom Administrative status</a:displayName>
<a:displayOrder>250</a:displayOrder>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="secondaryPassword" type="t:ProtectedStringType" minOccurs="0">
<xsd:annotation>
<xsd:appinfo>
<a:indexed>false</a:indexed>
<a:displayName>Secondary Password</a:displayName>
<a:displayOrder>260</a:displayOrder>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>