As part of midPoint containerization for InCommon Trusted Access Platform we have developed the midPoint connector for Grouper has been developed. This document describes its installation and use.
There are two mechanisms used for midPoint ↔ Grouper communication:
- synchronous, REST-based i.e. "pull" communication where midPoint asks Grouper to provide data on a given group or groups,
- asynchronous, MQ-based i.e. "push" communication where Grouper asynchronously sends updates about changes to midPoint via RabbitMQAMQP-based solution.
You can use both (this is preferred), or only one of these mechanisms in your deployment. For example, if you have relatively small deployment and your are OK with the nightly Grouper→midPoint synchronization, you can choose synchronous REST communication only.
Installation and use
The connector JAR file should be put into
icf-connectors directory in midPoint home directory. Current version of the file can be downloaded from https://github.internet2.edu/docker/midPoint_container/blob/master/demo/grouper/midpoint_server/container_files/mp-home/icf-connectors/connector-grouper-rest-0.6.jar. (TODO: this JAR should be published in more appropriate way, maybe as part of standard midPoint Internet2 dockerization as discussed on weekly Zoom meeting.) This JAR contains REST-based part of the connector.
The connector is to be used within the context of a midPoint resource object. Let us describe the sample resource object used for midPoint-Grouper integration demo. Its current version can be found in Internet2 GitHub.
This resource uses combined REST + MQ connectors.
REST connector configuration
connections. The MQ part refers to
grouper Groovy function library that has to be installed (simply by importing the functional-library-grouper.xml file into midPoint repository). TODO this is to be resolved somehow. Maybe it should be part of the standard midPoint containerization as discussed on Jan 28th on the weekly Zoom meeting.
REST connector configuration
Sample configuration for REST connector Sample configuration for REST connector is here:
<icfc:configurationProperties> <rest:baseUrl>https://grouper-ws:443</rest:baseUrl> <rest:username>banderson</rest:username> <rest:password>password</rest:password> <rest:ignoreSslValidation>true</rest:ignoreSslValidation> <rest:baseStem>:</rest:baseStem> <rest:groupIncludePattern>app:.*</rest:groupIncludePattern> <rest:groupIncludePattern>test:.*</rest:groupIncludePattern> <rest:groupIncludePattern>ref:.*</rest:groupIncludePattern> <rest:groupExcludePattern>.*_(includes|excludes|systemOfRecord|systemOfRecordAndIncludes)</rest:groupExcludePattern> <rest:subjectSource>ldap</rest:subjectSource> <rest:testStem>:</rest:testStem> <!-- no testGroup: we cannot be sure that banderson is a member of sysadmingroup when doing the first test --> </icfc:configurationProperties>
|conf:sources||Source(s) for asynchronous messages. These can be e.g. MQ or REST endpoints, although midPoint currently supports only AMQP 0.9.1 or custom (defined e.g. via overlay) sources.|
|amqp091/uri||URI where AMQP 0.9.1 broker resides.|
|amqp091/username||Name of the user that is used to access AMQP 0.9.1 broker.|
|amqp091/password||Password of the user that is used to access AMQP 0.9.1 broker.|
|amqp091/queue||Queue from where change notifications can be obtained.|
|amqp091/virtualHost||AMQP virtual host.||The default value is "/".|
|amqp091/prefetch||Number of messages to prefetch.||The default is 5.|
|amqp091/connectionHandlingThreads||Number of connection handling threads. (Note that if you'd need real multithreaded asynchronous messages handling, you need to specify also the number of worker threads also for Async Update task. This is to be described elsewhere.)||The default is 10.|
|transformExpression/script/code:parameters||Parameters related to the processing of asynchronous messages obtained from (e.g.) AMQP queue.|
|groupIncludePattern||Groups that should be visible to this connector. Specify them using regular expressions like "ref:.*". You can specify multiple values of this item. Should be the same as groupIncludePattern in the REST part.||If nothing is specified, all groups under root stem are included.|
|groupExcludePattern||Groups that should not be visible to this connector. Specify them using regular expressions like ".*_(includes|excludes|systemOfRecord|systemOfRecordAndIncludes)". You can specify multiple values of this item. Should be the same as groupExcludePattern in the REST part.|
|relevantSubjectSource||The source of subjects that will be visible by this connector. Should be the same as subjectSource parameter in the REST part.|
SchemaHandling and Synchronization configuration
schemaHandling section describes how data in Grouper are mapped to data in midPoint. In principle, this is out of scope of the Grouper connector as such. However, in order for Grouper-midPoint integration to work, something reasonable should be configured here. Let us describe the configuration we created for midPoint-Grouper integration demo, explaining probable point of extension or customization.
- Grouper groups are mapped to midPoint organizations (OrgType). This is set by by
- "Raw" group name (e.g.
ref:affiliation:alum) is directly stored as as
extension/grouperNameproperty in the respective OrgType Org objects. This is set by the first inbound mapping on on
- Everything else is driven by appropriate Org archetype. By default, all groups are mapped to orgs with the "the
generic-grouper-group" archetype (OID OID
5f2b96d2-49b5-4a8a-9601-14457309a69bin the demo). But you can customize this in the second inbound mapping on on
ri:nameattribute (see lines 108-113 in the sample configuration).
- Map Grouper groups to midPoint organizations (as stated above).
- Group-organization matching is based on group name == organization organization
- When new Grouper group is found (situation = unmatched), midPoint organization should be created (action = addFocus).
- When Grouper group is found that has midPoint organization created but these two are not linked together (situation = unlinked), they should simply be linked (action = link).
- When Grouper group is deleted, midPoint organization should not be deleted immediately (situation = deleted, action is not deleteFocus). Instead, the custom group scavenger task revokes group membership gracefully and then deletes the organization. Again, this is out of scope of this document.
- When Grouper group information is updated (situation = linked), midPoint organization is updated. But, as a special case, if the change information came from MQ, and if the only changed information is the group membership, the complex org update (involving e.g. REST calls to Grouper) is skipped because of performance reasons. This is implemented in lines 149-165.
Overall, the the
schemaHandling and and
synchronization sections should be left "as they are". The only customization/extension point is the mapping of group name to appropriate Org archetype.