Grouper rules


TODO: merge this one with Add disabled date on invalid membership


If a student is no longer a member of the course X group, then change the membership in the course wiki group to have an end date in one week.  The optional (e.g. nightly) daemon will look for members of the wiki who aren't in the course group and set their end date.

Java example

    AttributeAssign attributeAssign = ruleGroup
      .getAttributeDelegate().addAttribute(RuleUtils.ruleAttributeDefName()).getAttributeAssign();

    AttributeValueDelegate attributeValueDelegate = attributeAssign.getAttributeValueDelegate();

    attributeValueDelegate.assignValue(
        RuleUtils.ruleActAsSubjectSourceIdName(), actAs.getSourceId());
    attributeValueDelegate.assignValue(
        RuleUtils.ruleActAsSubjectIdName(), actAs.getId());

    //if the user falls out of mustBeInGroup, then set a disabled date in this group
    attributeValueDelegate.assignValue(
        RuleUtils.ruleCheckOwnerIdName(), mustBeInGroup.getId());
    attributeValueDelegate.assignValue(
        RuleUtils.ruleCheckTypeName(),
        RuleCheckType.membershipRemove.name());
    attributeValueDelegate.assignValue(
        RuleUtils.ruleIfConditionEnumName(),
        RuleIfConditionEnum.thisGroupHasImmediateEnabledNoEndDateMembership.name());
    attributeValueDelegate.assignValue(
        RuleUtils.ruleThenEnumName(), RuleThenEnum.assignMembershipDisabledDaysForOwnerGroupId.name());

    //number of days in future that disabled date should be set
    attributeValueDelegate.assignValue(
        RuleUtils.ruleThenEnumArg0Name(), "7");

    //if the membership in owner group doesnt exist, should it be added?  T|F
    attributeValueDelegate.assignValue(
        RuleUtils.ruleThenEnumArg1Name(), "F");

    //should be valid
    String isValidString = attributeValueDelegate.retrieveValueString(
        RuleUtils.ruleValidName());

    if (!StringUtils.equals("T", isValidString)) {
      throw new RuntimeException(isValidString);
    }

GSH shorthand method

RuleApi.groupIntersection(subjectActAs, groupA, groupB, 7);

GSH test case

gsh 0% grouperSession = GrouperSession.startRootSession();
edu.internet2.middleware.grouper.GrouperSession: f234aa6876784ea0990ae1aba754d5a7,'GrouperSystem','application'
gsh 1% groupA = new GroupSave(grouperSession).assignName("stem:a").assignCreateParentStemsIfNotExist(true).save();
group: name='stem:a' displayName='stem:a' uuid='4354a7db631e42bf93ac08eb5288b2c9'
gsh 2%  groupB = new GroupSave(grouperSession).assignName("stem:b").assignCreateParentStemsIfNotExist(true).save();
group: name='stem:b' displayName='stem:b' uuid='fa2fe9a442a44169875e82954386a332'
gsh 3% subjectActAs = SubjectFinder.findByIdAndSource("GrouperSystem", "g:isa", true);
subject: id='GrouperSystem' type='application' source='g:isa' name='GrouperSysAdmin'
gsh 4% RuleApi.groupIntersection(subjectActAs, groupA, groupB, 7);
gsh 5% addMember("stem:a", "test.subject.0");
true
gsh 6% addMember("stem:b", "test.subject.0");
true
gsh 7% delMember("stem:b", "test.subject.0");
true
gsh 8% hasMember("stem:a", "test.subject.0");
true
gsh 10% subject0 = SubjectFinder.findById("test.subject.0", true);
subject: id='test.subject.0' type='person' source='jdbc' name='my name is test.subject.0'
gsh 11% member0 = MemberFinder.findBySubject(grouperSession, subject0, false);
member: id='test.subject.0' type='person' source='jdbc' uuid='d20d4de2c7074da0a6a286f2b249d5ec'
gsh 12% membership = groupA.getImmediateMembership(Group.getDefaultList(), member0, true, true);
edu.internet2.middleware.grouper.Membership: Membership[createTime=1283754246504,creatorUuid=b0ad34466f1f401ba33c49cba4197cdb,depth=0,listName=members,listType=list,memberUuid=d20d4de2c7074da0a6a286f2b249d5ec,groupId=4354a7db631e42bf93ac08eb5288b2c9,type=immediate,uuid=4e107bdd371f49428ac65615fe43eab6:95f8d90414704e27bd558d41b03f9ba0]
gsh 13% membership.getDisabledTime()
java.sql.Timestamp: 2010-09-13 02:24:20.167
gsh 14%

GSH daemon test case

Run the above commands, and continue below

//get back to normal data
gsh 13% delMember("stem:a", "test.subject.0");
true

//subject0 should not be there
gsh 15% addMember("stem:a", "test.subject.0");
true

//subject1 is ok
gsh 16% addMember("stem:a", "test.subject.1");
true

//subject2 has a disabled date already, and shouldnt be touched
gsh 17% addMember("stem:a", "test.subject.2");
true

gsh 18% addMember("stem:b", "test.subject.1");
true
gsh 20% subject1 = SubjectFinder.findById("test.subject.1", true);
subject: id='test.subject.1' type='person' source='jdbc' name='my name is test.subject.1'
gsh 21% subject2 = SubjectFinder.findById("test.subject.2", true);
subject: id='test.subject.2' type='person' source='jdbc' name='my name is test.subject.2'
gsh 22% member1 = MemberFinder.findBySubject(grouperSession, subject1, false);
member: id='test.subject.1' type='person' source='jdbc' uuid='328d340a9d6d4774af8d12c1a6753d8e'
gsh 23% member2 = MemberFinder.findBySubject(grouperSession, subject2, false);
member: id='test.subject.2' type='person' source='jdbc' uuid='8f039afe4adf4770ad5ade263031f558'

//set disabled date for subject2
gsh 24% membership = groupA.getImmediateMembership(Group.getDefaultList(), member2, true, true);
edu.internet2.middleware.grouper.Membership: Membership[createTime=1285559733570,creatorUuid=7a06fd612353403dafe003630a5205a7,depth=0,listName=members,listType=list,memberUuid=8f039afe4adf4770ad5ade263031f558,groupId=9c1f128179d444c6970499e1a274dfa4,type=immediate,uuid=d3508dd616954915be37a6bbb2cdbce9:65d65d4d43d049358ca5348e81a6a1a3]
gsh 26% membership.setDisabledTime(new java.sql.Timestamp(System.currentTimeMillis() + (3 * 24 * 60 * 60 * 1000)));
gsh 27% GrouperDAOFactory.getFactory().getMembership().update(membership);

//run the daemon
gsh 28% status = GrouperLoader.runOnceByJobName(grouperSession, GrouperLoaderType.GROUPER_RULES);
loader ran successfully: Ran rules daemon, changed 0 records

//all groups should still have the members
gsh 29% hasMember("stem:a", "test.subject.0");
true
gsh 30% hasMember("stem:a", "test.subject.1");
true
gsh 31% hasMember("stem:a", "test.subject.2");
true

//the first one has 7 day forward disabled date
gsh 32% membership = groupA.getImmediateMembership(Group.getDefaultList(), member0, true, true);
edu.internet2.middleware.grouper.Membership: Membership[createTime=1285559719988,creatorUuid=7a06fd612353403dafe003630a5205a7,depth=0,listName=members,listType=list,memberUuid=090557f1838d40c4b594234632d82dae,groupId=9c1f128179d444c6970499e1a274dfa4,type=immediate,uuid=6d4e0e55ad7d496785a5d4df522fbbab:65d65d4d43d049358ca5348e81a6a1a3]
gsh 33% membership.getDisabledTime()
java.sql.Timestamp: 2010-10-03 23:58:37.904

//second one is ok, has no disabled date
gsh 34% membership = groupA.getImmediateMembership(Group.getDefaultList(), member1, true, true);
edu.internet2.middleware.grouper.Membership: Membership[createTime=1285559728869,creatorUuid=7a06fd612353403dafe003630a5205a7,depth=0,listName=members,listType=list,memberUuid=328d340a9d6d4774af8d12c1a6753d8e,groupId=9c1f128179d444c6970499e1a274dfa4,type=immediate,uuid=64ed8f25035d475490f774bd798910a0:65d65d4d43d049358ca5348e81a6a1a3]
gsh 35% membership.getDisabledTime()

//subject2 should keep the old disabled date, 3 days in future
gsh 36% membership = groupA.getImmediateMembership(Group.getDefaultList(), member2, true, true);
edu.internet2.middleware.grouper.Membership: Membership[createTime=1285559733570,creatorUuid=7a06fd612353403dafe003630a5205a7,depth=0,listName=members,listType=list,memberUuid=8f039afe4adf4770ad5ade263031f558,groupId=9c1f128179d444c6970499e1a274dfa4,type=immediate,uuid=d3508dd616954915be37a6bbb2cdbce9:65d65d4d43d049358ca5348e81a6a1a3]
gsh 37% membership.getDisabledTime()
java.sql.Timestamp: 2010-09-29 23:58:07.517
gsh 38%

Steps to add the rule via the UI ( Likely requires Wheel level access )

Assume there is a "source group" and a "target group". (The groups can be anywhere in Grouper.)

When a Membership is removed from "source group" the rule should add a membership to "target group" and set the new Membership to expire in 7 days. (Note: This date will be reset every time the user is removed from the "source group". )

If you did everything properly the system will add an additional metatdata assignment of etc:attribute:rules:ruleValid with a value of "T". ( Or it will be set to an error message to help you figure out where the problem is. (smile) ) Until the value is "T" the rule will not be effective.

a