10.7:documentation:adm:provisioning_context

Provisioning context

Provisioning context is used to optimize provisioning by allowing you to prepare data earlier than in individual attributes. The purpose is to avoid load the same data in multiple attributes.

An example might be the need to compute a value of an attribute based on identity contracts. In such a case, it is possible to load this contracts through the relevant service as part of the transformation into the system. However, a problem can arise if we need these same contracts in the other five attributes. At such a moment, it would mean 4 times unnecessary loading of the same contracts.

The solution to this situation is to use provisionig context, which allows you to load a contracts only once and distribute them to each attribute.

Provisioning context can be defined in two ways. The first is to check the predefined options on detail of mapping, that will fill the predefined context items. It is also possible to insert into the context any other object that we need to propagate. For this purpose, a map is included in the context, where the key is a String item and the value is Object.

The predefined context structure:

  • Add a contracts - Loads all identity contracts and adds them to the context (context.getContracts()).
  • Add a roles - Loads all assigned identity roles and adds them to the context (context.getIdentityRoles()).
  • Add roles that assign this system - Loads all assigned identity roles that this system assigns and adds them to the context (context.getIdentityRolesForSystem()).
  • Add an object from the target system - Loads an object from the target system and adds it to the context (context.getConnectorObject()).

The map in the context:

  • Insert object to the context map: context.put(key, value), where key is String and value Object.
  • Get object from the context map: context.get(key), where key is String.

For easy access to the context object, suggestions have been implemented that describe context methods (name, description, return type of the method). These suggestions are used in context scripts, in transformation to the system, and in all scripts that have a 'mapping context' category.

Using the context is very simple. Suppose we want to solve the problem described in the example above. Ie. we need to create a context that will contain all the identity contracts for which provisioning is performed.

  1. Provisioning context is defined on the mapping on the context tab (this tab is visible only for mapping with the provisioning type). On this tab, just check the item 'Add a contracts'. This automatically reads all identity contracts and puts them in context.
  2. Next is only need to use the data from the context in the attributes. This can be done in a transformation into a system whose input attribute is context. To get a list of a contracts can be used 'context.getContracts()' method.

Another example of using context. We want one of the attributes to return a list of objects containing the value eav "JobNameEAV" from all user contracts, including contract status information. For example, {"JobName": "job1", "State": "true"}, {"JobName": "job2", "State": "false"}

First of all, we must define provisioning context in the mapping of the system

We use this script in attribute mapping details:

import eu.bcvsolutions.idm.core.eav.api.dto.IdmFormInstanceDto;
import eu.bcvsolutions.idm.core.api.dto.IdmIdentityContractDto
 
contracts = context.get("contractFormInstances") 
 
def result = new ArrayList();
 
for( Serializable contractId : contracts.keySet()) {    //loop through contracts
	IdmFormInstanceDto contractFormInstance = contracts.get(contractId);
	String JobNameEav = (String) contractFormInstance.toSinglePersistentValue("JobNameEAV"); //get eav value
	def contract = context.getContracts().find{contractId.equals(it.getId())}; //finds the current contract
	if (JobNameEav){
	   Map<String,String> map = new HashMap<String,String>();
	   map.put("JobName", JobNameEav);
	   map.put("State", contract.isValid()); //return true if the current contract is valid 
	   result.add(map);
	}
}
return result; // return list all objects

Another example of using context.

Provisioning context in the mapping of the system

We use this script in attribute mapping details:

import eu.bcvsolutions.idm.core.api.utils.DtoUtils
import eu.bcvsolutions.idm.core.api.dto.IdmRoleDto;
import eu.bcvsolutions.idm.core.model.entity.IdmIdentityRole_
import eu.bcvsolutions.idm.core.api.dto.IdmIdentityRoleDto
import eu.bcvsolutions.idm.core.eav.api.dto.IdmFormInstanceDto;
import org.apache.commons.lang3.StringUtils;
 
def contracts = context.get("contractFormInstances")
def result = new ArrayList();
def values = new HashSet();
def roles = context.getIdentityRolesForSystem(); /get all identity roles for system
 
def getLogin(contracts, entity, domain, context) {
        def validContracts = context.getContracts(). findAll {contract -> contract.isValid()} .findAll {contract ->
            IdmFormInstanceDto contractFormInstance = contracts.get(contract.id) //list of all valid identity contract
        }      
 
        for (def validContract : validContracts) { //loop through valid contracts
            IdmFormInstanceDto contractFormInstance = contracts.get(validContract.id) 
            String login = (String) contractFormInstance.toSinglePersistentValue("EAVlogin");
 
            if(login){ 
                StringBuilder sb = new StringBuilder();
                sb.append(login);
                sb.append(domain);
                domainLogin = sb.toString()
            }
        }
        if(domainLogin){
            return domainLogin;
        }
}
 
for (def identityRoleDto : roles ){
    IdmRoleDto roleDto = DtoUtils.getEmbedded(identityRoleDto, IdmIdentityRole_.role);
    def roleCode = roleDto.getCode();
 
    if(roleCode == "Role1"){ 
    values.add(getLoginForCompany(contracts, entity,"@email1.CZ", context));
    }
 
    else if(roleCode == "Role2"){ 
    values.add(getLoginForCompany(contracts, entity,"@email2.CZ", context));
    }
 
    else if(roleCode == "Role3"){ 
    values.add(getLoginForCompany(contracts, entity, "@email3.CZ", context));
    }
 
}
 
if (values) {
    return result    
}