grouper-dev - hooks update
Subject: Grouper Developers Forum
List archive
- From: Chris Hyzer <>
- To: "" <>
- Subject: hooks update
- Date: Fri, 11 Jul 2008 02:12:08 -0400
- Accept-language: en-US
- Acceptlanguage: en-US
Hey, - I mentioned earlier about java Transaction Synchronization
to do postCommit hooks. So I added 29 more hooks (90 total, all tested
with 69 unit tests) -
post commit hooks will make grouper hooks more like signet hooks -
they also allow for economical notifications (especially if there is a full
daily sync, and missing a few here and there doesn’t cause problems) - I made the asynchronous hooks and postCommit hooks (which
could be asynchronous) pass the business objects as clones. I was nervous
that the data might have changed in the meantime. This also will make
grouper more like signet - We discussed on the call changed to GSH, WS and UI for
hooks. I forgot about graceful veto handling, this could be some decent
work depending on if there is an opportunity to add one central veto handling
call. I believe this is the case in WS at least. - I think we should keep example hooks in the API for people
to look at (I have 3 there now, will add more as use cases pop up) - TomZ gave me a use case for hooks (no new or changed
emailAddress attribute of a group can conflict with existing email address of
group or subject), and I made an example (untested). [code below] It does give an example of some complex parts of the API: -
hook based on insert and update at same time -
hook based on if an attribute changes (uses dbVersionDifferentFields() ) -
inverse of control on GrouperSession (which I think will be common in hook
implementations to execute as GrouperSystem) -
getting around security on business methods (group.getAttributesDb()). Note,
could also do that with GrouperSystem GrouperSession All this is documented on wiki https://wiki.internet2.edu/confluence/display/GrouperWG/Hooks To do’s: - finalize how context data works - set this data from UI / WS / GSH / API / etc - gracefully handle vetos from UI / WS / GSH Kind regards, Chris Ps. Hooks list: Lifecycle.grouperStartup() Lifecycle.hookInit() Lifecycle.hibernateInit() Group.preInsert() Group.postInsert() Group.postCommitInsert() Group.preDelete() Group.postDelete() Group.postCommitDelete() Group.preUpdate() Group.postUpdate() Group.postCommitUpdate() Membership.preAddMember() Membership.postAddMember() Membership.postCommitAddMember() Membership.preRemoveMember() Membership.postRemoveMember() Membership.postCommitRemoveMember() Membership.preInsert() Membership.postInsert() Membership.postCommitInsert() Membership.preDelete() Membership.postDelete() Membership.postCommitDelete() Membership.preUpdate() Membership.postUpdate() Membership.postCommitUpdate() Member.preInsert() Member.postInsert() Member.postCommitInsert() Member.preDelete() Member.postDelete() Member.postCommitDelete() Member.preUpdate() Member.postUpdate() Member.postCommitUpdate() Stem.preInsert() Stem.postInsert() Stem.postCommitInsert() Stem.preDelete() Stem.postDelete() Stem.postCommitDelete() Stem.preUpdate() Stem.postUpdate() Stem.postCommitUpdate() GrouperSession.preInsert() GrouperSession.postInsert() GrouperSession.postCommitInsert() GrouperSession.preDelete() GrouperSession.postDelete() GrouperSession.postCommitDelete() GrouperSession.preUpdate() GrouperSession.postUpdate() GrouperSession.postCommitUpdate() GroupType.preInsert() GroupType.postInsert() GroupType.postCommitInsert() GroupType.preDelete() GroupType.postDelete() GroupType.postCommitDelete() GroupType.preUpdate() GroupType.postUpdate() GroupType.postCommitUpdate() Field.preInsert() Field.postInsert() Field.postCommitInsert() Field.preDelete() Field.postDelete() Field.postCommitDelete() Field.preUpdate() Field.postUpdate() Field.postCommitUpdate() GroupTypeTuple.preInsert() GroupTypeTuple.postInsert() GroupTypeTuple.postCommitInsert() GroupTypeTuple.preDelete() GroupTypeTuple.postDelete() GroupTypeTuple.postCommitDelete() GroupTypeTuple.preUpdate() GroupTypeTuple.postUpdate() GroupTypeTuple.postCommitUpdate() Composite.preInsert() Composite.postInsert() Composite.postCommitInsert() Composite.preDelete() Composite.postDelete() Composite.postCommitDelete() Composite.preUpdate() Composite.postUpdate() Composite.postCommitUpdate() Pps. Example code for TomZ use case: http://viewvc.internet2.edu/viewvc.py/grouper/src/grouper/edu/internet2/middleware/grouper/hooks/examples/GroupHooksImplExampleEmail.java?root=I2MI&view=markup /* * @author mchyzer * $Id:
GroupHooksImplExampleEmail.java,v 1.2 2008/07/11 05:47:11 mchyzer Exp $ */ package
edu.internet2.middleware.grouper.hooks.examples; import java.util.Set; import
org.apache.commons.lang.StringUtils; import
edu.internet2.middleware.grouper.Group; import
edu.internet2.middleware.grouper.GroupFinder; import edu.internet2.middleware.grouper.GrouperSession; import
edu.internet2.middleware.grouper.GrouperSessionException; import
edu.internet2.middleware.grouper.GrouperSessionHandler; import
edu.internet2.middleware.grouper.SubjectFinder; import
edu.internet2.middleware.grouper.hooks.GroupHooks; import
edu.internet2.middleware.grouper.hooks.beans.HooksContext; import
edu.internet2.middleware.grouper.hooks.beans.HooksGroupBean; import
edu.internet2.middleware.grouper.hooks.logic.HookVeto; import
edu.internet2.middleware.grouper.util.GrouperUtil; import
edu.internet2.middleware.subject.Subject; import
edu.internet2.middleware.subject.SubjectNotFoundException; import
edu.internet2.middleware.subject.SubjectNotUniqueException; /** * test implementation of group hooks for test. checks to make sure group attribute * is not in use by another group, subject, or subject id (for email prefix) */ public class
GroupHooksImplExampleEmail extends GroupHooks { /** * if there is a changed emailAddress, make sure it doesnt already existin another group or subject * @see edu.internet2.middleware.grouper.hooks.GroupHooks#groupPreUpdate(edu.internet2.middleware.grouper.hooks.beans.HooksContext, edu.internet2.middleware.grouper.hooks.beans.HooksGroupBean) */ @Override public void
groupPreUpdate(HooksContext hooksContext, HooksGroupBean preUpdateBean) { //if its an
update, see if the emailAddress changed Group group =
preUpdateBean.getGroup(); if
(group.dbVersionDifferentFields().contains(Group.ATTRIBUTE_PREFIX+"emailAddress")) { String
emailAddress = group.getAttributesDb().get("emailAddress"); if (!StringUtils.isBlank(emailAddress))
{
checkEmailAddress(emailAddress); } } } /** * <pre> * check a new or changed email address * attribute that there is not an existing email address in a subject attribute, or group attribute * * note: this is example code and is not tested * </pre> * @param emailAddress is the new email address (changed if update), should not be blank */ static void
checkEmailAddress(final String emailAddress) { try { //start
session, dont clobber existing session
GrouperSession grouperSession = GrouperSession.start(SubjectFinder.findRootSubject(),
false);
GrouperSession.callbackGrouperSession(grouperSession, new
GrouperSessionHandler() {
public Object
callback(GrouperSession grouperSession)
throws
GrouperSessionException {
//first
see if there is a group with that attribute
Set<Group> groups = GroupFinder.findAllByAttribute(grouperSession,
"emailAddress", emailAddress);
if (GrouperUtil.length(groups)
> 0) {
//note,
dont show the group who is using it if that is a security problem
throw new HookVeto("memphis.group.email.attribute.usedByGroup", "The
email address: " + emailAddress
+ "
is already being used by another group. Please pick another email
address.");
}
//next
see if a subject has that attribute value. note, this will only work if
the subject adapter is
//conducive
to it
Set<Subject> subjects = SubjectFinder.findAll(emailAddress);
if (GrouperUtil.length(subjects)
> 0) {
//note,
dont show the user who is using it if that is a security problem
throw new HookVeto("memphis.group.email.attribute.usedBySubjectEmail", "The
email address: " + emailAddress
+ "
is already being used by another entity. Please pick another email
address.");
}
//next
see if a subject has an identifier with the beginning of the email
address. could also filter by subject type
String emailPrefix = GrouperUtil.prefixOrSuffix(emailAddress, "@", true);
boolean foundSubject = false;
try {
SubjectFinder.findByIdentifier(emailPrefix);
foundSubject = true;
} catch
(SubjectNotFoundException snfe) {
} catch
(SubjectNotUniqueException snue) {
//data
problem, but also others using the email address
foundSubject = true;
}
if (foundSubject)
{
//note,
dont show the user who is using it if that is a security problem
throw new HookVeto("memphis.group.email.attribute.usedBySubjectEmailPrefix", "The
email prefix: " + emailPrefix
+ "
is already being used by another entity. Please pick another email
address.");
}
return null;
}
});
GrouperSession.stopQuietly(grouperSession); } catch (Exception e) { throw new RuntimeException("Problem
checking email address: '" + emailAddress + "'", e); } } /** * * @see edu.internet2.middleware.grouper.hooks.GroupHooks#groupPreInsert(edu.internet2.middleware.grouper.hooks.beans.HooksContext, edu.internet2.middleware.grouper.hooks.beans.HooksGroupBean) */ @Override public void
groupPreInsert(HooksContext hooksContext, HooksGroupBean preInsertBean) { //if its an
insert, always check the attribute if it is there Group group =
preInsertBean.getGroup(); //getAttributesDb
goes around permissions, just get the data String emailAddress =
group.getAttributesDb().get("emailAddress"); if (!StringUtils.isBlank(emailAddress))
{ checkEmailAddress(emailAddress); } } } |
- hooks update, Chris Hyzer, 07/11/2008
Archive powered by MHonArc 2.6.16.