This topic is discussed in the "Grouper API - Part 2" training video. |
gsh is a command line shell for administering and interacting with the Grouper API. See architectural diagram. It can be used in both a batch and interactive manner. For Grouper 2.3.0 patch 72+, it is built on GroovyShell. For older versions of Grouper, it is built on Java BeanShell. The legacy BeanShell version is now deprecated, but you can switch back to it by setting gsh.useLegacy = true in grouper.properties.
gsh is now a core part of the Grouper API and so is always compatible with the current release.
When using the Grouper API source distribution, grouper.jar needs to be built before using gsh.sh for the first time:
cd $GROUPER_HOME ant dist |
For Windows use $GROUPER_HOME\bin\gsh.bat
Run gsh as an interactive shell:
$GROUPER_HOME/bin/gsh.sh |
Read gsh commands from a script file:
$GROUPER_HOME/bin/gsh.sh /path/to/your/script.gsh |
Run Grouper utilities:
$GROUPER_HOME/bin/gsh.sh <option> args: -h, Prints this message args: -check, Performs startup check and enters an interactive shell args: -runarg <command> Run command (use \\n to separate commands) args: -main <class> [args...] class, Full class name (must have main method) args, args as required by main method of class args: -initEnv [<configDir>] On Windows sets GROUPER_HOME and adds GROUPER_HOME/bin to path For *nix 'source gsh.sh' for the same result configDir optionally adds an alternative conf directory than GROUPER_HOME/conf to the classpath args: (-xmlimport | -xmlexport | -loader | -test | -registry | -usdu | findbadmemberships) Enter option to get additional usage for that option -xmlexport, Invokes XmlExporter -xmlimport, Invokes XmlImporter -loader, Invokes GrouperLoader -registry, Manipulate the Grouper schema and install bootstrap data -test, Run JUnit tests -usdu, Invoke USDU - Unresolvable Subject Deletion Utility -findbadmemberships, Check for membership data inconsistencies |
Note: you can log sql statements run from gsh by setting this in log4j.properties
log4j.logger.org.apache.tools.ant = WARN |
Run SQL file
./gsh.sh -registry -runsqlfile subjects.sql |
In the new GSH, to not print the value of every line, use this:
:set verbosity QUIET |
Any Grouper API method can be directly invoked just by referencing it, inclusive of the class in which it is defined. Methods return a java object which can be stored in a variable. For example, the following gsh session determines all of the groups to which a given subject belongs:
gsh 0% GrouperSession.startRootSession(); gsh 0% subj = findSubject("SD00125") subject: id='SD00125' type='person' source='kitn-person' name='Barton, Tom' gsh 1% sess = GrouperSession.start(subj) edu.internet2.middleware.grouper.GrouperSession: 29c40f97-9fb0-4e45-88bc-a14877a6c9b5,'SD00125','person' gsh 2% member = MemberFinder.findBySubject(sess, subj) member: id='SD00125' type='person' source='kitn-person' uuid='d0fa765e-1439-4701-89b1-9b08b4ce9daa' gsh 3% member.getGroups() group: name='etc:sysadmingroup' displayName='Grouper Administration:SysAdmin Group' uuid='6f77fb36-b466-481a-84a7-7af609f1ad09' |
Command | Description |
---|---|
addGroup(parent stem name, extension, displayExtension) | Add group to registry |
delGroup(name) | Delete group from registry |
getGroupAttr(group name, attr) | Get value of group attribute |
getGroups(name) | Find all groups with a matching naming attribute value, returns a Set of groups |
setGroupAttr(group name, attr, value) | Set value of group attribute |
GroupFinder.findByName(grouperSession, name) | Find one group by name |
GroupFinder.findByUuid(grouperSession, name) | Find one group by uuid |
You can set the description on a group by:
rsess = GrouperSession.startRootSession(); addGroup("stem1", "path_ID", "groupName"); group = GroupFinder.findByName(rsess, "stem1:path_ID"); group.setDescription("this is the description for groupName"); group.store(); |
You can use GroupSave as an alternate way:
new GroupSave(grouperSession).assignName("stem1:a").assignCreateParentStemsIfNotExist(true).save(); |
Command | Description |
---|---|
groupAddType(group name, type name) | Add type to group |
groupDelType(group name, type name) | Delete type from group |
groupGetTypes(group name) | Get group's types |
groupHasType(group name, type name) | Check whether group had type |
typeAdd(type name) | Create custom group type |
typeAddAttr(type name, attr name, read, write, required) | Create custom group attribute. read and write must be an |
typeAddList(type name, attr name, read, write) | Create a custom list. read and write must be an |
typeDel(type name) | Delete group type |
typeDelField(type name, field name) | Delete custom field from group type |
typeFind(type name) | Find the group |
typeGetFields(type name) | Get fields associated with the group type |
Change subject of a Member object, e.g.:
grouperSession = GrouperSession.startRootSession();
oldSubject = findSubject("10021368");
member = MemberFinder.findBySubject(grouperSession, oldSubject);
newSubject = findSubject("10021366");
member.changeSubject(newSubject);
Command | Description |
---|---|
member.changeSubject(newSubject); | Change the subject of the member object. If the subject is the same, its a no-op. If the new subject does not have a Member object, then the existing member object simply gets new subject information. If the new subject does have a member object, then all objects in the grouper registry which uses the old member, will be updated to the new member. Then the old member object is deleted from the registry |
member.changeSubject(newSubject,!Member.DELETE_OLD_MEMBER); | Change the subject, but dont delete the old member. Do this if the way which deletes the old member doesnt work due to foreign keys. This will do all the work it can, and the rest can be manual |
member.changeSubjectReport(newSubject,Member.DELETE_OLD_MEMBER); | Dont do any of the work, just print a report to the screen of what will be done. Dry-run. |
Command | Description |
---|---|
addComposite(group name, composite type, left group name, right group name) | Add composite membership. e.g. CompositeType.UNION |
addMember(group name, subject id) | Add member to the members list for the group. |
addMember(group name, subject id, field) | Add member to the specified list for the group. |
delComposite(group name) | Delete composite membership from group |
delMember(group name, subject id) | Delete member from the members list for the group |
delMember(group name, subject id, field) | Delete member from the specified list for the group |
getMembers(group name) | Get members of group |
hasMember(group name, subject id) | Check whether subject is member of the members list |
hasMember(group name, subject id, field) | Check whether subject is member of the specified list |
Command | Description |
---|---|
grantPriv(group name, subject id, privilege) | Grant privilege on group. privilege must be an AccessPrivilege (e.g. |
grantPriv(stem name, subject id, privilege) | Grant privilege on stem. privilege must be a NamingPrivilege (e.g. |
hasPriv(group name, subject id, privilege) | Check whether subject has privilege on group. privilege must be an AccessPrivilege (e.g. |
hasPriv(stem name, subject id, privilege) | Check whether subject has privilege on strem. privilege must be a NamingPrivilege (e.g. |
revokePriv(group name, subject id, privilege) | Revoke privilege on group. privilege must be an AccessPrivilege (e.g. |
revokePriv(stem name, subject id, privilege) | Revoke privilege on stem. privilege must be a NamingPrivilege (e.g. |
Command | Description |
---|---|
registryInitializeSchema() | Will generate schema DDL for the DB, and wont drop before creating, will not run script |
registryInitializeSchema(registryInitializeSchema.DROP_THEN_CREATE) | generate DDL for the DB, dropping existing tables, will not run script |
registryInitializeSchema.WRITE_AND_RUN_SCRIPT) | generate DDL for the DB, not dropping, but will run the script after writing it to file |
registryInitializeSchema(registryInitializeSchema.DROP_THEN_CREATE | registryInitializeSchema.WRITE_AND_RUN_SCRIPT) | generate DDL for the DB, drop existing grouper tables, and run the script after writing it to file |
resetRegistry() | Restore registry to default state(delete data from all tables, install defaults) |
registryInstall() | If the default Grouper data is not there, it will be added (e.g. root stem, default fields, etc) |
Command | Description |
---|---|
addRootStem(extension, displayExtension) | Add top-level stem to the registry |
addStem(parent stem name, extension, displayExtension) | Add stem to registry |
delStem(stem name) | Delete stem from registry |
obliterateStem(stem name, testOnlyBoolean, deleteFromPointInTimeBoolean) (Grouper v2.0.2+) | Delete stem, and subobjects. |
getStemAttr(stem name, attr) | Get value of stem attribute |
getStems(name) | Find all stems with a matching naming attribute value, returns a Set of stems |
setStemAttr(stem name, attr, value) | Set value of stem attribute |
StemFinder.findByName(grouperSession, name) | Find one stem by name |
StemFinder.findByUuid(grouperSession, uuid) | Find one stem by uuid |
| |
Delete stem and subcontents |
Command | Description | |
---|---|---|
addSubject(id, type, name) | Add local subject to registry | |
findSubject(id) | Find a subject | |
findSubject(id, type) | Find a subject | |
findSubject(id, type, source) | Find a subject | |
getSources() | Find all Subject sources | |
grouperSession = GrouperSession.startRootSession(); | Find all subjects in a source by search string | |
grouperSession = GrouperSession.startRootSession(); | Find a subject by id in a certain source | |
grouperSession = GrouperSession.startRootSession(); | Find a subject by identifier in a certain source | |
grouperSession = GrouperSession.startRootSession(); | Find a subject by id or identifier in a certain source | |
add test subjects to registry (e.g. test.subject.0 through 9) | grouperSession = GrouperSession.startRootSession(); | |
Edit subject (in this case name) | RegistrySubject registrySubject = GrouperDAOFactory.getFactory().getRegistrySubject().find("user1a", "person", true); | |
add a subject application principal with attributes (GSH) |
| |
remove a subject with attributes (GSH) |
|
Command | Description |
---|---|
sqlRun(file) | Execute each line of a sql file, just like ant would. This can run the files generated by registryInitializeSchema() |
sqlRun(string) | Executes a single sql statement |
:exit | Terminate shell |
help() | Display usage information |
p(command) | Pretty print results. |
:quit | Terminate shell |
version() | Return version information |
usdu finds which memberships are with subjects which cannot be found in a subject source, and prints them on the screen
- if the usdu.DELETE option is passed in, then the memberships will be deleted
- a grouper session must be open when this command is run.
For more information, see Unresolvable Subject Deletion Utility (USDU)
Command | Description |
---|---|
GrouperSession.startRootSession(); | Sample call to find all unresolvable subjects in the registry and print details to the screen |
usdu(usdu.DELETE) | Pass in that you want to delete memberships in the usdu call |
usduBySource("schoolperson") | Work only in a specific subject source, pass in the sourceId from sources.xml |
usduBySource("schoolperson", usdu.DELETE) | Work in a specific source and delete membeships |
subject=SubjectFinder.findById("GrouperSystem") | Work only with a specific member |
usduByMember(member, usdu.DELETE) | usdu by member, and delete memberships |
This command will find membership records in the database which are invalid, and prints them on the screen, along with a GSH script that will fix the memberships.
For more information, see Bad Membership Finder Utility
Command | Description |
---|---|
findBadMemberships() | complete findBadMemberships run |
Command | Description |
---|---|
xmlFromFile(filename) | Load registry from XML in file |
xmlFromString(xml) | Load registry from XML in string |
xmlFromURL(url) | Load registry from XML at URL |
xmlToFile(filename) | Exports registry to file |
xmlToString() | Exports registry to string. |
xmlUpdateFromFile(filename) | Update registry from XML in file |
xmlUpdateFromString(xml) | Update registry from XML in string |
xmlUpdateFromURL(url) | Update registry from XML at URL |
There is an object: XmlExport which has various chaining methods, which should be ended with an exportTo() method. You can export to file or string.
For more information, see Import-Export
Command | Description |
---|---|
XmlExport xmlExport.stem(stem) | The stem to export. Defaults to the ROOT stem. |
XmlExport xmlExport.group(group) | The group to export |
XmlExport xmlExport.relative(boolean) | If group or stem specified do not export parent Stems. |
XmlExport xmlExport.includeParent(boolean) | If group specified, export from the parent stem |
XmlExport xmlExport.childrenOnly(boolean) | If stem specified, export child stems and groups only - not the specified stem |
XmlExport xmlExport.userProperties(file) | Properties file for extra settings for import |
XmlExport xmlExport.grouperSession(grouperSession) | Operate within a certain grouper session (defaults to root session) |
void xmlExport.exportToFile(file) | Export to an XML file |
void xmlExport.exportToString(string) | Export to an XML string |
Examples:
gsh 1% new XmlExport().exportToFile(new File("c:/temp/export.xml")) |
gsh 1% grouperSession = GrouperSession.start(SubjectFinder.findById("mchyzer")); gsh 2% stem = StemFinder.findByName(grouperSession, "aStem"); gsh 3% new XmlExport().stem(stem).relative(true).userProperties(new File("C:/temp/some.props")).grouperSession(grouperSession).exportToFile(new File("c:/temp/export.xml")); |
-or- (without chaining)
gsh 3% xmlExport = new XmlExport(); gsh 4% xmlExport.stem(stem); gsh 5% xmlExport.grouperSession(grouperSession); gsh 6% xmlExport.exportToFile(new File("c:/temp/export.xml")) |
There is an object: XmlImport which has various chaining methods, which should be ended with an importFrom() method. You can import from file, string, or url.
For more information, see Import-Export
Command | Description |
---|---|
XmlImport xmlImport.stem(stem) | The Stem into which data will be imported. Defaults to the ROOT stem. |
XmlImport xmlImport.updateList(boolean) | XML contains a flat list of Stems or Groups which may be updated. |
XmlImport xmlImport.userProperties(file) | Properties file for extra settings for import |
XmlImport xmlImport.grouperSession(grouperSession) | Operate within a certain grouper session (defaults to root session) |
XmlImport xmlImport.ignoreInternal(boolean) | Ignore internal attributes, including group and stem uuids. |
void xmlImport.importFromFile(file) | Import from an XML file |
void xmlImport.importFromString(string) | Import from an XML string |
void xmlImport.importFromUrl(url) | Import XML from a URL |
Examples:
gsh 1% new XmlImport().importFromFile(new File("c:/temp/export.xml")) |
gsh 1% grouperSession = GrouperSession.start(SubjectFinder.findById("mchyzer")); gsh 2% stem = StemFinder.findByName(grouperSession, "aStem"); gsh 3% new XmlImport().stem(stem).updateList(true).userProperties(new File("C:/temp/some.props")).grouperSession(grouperSession).importFromUrl(new URL("http://whatever.xml")); |
-or- (without chaining)
gsh 3% xmlImport = new XmlImport(); gsh 4% xmlImport.stem(stem); gsh 5% xmlImport.grouperSession(grouperSession); gsh 6% xmlImport.importFromFile(new File("c:/temp/export.xml")) |
Transactions facilitate all commands succeeding or failing together, and perhaps some level of repeatable reads of the DB (depending on the DB). If there is an open transaction and an exception is thrown in a command, GSH will shut down so that subsequent commands will not execute outside of a transaction.
Command | Description |
---|---|
help("transaction") | print help information |
transactionStatus() | print the list of nested transactions |
transactionStart("<GrouperTransactionType>") | start a transaction, or make sure one is already started |
transactionCommit("<GrouperCommitType>") | commit a transaction |
transactionRollback("<GrouperRollbackType>") | rollback a transaction |
transactionEnd() | end a transaction |
Above, it describes how you can kick off the loader in daemon mode. You can also execute one job with:
Command | Description |
---|---|
grouperSession = GrouperSession.startRootSession(); | Kick off the loader for one group (configured by group attributes) |
loaderRunOneJob("MAINTENANCE_cleanLogs"); | Kick off the loader by job name |
loaderRunOneJob("CHANGE_LOG_changeLogTempToChangeLog"); | Move change log entries from the temp table to the real table |
loaderRunOneJob("CHANGE_LOG_consumer_grouperRules"); | Run the Grouper Rules daemon (the changelog or full version) |
loaderRunOneJob("CHANGE_LOG_consumer_test"); | Run a change log consumer |
This query (in Oracle) will find jobs with no success in the last day and make a gsh script:
select distinct 'loaderRunOneJob("' || job_name || '");' as script from grouper_loader_log gll where started_time > sysdate-1 and status != 'SUCCESS' and gll.job_name not like 'subjobFor%' and not exists (select 1 from grouper_loader_log gll2 where gll2.started_time > sysdate-1 and gll2.status = 'SUCCESS' and gll2.job_name = gll.job_name) |
v1.6+ loader
Command | Description |
---|---|
loaderRunOneJobAttr(attirbuteDef) | Run an attribute definition loader job |
You can run the loader as a linux service
gsh has several variables that can be set to modify runtime behavior
Variable | Description |
---|---|
GSH_DEBUG | Stack traces will be printed upon failure if true |
GSH_DEVEL | Summaries of returned objects are not automatically printed if true |
GSH_TIMER | Prints time spent evaluating each command if true |
Example:
gsh 4% GSH_DEVEL = true gsh 5% subj = findSubject("SD00125") gsh 6% sess = GrouperSession.start(subj) gsh 7% member = MemberFinder.findBySubject(sess, subj) gsh 8% p(member.getGroups()) group: name='etc:sysadmingroup' displayName='Grouper Administration:SysAdmin Group' uuid='6f77fb36-b466-481a-84a7-7af609f1ad09' |
# (1) Print tab-separated summary of all group members, and flags for direct, indirect, or both # Depending on the results, you could use the data to create a scrutinized list of Ids to delete, then import it and delete in a loop me = SubjectFinder.findByIdentifierAndSource("my-username", "pid", true); session = GrouperSession.start(me); // OR: session = GrouperSession.startRootSession(True) group = GroupFinder.findByName(session, "tmp:my:group", true); effectiveMembers = group.getEffectiveMembers(); immediateMembers = group.getImmediateMembers(); System.out.println(String.join("\t", "id", "name", "Effective", "Immediate")); for (Member m: group.getMembers()) { System.out.print(m.getSubject().getId() + "\t" + m.getSubject().getName() + "\t"); System.out.print(effectiveMembers.contains(m).toString() + "\t"); System.out.println(immediateMembers.contains(m).toString() + "\t"); } # (2) Get the immediate and effective members for a specific source ("pid" in this example), intersect them to find the redundant ones # This has a dryRun flag, so you can test first sources = new HashSet<Source>() sources.add(SourceManager.getInstance().getSource("pid")) effectiveUsers = group.getEffectiveMembers(Group.getDefaultList(), sources, null) immediateUsers = group.getImmediateMembers(Group.getDefaultList(), sources, null) # use retainAll() to find the intersection; i.e., users both as effective and immediate member immediateUsers.retainAll(effectiveUsers) System.out.println("There are " + immediateUsers.size() + " users having both direct + indirect memberships"); dryRun = true for (Member m: immediateUsers) { if (dryRun) { System.out.println("Ok to delete " + m.getSubject().getId()); } else { System.out.println("Deleting " + m.getSubject().getId()); group.deleteMember(m, false); } } |
Note: you cannot encrypt passwords with GSH since the passwords end up in the GSH history. To encrypt passwords, issue the command:
C:\mchyzer\isc\dev\grouper-qs-1.2.0\grouper>java -jar lib\morphString.jar Enter the location of morphString.properties: conf/morphString.properties Type the string to encrypt (note: pasting might echo it back): The encrypted string is: ca8a15be4ad0fb45c6f1b3ca0cfd9c9e |
v2.0: to sync up the point in time tables with regular tables, run this:
new edu.internet2.middleware.grouper.misc.SyncPITTables().syncAllPITTables() |
To create missing group sets:
new edu.internet2.middleware.grouper.misc.AddMissingGroupSets().addAllMissingGroupSets(); |
Delete memberships not in transaction
grouperSession = GrouperSession.startRootSession(); group = GroupFinder.findByName(grouperSession, "test:testGroup3", true); for (membership : group.getImmediateMemberships()) {membership.delete();} group.delete(); |
See the WIKI for running the Grouper Report manually
Here is an example to remove access from someone... run a SQL to generate a GSH script, e.g. in oracle:
set linesize 1000; set pagesize 1000; select 'delMember("' || gmlv.GROUP_NAME || '", "' || gmlv.SUBJECT_ID || '");' as script from grouper_memberships_lw_v gmlv where subject_id = '12345678' and gmlv.LIST_NAME = 'members'; |
Put that script in a text editor and remove extra whitespace (probably optional), and add this to the beginning:
grouperSession = GrouperSession.startRootSession(); |
Look at it and remove lines that dont apply... then run in GSH
[appadmin@lorenzo bin]$ ./gsh.sh remove.script |
Here is a more complicated example. I want all groups in a certain folder which do not have an ADMIN privilege assigned to my application service principal, to assign that privilege. Here is the query for oracle:
select 'grantPriv("' || gg.name || '", "someid/server.school.edu", AccessPrivilege.ADMIN);' as script from grouper_groups gg where gg.name like 'school:apps:appName:spaces:%' and not exists (select (1) from grouper_memberships_lw_v gmlv where gg.name = gmlv.group_name and list_name = 'admins' and gmlv.subject_id = 'someid/server.school.edu'); |
Here is an example of deleting memberships for a user in oracle, dont forget at top of script to add grouperSession = GrouperSession.startRootSession():
set linesize 1000; set pagesize 1000; select 'delMember("' || gg.name || '", "' || gm.subject_id || '");' as script from grouper_memberships_all_v gmav, grouper_fields gf, grouper_groups gg, grouper_members gm where GMAV.FIELD_ID = GF.ID and gm.subject_id = '12345678' and GF.name = 'members' and GMAV.OWNER_GROUP_ID = gg.ID and GMAV.MEMBER_ID = GM.ID and GMAV.DEPTH = 0 |
Here is an example of removing privileges from a user on groups in oracle, dont forget at top of script to add grouperSession = GrouperSession.startRootSession():
set linesize 1000; set pagesize 1000; select 'revokePriv("' || gmlv.group_name || '", "' || gmlv.subject_id || '", AccessPrivilege.' || case when gmlv.LIST_NAME = 'admins' then 'ADMIN' when gmlv.LIST_NAME = 'readers' then 'READ' when gmlv.LIST_NAME = 'viewers' then 'VIEW' when gmlv.LIST_NAME = 'updaters' then 'UPDATE' when gmlv.LIST_NAME = 'optins' then 'OPTIN' when gmlv.LIST_NAME = 'optouts' then 'OPTOUT' else gmlv.LIST_NAME end || ');' as script from grouper_memberships_lw_v gmlv where subject_id = '12345678' and GMLV.LIST_TYPE = 'access' |
This oracle script will remove privileges on folders for a certain user, dont forget at top of script to add grouperSession = GrouperSession.startRootSession():
set linesize 1000; set pagesize 1000; select 'revokePriv("' || gs.name || '", "' || gm.subject_id || '", NamingPrivilege.' || case when gf.NAME = 'stemmers' then 'STEM' when gf.NAME = 'creators' then 'CREATE' else gf.NAME end || ');' as script from grouper_memberships_all_v gmav, grouper_fields gf, grouper_stems gs, grouper_members gm where GMAV.FIELD_ID = GF.ID and gm.subject_id = '12345678' and GF.type = 'naming' and GMAV.OWNER_STEM_ID = GS.ID and GMAV.MEMBER_ID = GM.ID |
Create a permission and configure action list:
grouperSession = GrouperSession.startRootSession(); attributeDef = new AttributeDefSave(grouperSession).assignName("stem2:sub:c").assignToEffMembership(true).assignToGroup(true).assignAttributeDefType(AttributeDefType.perm).assignCreateParentStemsIfNotExist(true).save(); attributeDef.getAttributeDefActionDelegate().configureActionList("read,write"); |
Retrieve assignments for the attribute "school:attr:students:artsAndSciences"
attributeDefName = AttributeDefNameFinder.findByName("school:attr:students:artsAndSciences", true); group.getAttributeDelegate().retrieveAssignments(attributeDefName); |
The following script will print to standard output (not saved as files) two scripts.
Note: The disableLoaders.gsh script does not change the state of the loader jobs. Rather it only prints (outputs) GSH scripts that you can later execute to do disable/enable for the jobs on the system at the time.
Note: After running either of the scripts that are output, you need to restart all grouper daemon instances to make the changes effective.( So you might choose to stop them before running the "DISABLE" or "RESTORE" script.That order is not strictly required.)
Note well: The method used to "disable" the jobs is to alter the quartz schedule for the job to be a fixed time in the distant future. ( specifically: "0 0 0 1 1 ? 3000" ) So the "RESTORE OLD SCHEDULES" script is the only record of what the orginal scheduled values were. Don't lose it.
Note this works in the new GSH. To use in legacy GSH, take the set verbosity away...
:set verbosity QUIET grouperSession = GrouperSession.startRootSession(); sqlLoaderDefName = AttributeDefNameFinder.findByName("etc:legacy:attribute:legacyGroupType_grouperLoader", true); sqlLoaderDefScheduleName = AttributeDefNameFinder.findByName("etc:legacy:attribute:legacyAttribute_grouperLoaderQuartzCron", true); ldapLoaderDefName = AttributeDefNameFinder.findByName("etc:attribute:loaderLdap:grouperLoaderLdap", true); ldapLoaderDefScheduleName = AttributeDefNameFinder.findByName("etc:attribute:loaderLdap:grouperLoaderLdapQuartzCron", true); result = new StringBuilder(); result.append("\n\n############ RESTORE OLD SCHEDULES, BOUNCE GROUPER DAEMONS AFTERWARDS #############\n\ngrouperSession = GrouperSession.startRootSession();\n"); result.append("sqlLoaderDefName = AttributeDefNameFinder.findByName(\"etc:legacy:attribute:legacyGroupType_grouperLoader\", true);\n"); result.append("sqlLoaderDefScheduleName = AttributeDefNameFinder.findByName(\"etc:legacy:attribute:legacyAttribute_grouperLoaderQuartzCron\", true);\n"); result.append("ldapLoaderDefName = AttributeDefNameFinder.findByName(\"etc:attribute:loaderLdap:grouperLoaderLdap\", true);\n"); result.append("ldapLoaderDefScheduleName = AttributeDefNameFinder.findByName(\"etc:attribute:loaderLdap:grouperLoaderLdapQuartzCron\", true);\n"); attributeAssigns = GrouperDAOFactory.getFactory().getAttributeAssign().findAttributeAssignments(AttributeAssignType.group, null, sqlLoaderDefName.getId(), null, null, null, null, null, true, false); for (AttributeAssign attributeAssign : attributeAssigns) {result.append("group = GroupFinder.findByName(grouperSession, \"" + attributeAssign.getOwnerGroup().getName() + "\");\nattributeAssignOnAssign = group.getAttributeDelegate().retrieveAssignment(null, sqlLoaderDefName, false, false);\nattributeAssignOnAssign.getAttributeValueDelegate().assignValueString(\"" + sqlLoaderDefScheduleName.getName() + "\", \"" + attributeAssign.getAttributeValueDelegate().retrieveValueString(sqlLoaderDefScheduleName.getName()) + "\");\n"); } attributeAssigns = GrouperDAOFactory.getFactory().getAttributeAssign().findAttributeAssignments(AttributeAssignType.group, null, ldapLoaderDefName.getId(), null, null, null, null, null, true, false); for (AttributeAssign attributeAssign : attributeAssigns) {result.append("group = GroupFinder.findByName(grouperSession, \"" + attributeAssign.getOwnerGroup().getName() + "\");\nattributeAssignOnAssign = group.getAttributeDelegate().retrieveAssignment(null, ldapLoaderDefName, false, false);\nattributeAssignOnAssign.getAttributeValueDelegate().assignValueString(\"" + ldapLoaderDefScheduleName.getName() + "\", \"" + attributeAssign.getAttributeValueDelegate().retrieveValueString(ldapLoaderDefScheduleName.getName()) + "\");\n"); } result.append("\n\n############ DISABLE ALL SCHEDULES, BOUNCE GROUPER DAEMONS AFTERWARDS #############\n\ngrouperSession = GrouperSession.startRootSession();\n"); result.append("sqlLoaderDefName = AttributeDefNameFinder.findByName(\"etc:legacy:attribute:legacyGroupType_grouperLoader\", true);\n"); result.append("sqlLoaderDefScheduleName = AttributeDefNameFinder.findByName(\"etc:legacy:attribute:legacyAttribute_grouperLoaderQuartzCron\", true);\n"); result.append("ldapLoaderDefName = AttributeDefNameFinder.findByName(\"etc:attribute:loaderLdap:grouperLoaderLdap\", true);\n"); result.append("ldapLoaderDefScheduleName = AttributeDefNameFinder.findByName(\"etc:attribute:loaderLdap:grouperLoaderLdapQuartzCron\", true);\n"); attributeAssigns = GrouperDAOFactory.getFactory().getAttributeAssign().findAttributeAssignments(AttributeAssignType.group, null, sqlLoaderDefName.getId(), null, null, null, null, null, true, false); for (AttributeAssign attributeAssign : attributeAssigns) {result.append("group = GroupFinder.findByName(grouperSession, \"" + attributeAssign.getOwnerGroup().getName() + "\");\nattributeAssignOnAssign = group.getAttributeDelegate().retrieveAssignment(null, sqlLoaderDefName, false, false);\nattributeAssignOnAssign.getAttributeValueDelegate().assignValueString(\"" + sqlLoaderDefScheduleName.getName() + "\", \"0 0 0 1 1 ? 3000\");\n"); } attributeAssigns = GrouperDAOFactory.getFactory().getAttributeAssign().findAttributeAssignments(AttributeAssignType.group, null, ldapLoaderDefName.getId(), null, null, null, null, null, true, false); for (AttributeAssign attributeAssign : attributeAssigns) {result.append("group = GroupFinder.findByName(grouperSession, \"" + attributeAssign.getOwnerGroup().getName() + "\");\nattributeAssignOnAssign = group.getAttributeDelegate().retrieveAssignment(null, ldapLoaderDefName, false, false);\nattributeAssignOnAssign.getAttributeValueDelegate().assignValueString(\"" + ldapLoaderDefScheduleName.getName() + "\", \"0 0 0 1 1 ? 3000\");\n"); } System.out.println(result); |
Example: was run against a server with two jobs that are both scheduled to run at "0 0 * * * ?" .
[appadmin@i2midev6 bin]$ ./gsh disableLoaders.gsh ############ RESTORE OLD SCHEDULES, BOUNCE GROUPER DAEMONS AFTERWARDS ############# grouperSession = GrouperSession.startRootSession(); sqlLoaderDefName = AttributeDefNameFinder.findByName("etc:legacy:attribute:legacyGroupType_grouperLoader", true); sqlLoaderDefScheduleName = AttributeDefNameFinder.findByName("etc:legacy:attribute:legacyAttribute_grouperLoaderQuartzCron", true); ldapLoaderDefName = AttributeDefNameFinder.findByName("etc:attribute:loaderLdap:grouperLoaderLdap", true); ldapLoaderDefScheduleName = AttributeDefNameFinder.findByName("etc:attribute:loaderLdap:grouperLoaderLdapQuartzCron", true); group = GroupFinder.findByName(grouperSession, "nyu_apereo:presenter:allStevens3"); attributeAssignOnAssign = group.getAttributeDelegate().retrieveAssignment(null, sqlLoaderDefName, false, false); attributeAssignOnAssign.getAttributeValueDelegate().assignValueString("etc:legacy:attribute:legacyAttribute_grouperLoaderQuartzCron", "0 0 * * * ?"); group = GroupFinder.findByName(grouperSession, "test:loader:testLdapGroupList"); attributeAssignOnAssign = group.getAttributeDelegate().retrieveAssignment(null, ldapLoaderDefName, false, false); attributeAssignOnAssign.getAttributeValueDelegate().assignValueString("etc:attribute:loaderLdap:grouperLoaderLdapQuartzCron", "0 0 * * * ?"); ############ DISABLE ALL SCHEDULES, BOUNCE GROUPER DAEMONS AFTERWARDS ############# grouperSession = GrouperSession.startRootSession(); sqlLoaderDefName = AttributeDefNameFinder.findByName("etc:legacy:attribute:legacyGroupType_grouperLoader", true); sqlLoaderDefScheduleName = AttributeDefNameFinder.findByName("etc:legacy:attribute:legacyAttribute_grouperLoaderQuartzCron", true); ldapLoaderDefName = AttributeDefNameFinder.findByName("etc:attribute:loaderLdap:grouperLoaderLdap", true); ldapLoaderDefScheduleName = AttributeDefNameFinder.findByName("etc:attribute:loaderLdap:grouperLoaderLdapQuartzCron", true); group = GroupFinder.findByName(grouperSession, "nyu_apereo:presenter:allStevens3"); attributeAssignOnAssign = group.getAttributeDelegate().retrieveAssignment(null, sqlLoaderDefName, false, false); attributeAssignOnAssign.getAttributeValueDelegate().assignValueString("etc:legacy:attribute:legacyAttribute_grouperLoaderQuartzCron", "0 0 0 1 1 ? 3000"); group = GroupFinder.findByName(grouperSession, "test:loader:testLdapGroupList"); attributeAssignOnAssign = group.getAttributeDelegate().retrieveAssignment(null, ldapLoaderDefName, false, false); attributeAssignOnAssign.getAttributeValueDelegate().assignValueString("etc:attribute:loaderLdap:grouperLoaderLdapQuartzCron", "0 0 0 1 1 ? 3000"); |
In Grouper 2.3 the UI can delete inherited privileges rules.
To delete a rule, find it in the database in grouper_rules_v. Get the attributeAssignId
GrouperSession grouperSession = GrouperSession.startRootSession(); AttributeAssign attributeAssign = AttributeAssignFinder.findById("b629bd8170964663be507968752f4f17", true); attributeAssign.delete(); |
Create queues / topics, assign privileges for Grouper builtin messaging (not activemq, rabbitmq, AWS, etc) (Grouper 2.3+)
grouperSession = GrouperSession.startRootSession(); // create objects GrouperBuiltinMessagingSystem.createQueue("abc"); GrouperBuiltinMessagingSystem.createTopic("def"); // delete objects GrouperBuiltinMessagingSystem.deleteQueue("abc"); GrouperBuiltinMessagingSystem.deleteTopic("def"); // permissions on objects GrouperBuiltinMessagingSystem.allowSendToQueue("abc", SubjectTestHelper.SUBJ0); GrouperBuiltinMessagingSystem.allowSendToTopic("abc", SubjectTestHelper.SUBJ0); GrouperBuiltinMessagingSystem.allowReceiveFromQueue("abc", SubjectTestHelper.SUBJ0); GrouperBuiltinMessagingSystem.disallowSendToQueue("abc", SubjectTestHelper.SUBJ0); GrouperBuiltinMessagingSystem.disallowSendToTopic("abc", SubjectTestHelper.SUBJ0); GrouperBuiltinMessagingSystem.disallowReceiveFromQueue("abc", SubjectTestHelper.SUBJ0); // topics send to queues GrouperBuiltinMessagingSystem.topicAddSendToQueue("def", "abc"); Collection<String> queues = GrouperBuiltinMessagingSystem.queuesTopicSendsTo("def"); GrouperBuiltinMessagingSystem.topicRemoveSendToQueue("def", "abc"); |
Send, receive, acknowledge messages in any message system (Grouper builtin, activeMQ, rabbitmq, AWS, etc) (Grouper 2.3+)
//note, or whatever user should be sending the messages grouperSession = GrouperSession.startRootSession(); //send message to queue GrouperMessagingEngine.send(new GrouperMessageSendParam().assignGrouperMessageSystemName(GrouperBuiltinMessagingSystem.BUILTIN_NAME).assignQueueType(GrouperMessageQueueType.queue).assignQueueOrTopicName("queueName").addMessageBody("Some message body")); //send message to topic GrouperMessagingEngine.send(new GrouperMessageSendParam().assignGrouperMessageSystemName(GrouperBuiltinMessagingSystem.BUILTIN_NAME).assignQueueType(GrouperMessageQueueType.topic).assignQueueOrTopicName("queueName").addMessageBody("Some message body")); //receive messages GrouperMessageReceiveResult grouperMessageReceiveResult = GrouperMessagingEngine.receive(new GrouperMessageReceiveParam().assignGrouperMessageSystemName(GrouperBuiltinMessagingSystem.BUILTIN_NAME).assignQueueName(queueName)); Collection<GrouperMessage> grouperMessages = grouperMessageReceiveResult.getGrouperMessages(); //acknowledge message as processed GrouperMessagingEngine.acknowledge(new GrouperMessageAcknowledgeParam().assignAcknowledgeType(GrouperMessageAcknowledgeType.mark_as_processed).assignQueueName("abc").addGrouperMessage(grouperMessage).assignGrouperMessageSystemName(GrouperBuiltinMessagingSystem.BUILTIN_NAME)); //acknowledge message as return to queue (receive next time ask for messages) GrouperMessagingEngine.acknowledge(new GrouperMessageAcknowledgeParam().assignAcknowledgeType(GrouperMessageAcknowledgeType.return_to_queue).assignQueueName("abc").addGrouperMessage(grouperMessage).assignGrouperMessageSystemName(GrouperBuiltinMessagingSystem.BUILTIN_NAME)); //acknowledge message as return to queue (receive after other messages on the queue) GrouperMessagingEngine.acknowledge(new GrouperMessageAcknowledgeParam().assignAcknowledgeType(GrouperMessageAcknowledgeType.return_to_end_of_queue).assignQueueName("abc").addGrouperMessage(grouperMessage).assignGrouperMessageSystemName(GrouperBuiltinMessagingSystem.BUILTIN_NAME)); //acknowledge message send to another queue or topic (e.g. dead letter queue, dlq) GrouperMessagingEngine.acknowledge(new GrouperMessageAcknowledgeParam().assignAcknowledgeType(GrouperMessageAcknowledgeType.send_to_another_queue).assignQueueName("abc").addGrouperMessage(grouperMessage).assignGrouperMessageSystemName(GrouperBuiltinMessagingSystem.BUILTIN_NAME).assignAnotherQueueParam(new GrouperMessageQueueParam().assignQueueOrTopicName("dlq").assignQueueType(GrouperMessageQueueType.queue)); |
sdf