Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Include Page
spaceKeyGrouper
pageTitleNavigation

Table of Contents

Panel
borderColor#ccc
bgColor#FcFEFF
titleColorwhite
titleBGColor#00a400

 This topic is discussed in the "Grouper API - Part 2" training video.

...

Code Block
export GSH_JVMARGS="-Dlibrary.jansi.path=/some/other/temp/path/with/exec"

Supported Commands

Grouper API methods

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:

Environment variables that affect GSH startup:

  • GROUPER_HOME: if set to a valid Grouper directory, it will use this directory. Otherwise, it will determine it based on the path to gsh
  • GROUPER_CONF: if set to a valid conf directory, it will use this directory. Otherwise it will determine it based on GROUPER_HOME
  • MEM_START: Override the default -Xms Java parameter (initial Java heap size)
  • MEM_MAX: Override the default -Xmx Java parameter (maximum Java heap size)
  • CLASSPATH: Will prepend to the constructed classpath
  • GSH_JVMARGS: Additional arguments to pass to Java
  • GSH_CYGWIN: (since 2.4.0 api patch 3) if set and not blank, the script will convert paths and the classpath to Windows-style, for use with Windows Java under Cygwin
  • GSH_QUIET: (since 2.4.0 api patch 3) if set and not blank, will not output preliminary diagnostic information before starting Java, other than errors

Command line arg in script

Code Block
./gsh -runarg 'userToFind="user1"\n:load "/opt/grouper/scripts/myGSHScript.gsh"'


Supported Commands

Grouper API methods

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:

No Format
gsh 0% GrouperSession.startRootSession();
gsh 0% subj = findSubject("SD00125")
subject
No Format
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' uuidname='d0fa765e-1439-4701-89b1-9b08b4ce9daaBarton, Tom'
gsh 1% sess 3%= memberGrouperSession.getGroupsstart(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

When using Java 1.8+ and Grouper 2.3 (later patches)+

this can be handy to print the group.getName() values for all groups that are found.

getGroups("Wheel").each{it -> println "${it.getName()}"}

setGroupAttr(group name, attr, value)

Set value

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

...

Code Block
new GroupSave(grouperSession).assignName("stem1:a").assignCreateParentStemsIfNotExist(true).save();

Group Types

Set attribute on group

New group types on folder

Code Block
GrouperSession 
Code Block
languagegroovy
titleAdd a new type with an attribute, add this to group and then set its value on the group, e.g.
grouperSession = GrouperSession.startRootSession();
gStem stem = GroupFinderStemFinder.findByName(sessiongrouperSession, "admin:loader_groups"test:gdg:app", true);
typeAttributeDefName typeMarker = typeAddAttributeDefNameFinder.findByName("sync_group"etc:objectTypes:grouperObjectTypeMarker", true);
type.addAttribute(session, "sync_group", false, "sync");
groupAddType("admin:loader_groups", "sync_group");
g.setAttribute("sync", "true");

...

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 AccessPrivilege (e.g. AccessPrivilege.ADMIN)

...

typeAddList(type name, attr name, read, write)

...

Create a custom list. read and write must be an AccessPrivilege (e.g. AccessPrivilege.ADMIN).

...

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

AttributeAssign attributeAssign = stem.getAttributeDelegate().hasAttribute(typeMarker) ? stem.getAttributeDelegate().retrieveAssignments(typeMarker).iterator().next() : stem.getAttributeDelegate().addAttribute(typeMarker).getAttributeAssign();
attributeAssign.getAttributeValueDelegate().assignValue("etc:objectTypes:grouperObjectTypeDirectAssignment", "true");
attributeAssign.getAttributeValueDelegate().assignValue("etc:objectTypes:grouperObjectTypeName", "app");


Set attribute on group

Code Block
languagegroovy
titleAdd a new type with an attribute, add this to group and then set its value on the group, e.g.
grouperSession = GrouperSession.startRootSession();
g = GroupFinder.findByName(session, "admin:loader_groups");
type = typeAdd("sync_group");
type.addAttribute(session, "sync_group", false, "sync");
groupAddType("admin:loader_groups", "sync_group");
g.setAttribute("sync", "true");


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 AccessPrivilege (e.g. AccessPrivilege.ADMIN)

typeAddList(type name, attr name, read, write)

Create a custom list. read and write must be an AccessPrivilege (e.g. AccessPrivilege.ADMIN).

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

Member change subject

Change subject of a Member object, e.g.:

grouperSession = GrouperSession.startRootSession();
oldSubject = findSubject("10021368");
member = MemberFinder.findBySubject(grouperSession, oldSubject);

Member change subject

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);

...

add test subjects to registry (e.g. test.subject.0 through 9)new RegistryReset()._addSubjects(RegistrySubject registrySubject = GrouperDAOFactory.getFactory().getRegistrySubject().find("user1a", "person
registrySubject.setName("New name" HibernateSessionbyObjectStatic.update(registrySubjectString principal = "someApp"; String email = null; GrouperSession grouperSession =

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();
SubjectFinder.findAll(searchString, source);

Find all subjects in a source by search string

grouperSession = GrouperSession.startRootSession();
SubjectFinder.findByIdAndSource(id, source, exceptionIfNull);
SubjectFinder.findByIdAndSource("12345", "jdbc", true);

Find a subject by id in a certain source

grouperSession = GrouperSession.startRootSession();
SubjectFinder.findByIdentifierAndSource(identifier, source, exceptionIfNull);
SubjectFinder.findByIdentifierAndSource("jsmith", "jdbc", true);

Find a subject by identifier in a certain source

. You need the jdbc source for this to work. The type parameter describes the type of subject (e.g. "people"), and is required non-null even though there are few useful api methods to query it.

In 2.4.0.api.41+ patch, this will also create the id, name, description, and loginid attribute (unless grouper.properties create.attributes.when.creating.registry.subjects is false)

RegistrySubject.addOrUpdate(grouperSession, id, type, name, nameAttributeValue, loginid, description, email)In 2.4.0.api.41+ patch, add a registry subject like addSubject, but specify the attribute values of name, loginid, etc
e.g. RegistrySubject.addOrUpdate(grouperSession, "someTestSubject", "person", "Some Testsubject", "Name Some Test Subject", "stsub", "Some Testsubject - employee - also alumni", "some@test.subject");
RegistrySubject.find(id, errorOnNotFound)In 2.4.0.api.41+ patch, get a registry subject
e.g. registrySubject = RegistrySubject.find("someTestSubject", false);
registrySubject.delete(grouperSession)In 2.4.0.api.41+ patch, delete a registry subject
e.g. registrySubject.delete(grouperSession);
RegistrySubjectAttribute.addOrUpdate(subjectId, attributeName, attributeValue)In 2.4.0.api.41+ patch, add or update a registry subject attribute
registrySubjectAttribute.delete()In 2.4.0.api.41+ patch, delete an attribute value

findSubject(idOrIdentifier)

Find a subject by id or identifier

findSubject(idOrIdentifier, type)

Find a subject by id or identifier; type is a deprecated parameter that is ignored

findSubject(idOrIdentifier, type, source)grouperSession = GrouperSession.startRootSession();
SubjectFinder.findByIdOrIdentifierAndSource(idOrIdentifier, source, exceptionIfNull);
SubjectFinder.findByIdOrIdentifierAndSource("jsmith", "jdbc", true);

Find a subject by id or identifier in for a certain sourcespecific subject source; type is a deprecated parameter that is ignored

getSources()

Find all Subject sources

grouperSession = GrouperSession.startRootSession();

SubjectFinder.findAll(searchString, source);

Find all subjects in a source by search string

grouperSession = GrouperSession.startRootSession();
SubjectFinder.findByIdAndSource(id, source, exceptionIfNull);
SubjectFinder.findByIdAndSource("12345", "jdbc

Edit subject (in this case name)

", true);

Find a subject by id in a certain source

grouperSession = GrouperSession.startRootSession();

SubjectFinder.

findByIdentifierAndSource(identifier, source, exceptionIfNull)

;
SubjectFinder.findByIdentifierAndSource("jsmith", "jdbc", true);

add a subject application principal with attributes (GSH)

Find a subject by identifier in a certain source

grouperSession =

Code Block

GrouperSession.startRootSession();
SubjectFinder.findByIdOrIdentifierAndSource(idOrIdentifier, source, exceptionIfNull);
SubjectFinder.findByIdOrIdentifierAndSource("jsmith", "jdbc", true);

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();
new RegistryReset()._addSubjects();

Edit subject (in this case name)

RegistrySubject registrySubject = GrouperDAOFactory.getFactory().getRegistrySubject().find("user1a", "person", true);
registrySubject.setName("New name");
HibernateSession.byObjectStatic().update(registrySubject);

add a subject application principal with attributes (GSH)


Code Block
String principal = "someApp";
String email = null;

GrouperSession grouperSession = GrouperSession.startRootSession();


addSubject(principal, "application", principal);
HibernateSession.bySqlStatic().executeSql("insert into


addSubject(principal, "application", principal);
HibernateSession.bySqlStatic().executeSql("insert into subjectattribute (subjectId, name, value, searchValue) values (?, ?, ?, ?)", GrouperUtil.toListObject(new Object[]{principal, "description", principal, principal.toLowerCase()}));
if (email != null){ HibernateSession.bySqlStatic().executeSql("insert into subjectattribute (subjectId, name, value, searchValue) values (?, ?, ?, ?)", GrouperUtil.toListObject(new Object[]{principal, "email", email, email.toLowerCase()}));}
HibernateSession.bySqlStatic().executeSql("insert into subjectattribute (subjectId, name, value, searchValue) values (?, ?, ?, ?)", GrouperUtil.toListObject(new Object[]{principal, "loginiddescription", principal, principal.toLowerCase()}));
if (email != null){ HibernateSession.bySqlStatic().executeSql("insert into subjectattribute (subjectId, name, value, searchValue) values (?, ?, ?, ?)", GrouperUtil.toListObject(new Object[]{principal, "nameemail", principalemail, principalemail.toLowerCase()}));


remove a subject with attributes (GSH)
Code Block
String principal = "someApp";
String email = null;

GrouperSession grouperSession = GrouperSession.startRootSession();

HibernateSession.bySqlStatic().executeSql("delete from subjectattribute where subjectId = ?}
HibernateSession.bySqlStatic().executeSql("insert into subjectattribute (subjectId, name, value, searchValue) values (?, ?, ?, ?)", GrouperUtil.toListObject(new Object[]{principal, "loginid", principal, principal}));
HibernateSession.bySqlStatic().executeSql("delete from subject where subjectId = ?insert into subjectattribute (subjectId, name, value, searchValue) values (?, ?, ?, ?)", GrouperUtil.toListObject(new Object[]{principal, "name", principal, principal}));

System

...

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





remove a subject with attributes (GSH)


Code Block
String principal = "someApp";
String email = null;

GrouperSession grouperSession = GrouperSession.startRootSession();

HibernateSession.bySqlStatic().executeSql("delete from subjectattribute where subjectId = ?", GrouperUtil.toListObject(new Object[]{principal}));
HibernateSession.bySqlStatic().executeSql("delete from subject where subjectId = ?", GrouperUtil.toListObject(new Object[]{principal}));


System

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

Unresolvable subject deletion utility (USDU)

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();
 usdu()

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")
 session=GrouperSession.start(subject)"
 memberSubject=SubjectFinder.findById("1234567")
 member=MemberFinder.findBySubject(session,memberSubject)
 usduByMember(member)

Work only with a specific member

usduByMember(member, usdu.DELETE)

usdu by member, and delete memberships

Find bad 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


XML legacy

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

XML export legacy

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:

No Format
gsh 1% new XmlExport()

Unresolvable subject deletion utility (USDU)

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();
 usdu()

...

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")
 session=GrouperSession.start(subject)"
 memberSubject=SubjectFinder.findById("1234567")
 member=MemberFinder.findBySubject(session,memberSubject)
 usduByMember(member)

...

Work only with a specific member

...

usduByMember(member, usdu.DELETE)

...

usdu by member, and delete memberships

Find bad 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

XML legacy

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

XML export legacy

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:

No Format
gsh 1% new XmlExport().exportToFile(new File("c:/temp/export.xml"))
No Format
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)

No Format
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"))

XML import legacy

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.
Missing Stems and Groups are not created.

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:


No Format
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)

No Format
gsh 3% xmlExport = new XmlExport();
gsh 4% xmlExport.stem(stem);
gsh 5% xmlExport.grouperSession(grouperSession);
gsh 6% xmlExport.exportToFile
No Format
gsh 1% new XmlImport().importFromFile(new File("c:/temp/export.xml"))
No Format
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)

XML import legacy

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.
Missing Stems and Groups are not created.

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:

No Format
gsh 1% new XmlImport()
No Format
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

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
   Can use: "READONLY_OR_USE_EXISTING", "NONE", "READONLY_NEW",
"READ_WRITE_OR_USE_EXISTING", "READ_WRITE_NEW"

transactionCommit("<GrouperCommitType>")

commit a transaction
   Can use: "COMMIT_NOW", "COMMIT_IF_NEW_TRANSACTION

transactionRollback("<GrouperRollbackType>")

rollback a transaction
    Can use: "ROLLBACK_NOW", "ROLLBACK_IF_NEW_TRANSACTION

transactionEnd()

end a transaction
    Note if it was read/write, and not committed or rolled back, this will commit and end

Loader

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();
loaderGroup = GroupFinder.findByName(grouperSession, "stem:group");
loaderRunOneJob(loaderGroup);

...

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");
loaderRunOneJob("MAINTENANCE__rules");

...

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:

Code Block
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)
Code Block
languagesql
titleHSQLDB (similar example)
select distinct job_name from grouper_loader_log gll where started_time > CURRENT_DATE - 1 DAY and status != 'SUCCESS' and gll.job_name not like 'subjobFor%' 
AND NOT EXISTS (select job_name from grouper_loader_log gll2 where gll2.started_time > CURRENT_DATE - 1 DAY 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

GrouperShell Variables (BeanShell only)

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


No Format
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)

No Format
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

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
   Can use: "READONLY_OR_USE_EXISTING", "NONE", "READONLY_NEW",
"READ_WRITE_OR_USE_EXISTING", "READ_WRITE_NEW"

transactionCommit("<GrouperCommitType>")

commit a transaction
   Can use: "COMMIT_NOW", "COMMIT_IF_NEW_TRANSACTION

transactionRollback("<GrouperRollbackType>")

rollback a transaction
    Can use: "ROLLBACK_NOW", "ROLLBACK_IF_NEW_TRANSACTION

transactionEnd()

end a transaction
    Note if it was read/write, and not committed or rolled back, this will commit and end

Loader

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();
loaderGroup = GroupFinder.findByName(grouperSession, "stem:group");
loaderRunOneJob(loaderGroup);

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");
loaderRunOneJob("MAINTENANCE__rules");

Run the Grouper Rules daemon (the changelog or full version)

loaderRunOneJob("CHANGE_LOG_consumer_test");

Run a change log consumer

GrouperLoaderType.validateAndScheduleSqlLoad(group, null, false)Schedule SQL job
GrouperLoaderType.validateAndScheduleLdapLoad(attributeAssign, null, false)Schedule LDAP job

This query (in Oracle) will find jobs with no success in the last day and make a gsh script:

Code Block
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)


Code Block
languagesql
titleHSQLDB (similar example)
select distinct job_name from grouper_loader_log gll where started_time > CURRENT_DATE - 1 DAY and status != 'SUCCESS' and gll.job_name not like 'subjobFor%' 
AND NOT EXISTS (select job_name from grouper_loader_log gll2 where gll2.started_time > CURRENT_DATE - 1 DAY 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

GrouperShell Variables (BeanShell only)

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:

No Format
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'

Membership scripts

Code Block
# (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);
    }
}

# (3) Get the groups this subject is a member of. Note that a group is a kind of subject, and has a toSubject() method to convert it.

import edu.internet2.middleware.grouper.membership.MembershipSubjectContainer

GrouperSession grouperSession = GrouperSession.startRootSession();

Group group = GroupFinder.findByName(grouperSession, "test:testGroup", true);
Subject subject = g.toSubject();

Set<MembershipSubjectContainer> msc = new MembershipFinder().addSubject(subject).findMembershipResult().getMembershipSubjectContainers();

for (MembershipSubjectContainer membershipSubjectContainer : msc) { println(membershipSubjectContainer.getGroupOwner().getName());}

//Note there are a few other options for the search. Add these to the MembershipFinder method chain before calling findMembershipResult():
//  - search immediate, effective, etc. (needs to import MembershipType)
import edu.internet2.middleware.grouper.membership.MembershipType
membershipFinder.assignMembershipType(MembershipType.IMMEDIATE) // options are IMMEDIATE|NONIMMEDIATE|EFFECTIVE|COMPOSITE
//  - retrieve specific groups based on pattern
membershipFinder.assignScope("%:test:%")
//  - Enabled status -- true means enabled only, false, means disabled only, and null means all
membershipFinder.assignEnabled(false)
// For other methods, refer to the Javadoc at http://internet2.github.io/grouper/master/grouper-parent/apidocs/edu/internet2/middleware/grouper/MembershipFinder.html


Misc

Note: you cannot encrypt passwords with GSH since the passwords end up in the GSH history.  To encrypt passwords, issue the command:

No Format
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:

Code Block
new edu.internet2.middleware.grouper.misc.SyncPITTables().syncAllPITTables()

To create missing group sets:

Code Block
new edu.internet2.middleware.grouper.misc.AddMissingGroupSets().addAllMissingGroupSets();

Delete memberships not in transaction

Code Block
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

Create a script from SQL

Here is an example to remove access from someone...  run a SQL to generate a GSH script, e.g. in oracle:

Code Block
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:

Code Block
grouperSession = GrouperSession.startRootSession();

Look at it and remove lines that dont apply...  then run in GSH

Code Block
[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:

Code Block
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():

Code Block
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():

Code Block
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():

Code Block
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

Attribute framework

Create a permission and configure action list:

Code Block
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"

Code Block
attributeDefName = AttributeDefNameFinder.findByName("school:attr:students:artsAndSciences", true);
group.getAttributeDelegate().retrieveAssignments(attributeDefName);


Anchor
disableLoaders
disableLoaders
disableLoaders.gsh ( disableLoaders.gsh ) 

The following script will print to standard output (not saved as files) two scripts.

  • One to disable all loader jobs (AKA: "DISABLE ALL SCHEDULES").
  • A second one to re-enabled  them (AKA: "RESTORE OLD SCHEDULES") .

  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...

Code Block
languagegroovy
titledisableLoaders.gsh
: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 * * * ?" .

Code Block
languagebash
titleExample of running disableLoaders.gsh
[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");



Rules

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

Code Block
GrouperSession grouperSession = GrouperSession.startRootSession();
AttributeAssign attributeAssign = AttributeAssignFinder.findById("b629bd8170964663be507968752f4f17", true);
attributeAssign.delete();


Grouper Builtin Messaging

Create queues / topics, assign privileges for Grouper builtin messaging (not activemq, rabbitmq, AWS, etc) (Grouper 2.3+)

Code Block
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");


Grouper messaging 

Send, receive, acknowledge messages in any message system (Grouper builtin, activeMQ, rabbitmq, AWS, etc) (Grouper 2.3+)

Code Block
//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));



Expression language testing


Code Block
Set this in log4j.properties


log4j.logger.edu.internet2.middleware.grouper.util.GrouperUtil = DEBUG


Run GSH:


gsh 0% GrouperSession grouperSession = GrouperSession.startRootSession();
gsh 1% Group 

    Example:

No Format
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'

Membership scripts

Code Block
# (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);
    }
}


Misc

Note: you cannot encrypt passwords with GSH since the passwords end up in the GSH history.  To encrypt passwords, issue the command:

No Format
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:

Code Block
new edu.internet2.middleware.grouper.misc.SyncPITTables().syncAllPITTables()

To create missing group sets:

Code Block
new edu.internet2.middleware.grouper.misc.AddMissingGroupSets().addAllMissingGroupSets();

Delete memberships not in transaction

Code Block
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

Create a script from SQL

Here is an example to remove access from someone...  run a SQL to generate a GSH script, e.g. in oracle:

Code Block
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:

Code Block
grouperSession = GrouperSession.startRootSession();

Look at it and remove lines that dont apply...  then run in GSH

Code Block
[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:

Code Block
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():

Code Block
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():

Code Block
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():

Code Block
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

Attribute framework

Create a permission and configure action list:

Code Block
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"

Code Block
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.

  • One to disable all loader jobs (AKA: "DISABLE ALL SCHEDULES").
  • A second one to re-enabled  them (AKA: "RESTORE OLD SCHEDULES") .

  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.

...

Code Block
languagegroovy
titledisableLoaders.gsh
: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, \"apps:loader" + 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);
gsh 2% Map variableMap =  new HashMap();
gsh 3% variableMap.put("theGroup", group);
gsh 4% String result = GrouperUtil.substituteExpressionLanguage("Name: ${theGroup.name}", variableMap);
gsh 5% result
Name: apps:loader

This is the log entry:

2018-06-04 22:32:58,197: [main] DEBUG GrouperUtil.substituteExpressionLanguage(9416) -  - Subsituting EL: 'Name: ${theGroup.name}', and with env vars: theGroup, grouperUtil with result: 'Name: apps:loader'



Example of attribute value assign to group and SQL query

Code Block
gsh 0% GrouperSession grouperSession = GrouperSession.startRootSession();\n");
result.append("sqlLoaderDefNamegsh 1% AttributeDef attributeDef = 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 * * * ?" .

Code Block
languagebash
titleExample of running disableLoaders.gsh
[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");


Rules

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

Code Block
GrouperSession grouperSession = GrouperSession.startRootSession();
AttributeAssign attributeAssign = AttributeAssignFinder.findById("b629bd8170964663be507968752f4f17", true);
attributeAssign.delete();

Grouper Builtin Messaging

Create queues / topics, assign privileges for Grouper builtin messaging (not activemq, rabbitmq, AWS, etc) (Grouper 2.3+)

Code Block
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");


Grouper messaging 

Send, receive, acknowledge messages in any message system (Grouper builtin, activeMQ, rabbitmq, AWS, etc) (Grouper 2.3+)

Code Block
//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));


Expression language testing

Code Block
Set this in log4j.properties


log4j.logger.edu.internet2.middleware.grouper.util.GrouperUtil = DEBUG


Run GSH:


gsh 0% GrouperSession grouperSession = GrouperSession.startRootSession();
gsh 1% Group group = GroupFinder.findByName(grouperSession, "apps:loader");
gsh 2% Map variableMap =  new HashMap();
gsh 3% variableMap.put("theGroup", group);
gsh 4% String result = GrouperUtil.substituteExpressionLanguage("Name: ${theGroup.name}", variableMap);
gsh 5% result
Name: apps:loader

This is the log entry:

2018-06-04 22:32:58,197: [main] DEBUG GrouperUtil.substituteExpressionLanguage(9416) -  - Subsituting EL: 'Name: ${theGroup.name}', and with env vars: theGroup, grouperUtil with result: 'Name: apps:loader'


Example of attribute value assign to group and SQL query

Code Block
gsh 0% GrouperSession grouperSession = GrouperSession.startRootSession();
gsh 1% AttributeDef attributeDef = new AttributeDefSave(grouperSession).assignName("test:testAttribute:someAttrDef").assignCreateParentStemsIfNotExist(true).assignToGroup(true).assignAttributeDefType(AttributeDefType.attr).assignMultiAssignable(false).assignMultiValued(false).assignValueType(AttributeDefValueType.string).save();
gsh 2% AttributeDefName attributeDefName = new AttributeDefNameSave(grouperSession, attributeDef).assignName("test:testAttribute:someAttr").assignCreateParentStemsIfNotExist(true).save();
gsh 3% Group group = new GroupSave(grouperSession).assignName("test:testAttribute:group").assignCreateParentStemsIfNotExist(true).save()
gsh 4% group.getAttributeValueDelegate().assignValueString(attributeDefName.getName(), "someValue");
edu.internet2.middleware.grouper.attr.value.AttributeValueResult: edu.internet2.middleware.grouper.attr.value.AttributeValueResult@2f08e6d3
gsh 5% HibernateSession.bySqlStatic().select(String.class, "SELECT value_string FROM grouper_aval_asn_group_v WHERE group_name = 'test:testAttribute:group' AND attribute_def_name_name = 'test:testAttribute:someAttr'");
someValue
gsh 6% 

Example of finding groups with a certain attribute value

Code Block
GrouperSession grouperSession = GrouperSession.startRootSession();
Set<Group> groups = new GroupFinder().assignNameOfAttributeDefName("bath:provisionClass").assignAttributeValue("groupmanager-groups")
       .assignPrivileges(AccessPrivilege.ATTRIBUTE_READ_PRIVILEGES).findGroups();

Example of finding groups with a certain attribute value on metadata assignments

This is useful for attestation and loader metadata, for example.

Code Block
//groups loaded by a particular group
def attrDef = AttributeDefNameFinder.findByName(GrouperCheckConfig.loaderMetadataStemName() + ":" + GrouperLoader.ATTRIBUTE_GROUPER_LOADER_METADATA_GROUP_ID, true)            
def groups = new GroupFinder().assignIdOfAttributeDefName(attrDef.id).assignAttributeValuesOnAssignment(GrouperUtil.toSetObjectType("3779b51223804784b4a02ee238b73079")).findGroups()

//    OR, without the extra attributeDef, look up the name directly in GroupFinder
def groups = new GroupFinder().assignNameOfAttributeDefName("etc:attribute:loaderMetadata:grouperLoaderMetadataGroupId").assignAttributeValuesOnAssignment(GrouperUtil.toSetObjectType("3779b51223804784b4a02ee238b73079")).findGroups()


//attestations that are due
import edu.internet2.middleware.grouper.app.attestation.GrouperAttestationJob
def groups = new GroupFinder().assignIdOfAttributeDefName(GrouperAttestationJob.retrieveAttributeDefNameCalculatedDaysLeft().id).assignAttributeValuesOnAssignment(GrouperUtil.toSetObjectType("0")).findGroups(
 new AttributeDefSave(grouperSession).assignName("test:testAttribute:someAttrDef").assignCreateParentStemsIfNotExist(true).assignToGroup(true).assignAttributeDefType(AttributeDefType.attr).assignMultiAssignable(false).assignMultiValued(false).assignValueType(AttributeDefValueType.string).save();
gsh 2% AttributeDefName attributeDefName = new AttributeDefNameSave(grouperSession, attributeDef).assignName("test:testAttribute:someAttr").assignCreateParentStemsIfNotExist(true).save();
gsh 3% Group group = new GroupSave(grouperSession).assignName("test:testAttribute:group").assignCreateParentStemsIfNotExist(true).save()
gsh 4% group.getAttributeValueDelegate().assignValueString(attributeDefName.getName(), "someValue");
edu.internet2.middleware.grouper.attr.value.AttributeValueResult: edu.internet2.middleware.grouper.attr.value.AttributeValueResult@2f08e6d3
gsh 5% HibernateSession.bySqlStatic().select(String.class, "SELECT value_string FROM grouper_aval_asn_group_v WHERE group_name = 'test:testAttribute:group' AND attribute_def_name_name = 'test:testAttribute:someAttr'");
someValue
gsh 6% 


Example of finding groups with a certain attribute value

Code Block
GrouperSession grouperSession = GrouperSession.startRootSession();
Set<Group> groups = new GroupFinder().assignNameOfAttributeDefName("bath:provisionClass").assignAttributeValue("groupmanager-groups")
       .assignPrivileges(AccessPrivilege.ATTRIBUTE_READ_PRIVILEGES).findGroups();


Example of finding groups with a certain attribute value on metadata assignments

This is useful for attestation and loader metadata, for example.

Code Block
//groups loaded by a particular group
def attrDef = AttributeDefNameFinder.findByName(GrouperCheckConfig.loaderMetadataStemName() + ":" + GrouperLoader.ATTRIBUTE_GROUPER_LOADER_METADATA_GROUP_ID, true)            
def groups = new GroupFinder().assignIdOfAttributeDefName(attrDef.id).assignAttributeValuesOnAssignment(GrouperUtil.toSetObjectType("3779b51223804784b4a02ee238b73079")).findGroups()

//    OR, without the extra attributeDef, look up the name directly in GroupFinder
def groups = new GroupFinder().assignNameOfAttributeDefName("etc:attribute:loaderMetadata:grouperLoaderMetadataGroupId").assignAttributeValuesOnAssignment(GrouperUtil.toSetObjectType("3779b51223804784b4a02ee238b73079")).findGroups()


//attestations that are due
import edu.internet2.middleware.grouper.app.attestation.GrouperAttestationJob
def groups = new GroupFinder().assignIdOfAttributeDefName(GrouperAttestationJob.retrieveAttributeDefNameCalculatedDaysLeft().id).assignAttributeValuesOnAssignment(GrouperUtil.toSetObjectType("0")).findGroups()



Example of finding provisioning targets for PSPNG

Example of finding provisioning targets for PSPNG

Code Block
gsh 0% HibernateSession.bySqlStatic().listSelect(String.class, "SELECT DISTINCT gaaa.value_string FROM grouper_attribute_assign_value gaaa, grouper_attribute_assign gaa, grouper_attribute_def_name gadn WHERE gaaa.attribute_assign_id = gaa.id AND gaa.attribute_def_name_id = gadn.id AND gadn.extension IN ('provision_to', 'do_not_provision_to')", null, null);
java.util.ArrayList: [ad, ldap]

Example of finding which groups are provisioned to a certain target (from daemon where PSPNG is installed)

Code Block
provisioner_name="xyz"; // Whatever your provisioner is called in grouper_loader.properties
gs=GrouperSession.startRootSession();
provisioner=edu.internet2.middleware.grouper.pspng.ProvisionerFactory.createProvisioner(provisioner_name,false);
provisioner.getAllGroupsForProvisioner();

Long hand example of which groups are provisioned to a certain target

Code Block
    String provisionTarget = "ad";
    GrouperSession grouperSession = GrouperSession.startRootSession();
    
    Set stemsToProvisionToSet = HibernateSession.byHqlStatic().createQuery("select s from Stem s, AttributeAssign aa, AttributeDefName adn, AttributeAssignValue aav where s.id = aa.ownerStemId and aav.attributeAssignId = aa.id and aa.attributeDefNameId = adn.id and aa.attributeAssignTypeDb = 'stem' and aa.enabledDb = 'T' and adn.extensionDb = 'provision_to' and aav.valueString = '" + provisionTarget + "'").listSet(Stem.class);
    for (Object stemObject : stemsToProvisionToSet) { Stem stem = (Stem)stemObject; System.out.println("provision_to assigned to stem: " + stem.getName());  }
    Set stemsToNotProvisionToSet = HibernateSession.byHqlStatic().createQuery("select s from Stem s, AttributeAssign aa, AttributeDefName adn, AttributeAssignValue aav where s.id = aa.ownerStemId and aav.attributeAssignId = aa.id and aa.attributeDefNameId = adn.id and aa.attributeAssignTypeDb = 'stem' and aa.enabledDb = 'T' and adn.extensionDb = 'do_not_provision_to' and aav.valueString = '" + provisionTarget + "'").listSet(Stem.class);
    for (Object stemObject : stemsToNotProvisionToSet) { Stem stem = (Stem)stemObject; System.out.println("do_not_provision_to assigned to stem: " + stem.getName());  }
    Set groupsToProvisionToSet = HibernateSession.byHqlStatic().createQuery("select g from Group g, AttributeAssign aa, AttributeDefName adn, AttributeAssignValue aav where g.id = aa.ownerGroupId and aav.attributeAssignId = aa.id and aa.attributeDefNameId = adn.id and aa.attributeAssignTypeDb = 'group' and aa.enabledDb = 'T' and adn.extensionDb = 'provision_to' and aav.valueString = '" + provisionTarget + "'").listSet(Stem.class);
    for (Object groupObject : groupsToProvisionToSet) { Group group = (Group)groupObject; System.out.println("provision_to assigned to group: " + group.getName());  }
    Set groupsToNotProvisionToSet = HibernateSession.byHqlStatic().createQuery("select g from Group g, AttributeAssign aa, AttributeDefName adn, AttributeAssignValue aav where g.id = aa.ownerGroupId and aav.attributeAssignId = aa.id and aa.attributeDefNameId = adn.id and aa.attributeAssignTypeDb = 'group' and aa.enabledDb = 'T' and adn.extensionDb = 'do_not_provision_to' and aav.valueString = '" + provisionTarget + "'").listSet(Stem.class);
    for (Object groupObject : groupsToNotProvisionToSet) { Group group = (Group)groupObject; System.out.println("do_not_provision_to assigned to group: " + group.getName());  }
    Set allGroups = new LinkedHashSet();
    Set allGroupsToProvision = new TreeSet();
    allGroupsToProvision.addAll(groupsToProvisionToSet);

    Set stemNamesToNotProvisionTo = new HashSet();
    Set stemNamesToProvisionTo = new HashSet();
    
    for (Object stemToProvision : stemsToProvisionToSet) { stemNamesToProvisionTo.add(((Stem)stemToProvision).getName()); }
    for (Object stemNotToProvision : stemsToNotProvisionToSet) { stemNamesToNotProvisionTo.add(((Stem)stemNotToProvision).getName()); }

    for (Object stemToProvision : stemsToProvisionToSet) { allGroups.addAll(((Stem)stemToProvision).getChildGroups(edu.internet2.middleware.grouper.Stem.Scope.SUB)); }
    
    Map groupToPaths = new HashMap();
    for (Object groupObject : allGroups) { Group group = (Group)groupObject; if (allGroupsToProvision.contains(group)) {continue;} if (groupsToNotProvisionToSet.contains(group)) {continue;} List paths = new ArrayList(); groupToPaths.put(group, paths); String currentName = group.getName(); paths.add(currentName);  while(true) { currentName = GrouperUtil.parentStemNameFromName(currentName);  if (GrouperUtil.isBlank(currentName)) {break;} paths.add(currentName);  }   }
    
    for (Object groupObject : groupToPaths.keySet()) {Group group = (Group)groupObject; List paths = (List)groupToPaths.get(group); for (Object pathObject : paths) { String path = (String)pathObject; if (stemNamesToProvisionTo.contains(path)) { allGroupsToProvision.add(group); break; } if (stemNamesToNotProvisionTo.contains(path)) { break; } } }
    
    for (Object groupObject : allGroupsToProvision) { Group group = (Group)groupObject; System.out.println("configured to provision to: " + provisionTarget + ": " + group.getName()); }


Stem move

try this:

Code Block
GrouperSession.startRootSession();
stemFrom = StemFinder.findByName(grouperSession, "a:b", true);
stemTo = StemFinder.findByName(grouperSession, "a:c", true);
new edu.internet2.middleware.grouper.StemMove(stemFrom, stemTo).assignAlternateName(false).save();

...