Skip to content
Permalink
a2b389f25d
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
192 lines (174 sloc) 10.3 KB
<!--
~ Copyright (c) 2019 Evolveum and contributors
~
~ This work is dual-licensed under the Apache License 2.0
~ and European Union Public License. See LICENSE file for details.
-->
<role xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
xmlns:apti="http://midpoint.evolveum.com/xml/ns/public/common/api-types-3"
xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
xmlns:icfs="http://midpoint.evolveum.com/xml/ns/public/connector/icf-1/resource-schema-3"
xmlns:org="http://midpoint.evolveum.com/xml/ns/public/common/org-3"
xmlns:q="http://prism.evolveum.com/xml/ns/public/query-3"
xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
oid="bcaec940-50c8-44bb-aa37-b2b5bb2d5b90">
<name>metarole-grouper-provided-group</name>
<description>A metarole for archetyped Grouper-provided groups</description>
<!--
This metarole arranges everything that is needed for a Grouper group to live in midPoint.
The schema is the following:
Grouper group -> shadow -> org -> archetype -> this metarole
e.g.
ref:affiliation:member -> shadow -> affiliation_member -> affiliation (archetype) -> metarole-grouper-provided-group
1) Grouper group (e.g. ref:affiliation:member) has a shadow object.
2) An org object (affiliation_member) is created and linked to this shadow.
3) At the same time, appropriate archetype is assigned to the org, based on the Grouper name
(e.g. ref:affiliation:* leads to archetype affiliation).
4) This archetype defines basic parameters for the particular class of Grouper groups; e.g. where in midPoint
org tree they belong (e.g. under Affiliations org), where in LDAP tree they belong (e.g. under
ou=Affiliations,ou=Groups,dc=internet2,dc=edu), what's the schema for their midPoint name
(e.g. affiliation_...) and displayName (e.g. Affiliation: ...).
5) To avoid code duplication, these archetypes delegate specific processing
(i.e. filling-in appropriate properties of org objects) to metaroles:
to this one as well as to metarole-ldap-group.
This metarole is devoted to process Grouper-specific information for Grouper groups.
As a source it needs only two pieces of information: extension/grouperName (e.g. ref:affiliation:member)
and particular archetype (e.g. affiliation) with its configuration data.
It fills-in the following items: extension/grouperName -> identifier -> name and displayName
by inducing appropriate focus mappings to the org object.
-->
<inducement>
<focusMappings>
<mapping>
<name>identifier</name>
<description>This mapping fills-in org identifier (e.g. 'member') from extension/grouperName (e.g. 'ref:affiliation:member').
It uses extension/grouperNamePrefix information from the archetype (e.g. 'ref:affiliation:' defined in affiliation archetype)</description>
<strength>strong</strength>
<source>
<path>extension/grouperName</path>
</source>
<expression>
<script>
<code>
if (grouperName == null) {
null
} else {
archetype = assignmentPath[-2].source // e.g. archetype affiliation
log.info('archetype = {}', archetype)
if (archetype == null) {
throw new IllegalStateException('No archetype in assignment path: ' + assignmentPath)
}
grouperNamePrefix = basic.getExtensionPropertyValue(archetype, 'grouperNamePrefix') // e.g. 'ref:affiliation:'
if (grouperNamePrefix == null) {
throw new IllegalStateException('No grouper name prefix in archetype ' + archetype)
}
// grouperName is e.g. 'ref:affiliation:member'
if (grouperName.startsWith(grouperNamePrefix)) {
grouperName.substring(grouperNamePrefix.length()) // returning e.g. 'member'
} else {
throw new IllegalStateException('Grouper name ' + grouperName + ' does not match the expected prefix: ' + grouperNamePrefix)
}
}
</code>
</script>
</expression>
<target>
<path>identifier</path>
</target>
</mapping>
<mapping>
<name>name</name>
<description>This mapping fills-in org name (e.g. 'affiliation_member') from identifier (e.g. 'member').
It uses extension/midPointNamePrefix information from the archetype (e.g. 'affiliation_' defined in affiliation archetype)</description>
<strength>strong</strength>
<source>
<path>identifier</path>
</source>
<expression>
<script>
<code>
if (identifier == null) {
null
} else {
// e.g. identifier = 'member'
archetype = assignmentPath[-2].source // e.g. affiliation archetype
if (archetype == null) {
throw new IllegalStateException('No archetype in assignment path: ' + assignmentPath)
}
prefix = basic.getExtensionPropertyValue(archetype, 'midPointNamePrefix') // e.g. 'affiliation_'
prefix + identifier // e.g. 'affiliation_member'
}
</code>
</script>
</expression>
<target>
<path>name</path>
</target>
</mapping>
<mapping>
<name>displayName</name>
<description>This mapping fills-in org displayName (e.g. 'Affiliation: member') from identifier (e.g. 'member').
It uses extension/midPointDisplayNamePrefix information from the archetype (e.g. 'Affiliation: ' defined in affiliation archetype)</description>
<strength>strong</strength>
<source>
<path>identifier</path>
</source>
<expression>
<script>
<code>
if (identifier == null) {
null
} else {
archetype = assignmentPath[-2].source // e.g. affiliation archetype
if (archetype == null) {
throw new IllegalStateException('No archetype in assignment path: ' + assignmentPath)
}
prefix = basic.getExtensionPropertyValue(archetype, 'midPointDisplayNamePrefix') // e.g. 'Affiliation: '
prefix + identifier // e.g. 'Affiliation: member'
}
</code>
</script>
</expression>
<target>
<path>displayName</path>
</target>
</mapping>
<mapping>
<name>lifecycle state</name>
<description>This mapping sets org lifecycle state to be either "active" or "retired", depending on
whether Grouper group for this org still exists. Orgs in the latter state are on the way to deletion:
their members are unassigned and after no members are there, the org is automatically deleted.</description>
<strength>strong</strength>
<expression>
<script>
<code>
import com.evolveum.midpoint.model.impl.expr.*
import com.evolveum.midpoint.schema.*
import com.evolveum.midpoint.xml.ns._public.common.common_3.*
GROUPER_RESOURCE_OID = '1eff65de-5bb6-483d-9edf-8cc2c2ee0233'
modelContext = ModelExpressionThreadLocalHolder.lensContext
rsd = new ResourceShadowDiscriminator(GROUPER_RESOURCE_OID, ShadowKindType.ENTITLEMENT, 'group', null, false)
if (modelContext.findProjectionContext(rsd) != null) {
log.info('Projection context for Grouper group found, marking as "active"')
'active'
} else {
log.info('No projection context for Grouper group, marking as "retired"')
'retired'
}
</code>
</script>
</expression>
<target>
<path>lifecycleState</path>
</target>
</mapping>
</focusMappings>
<!--
Inducement order of 2 means these mappings are to be applied on org object, because the assignment structure is like this:
org -> archetype -> this-metarole
-->
<order>2</order>
</inducement>
</role>