Consistency mechanism is a part of midPoint that takes care of cases when midPoint cannot carry out the operation as it wants to. Inconsistencies form in these cases. Inconsistencies are the difference between what midPoint thinks that should be and what really is. Inconsistencies may happen if midPoint wants to create an account but the resource is down, if midPoint try to create an account but it finds that the account already exists and in many more cases. These may be caused by network outages, resource downtime, changes that happen outside midPoint, parallel and concurrent execution of tasks and also by technology limitations (e.g. connector unable to report all the changes). In practice inconsistencies happen all the time. Therefore a mechanism to handle them is an essential part of any IDM solution.
Consistency in midPoint
MidPoint implements consistency mechanisms at several layers:
- Operations that cannot be executed synchronously are postponed (e.g. in case a resource is down)
- Inconsistencies discovered during execution of operations are processed before the operation is finished (e.g. midPoint finds existing account while trying to create it)
- All the inconsistencies are detected and processed during a reconciliation process
Postponing the operations
Provisioning errors are divided into groups of known problems. One of these groups are problems in communication with the external resource, for example the resource is down, timeout occur during processing request etc. In this situation, when we recognize that the resource is unavailable, we postpone the actually processed operation to be able to process it when the resource goes online. The postponing operation means that we store actually processed object (shadow) to the local midpoint's repository. This object contains some additional information that make it clear what went wrong and what need to be done to finish the operation successfully.
Example - adding
In the case, that the admin tries to add new account on the resource which is down at this moment, we store the whole account's shadow to the midpoint's repository. This shadows (in contrast with regular shadows) contains all account's attributes and additional information:
- Failed operation type (in this case ADD)
- Operation result (result of the operation with the error explaining what went wrong)
- Attempt number (how many times we have try to re-add the account yet)
Example – modifying (exists)
In the case when admin tries to modify account that is actually present on the resource, but resource is unavailable, we store the delta to corresponding shadow into the midpoint's repository. Such shadow then contains additional information:
- Failed operation type (in this case MODIFY)
- Operation result
- Attempt number
- Object delta (modification that will be applied when the resource goes online)
Example – modifying (not exists yet)
Administrator may also try to modify attributes of account that have not been created yet on the external resource (e.g. Administrator tries to add account, but resource was unavailable and we have only shadow in midpoint's repository and no account on the external resource). In this scenario, modifications are applied directly to the shadow in the local midpoint's repository and when the resource goes online, the new account is created. Additional information in this case is:
- Failed operation type (ADD – so we need to execute only one operation (add) instead of two (add and than modify))
- Operation result
- Attempt number
Example – deleting
Administrator tries to delete account on the unavailable resource. The shadow is not deleted, but it is unlinked from the user. In this situation we store these additional information to the shadow in repository:
- Failed operation (DELETE)
- Dead (true, describes that the shadow is actually dead but we wait for the external resource to goes online and so we can delete the account from the resource and also shadow from the midpoint's repository)
- Operation result
- Attempt number
Finishing operation is done in two ways, either by discovery or by reconciliation process. These processes are described later.
For postponing operation you do not need any additional configuration. Additional configurations are needed for compensating groups of problems when object is not found on the resource or object with the same identifier already exists on the resource. In both situation you need to configure synchronization part of the resource. By the object already exists problems you need to configure also maximal number of iteration which may be executed to find identifier that is not in conflict with any other.
Discovery is used as one way to detect and eliminate the inconsistencies. It runs while executing operation when we recognize that something with the processed object is not okay. For example, the user tries to get account that is not actually present on the resource but only the shadow exists in the midpoint's repository. This shadow was created during resource unavailability and the account needs to be created on the resource when it goes online. Another example is, when the shadow contains pending modification. In this case, when the resource is not up, we first try to apply this modifications to the account and then return the most fresh account. Also, if the administrator gets the account that is not found on the resource, but the shadow exists we run discovery to find out what to do with this present shadow.
Handling different situations
Get – with previous problem in communication with resource while adding account
When the provisioning is requested to get account from the resource and only incomplete shadow exists (this shadow does not have the identifier of the real account on the resource), we run the discovery and tries to complete the previous operation (in this case, create account on the resource). Discovery may be a quite a long process and it is not good to run it by every get request when we are not sure that the resource is up now. Therefore, the discovery by get operation runs only if the resource is up (the resource has last availability status which tells us if the resource is up or down). After finishing the operation successfully, the new account is created on the resource and we return this, most fresh, account. If the resource is still unavailable we do not run discovery and we return the incomplete shadow.
Get – with previous problem in communication with resource while modifying account
This situation is similar to previous one, with one difference that if the resource is up and we run discovery, the account is not created, but pending modifications are applied to the account on the resource and the most fresh object is returned.
Get – object is not found on the external resource
In this scenario, administrator tries to get account, that is not present on the external resource. Or example, such situation can be formatted if the external resource does not support synchronization and someone deletes the account directly from the resource. Now, we have shadow in the midpoint's repository that has invalid link to the real account. We run discovery to find out what to do with such shadow. There are two possibilities, either the shadow is deleted or the account on the resource is re-created. It depends on the way, how the original account was created. If it was created using assignment, the result of the discovery is re-created account on the external resource which we return to administrator. If the account was created directly (not using assignment), the shadow is deleted.
For the discovery machanism we do not need any additional settings. All what you need is to have configured synchronization part in the resource description.
Reconciliation process (also called synchronization) is a standard way how identity management systems solve possible inconsistencies. It is used to scan external resource and find out changes that have been not applied yet because of some reason, e.q. when administrator made changes on external resource, synchronization was suspended. In the midPoint we use this standard reconciliation process, but we also add another option. In out reconciliation process we process not only changes from the external resource but also the changes from the local midPoint's repository. In this way, we add opaque direction for handling. In the direction from midpoint's repository to external resource, we search through shadows and if the one with additional information is found, we try to process it and complete previous failed operation.