The info on this page applies to Grouper 2.6 and above. |
The connection between the Grouper Provisioning framework and the target is the target DAO (data access object). This is an interface where the available/applicable methods are implemented.
Base class: edu.internet2.middleware.grouper.app.provisioning.targetDao.GrouperProvisionerTargetDaoBase
Here are some target DAO methods
TargetDaoInsertGroupResponse insertGroup(TargetDaoInsertGroupRequest) TargetDaoInsertGroupsResponse insertGroups(TargetDaoInsertGroupsRequest) TargetDaoInsertMembershipResponse insertMembership(TargetDaoInsertMembershipRequest) TargetDaoInsertMembershipsResponse insertMemberships(TargetDaoInsertMembershipsRequest) TargetDaoRetrieveAllDataResponse retrieveAllData(TargetDaoRetrieveAllDataRequest) TargetDaoRetrieveAllEntitiesResponse retrieveAllEntities(TargetDaoRetrieveAllEntitiesRequest) TargetDaoRetrieveAllGroupsResponse retrieveAllGroups(TargetDaoRetrieveAllGroupsRequest) |
All methods and options that the DAO supports must be identified in the DAO capabilities
e.g. an example of a provisioner that provisions memberships as group attributes
@Override public void registerGrouperProvisionerDaoCapabilities(GrouperProvisionerDaoCapabilities grouperProvisionerDaoCapabilities) { grouperProvisionerDaoCapabilities.setCanDeleteGroup(true); grouperProvisionerDaoCapabilities.setCanInsertGroup(true); grouperProvisionerDaoCapabilities.setCanRetrieveAllEntities(true); grouperProvisionerDaoCapabilities.setCanRetrieveAllGroups(true); grouperProvisionerDaoCapabilities.setCanRetrieveEntities(true); grouperProvisionerDaoCapabilities.setCanRetrieveGroups(true); grouperProvisionerDaoCapabilities.setCanRetrieveGroupWithOrWithoutMembershipAttribute(true); grouperProvisionerDaoCapabilities.setCanUpdateGroup(true); grouperProvisionerDaoCapabilities.setCanUpdateGroupMembershipAttribute(true); } |
After you insert/update/delete, you need to mark each object as provisioned or throw an exception
e.g.
targetGroup.setProvisioned(true); |
In a batched method, set each item to provisioned or not if some succeed or some fail.
If there is an exception, it should be set in the object. If you just throw the exception, then the caller (framework) will set exceptions into the objects and set provisioned false. Assigning exceptions is more important for batched methods
targetGroup.setProvisioned(false); targetGroup.setException(e); |
Note: you can easily store a string expression of an object in the exception (or other info)
GrouperUtil.injectInException(e, targetGroup.toString()); |
long startNanos = System.nanoTime(); try { ..target code } finally { this.addTargetDaoTimingInfo(new TargetDaoTimingInfo(<method name>, startNanos)); } } |
e.g.
int numberOfBatches = GrouperUtil.batchNumberOfBatches(grouperTargetGroups.size(), 900); for (int i = 0; i < numberOfBatches; i++) { long startNanos = System.nanoTime(); try { List<ProvisioningGroup> currentBatchGrouperTargetGroups = GrouperUtil.batchList(grouperTargetGroups, 900, i); StringBuilder sql = new StringBuilder(sqlInitial); sql.append(" where g.").append(groupTableIdColumn).append(" in ("); GcDbAccess gcDbAccess = new GcDbAccess().connectionName(dbExternalSystemConfigId); for (int j=0; j<currentBatchGrouperTargetGroups.size();j++) { ProvisioningGroup grouperTargetGroup = currentBatchGrouperTargetGroups.get(j); gcDbAccess.addBindVar(grouperTargetGroup.getId()); if (j>0) { sql.append(","); } sql.append("?"); } sql.append(" ) "); groupsAndAttributeValues = gcDbAccess.sql(sql.toString()).selectList(Object[].class); retrieveGroupsByAttributesAddRecord(result, groupTableIdColumn, groupAttributeTableAttributeNameColumn, groupAttributeTableAttributeValueColumn, commaSeparatedGroupColumnNames, groupColumnNamesArray, groupAttributeColumnNamesArray, groupsAndAttributeValues); } finally { this.addTargetDaoTimingInfo(new TargetDaoTimingInfo("retrieveGroups", startNanos)); } } |