In Grouper 4.9.0+ there is a new optional format for GSH templates.
You can use the previous format without making changes, there are no plans to deprecate it. The new version involves only the source code (GSH) and the template version. All the inputs and validations etc work the same.
Advantages
- You can have test cases and test from the UI
- This facilitates easier changes
- Quicker to test during upgrades
- More reliable GSH template logic
- The template only executes in GSH once
- The templates are a lot faster
- Less resources used in UI/WS
Write a new template
- Configure the template and inputs in UI
- Make a subclass of GshTemplateV2
- Implement the gshRunLogic() method
- Optionally override the decorateTemplateForUiDisplay() method for dynamic dropdown templates
- Declare variables like was generated for you in V1 templates
- Register the subclass with Grouper
For details see the example below...
Convert from old to new
- Edit template
- Make a class with subclass
- Declare the built in variables yourself (see example)
Convert any "GSH shortcuts" to the Grouper Java API. e.g.
FROMaddMember("a:b:c", "jsmith");
TO
Group group = GroupFinder.findByName("a:b:c", true); group.addMember(SubjectFinder.findByIdOrIdentifier("jsmith", true), false);
- Edit the template config, and mark version as v2
- Add tests as needed
- Run the tests from the UI
- Change from GrouperUtil.gshReturn() to return
Example without tests
Config
grouperGshTemplate.myTemplate.defaultRunButtonFolderUuidOrName = test grouperGshTemplate.myTemplate.displayErrorOutput = true grouperGshTemplate.myTemplate.folderShowType = allFolders grouperGshTemplate.myTemplate.input.0.description = app name grouperGshTemplate.myTemplate.input.0.label = App name grouperGshTemplate.myTemplate.input.0.name = gsh_input_appName grouperGshTemplate.myTemplate.input.0.validationBuiltin = alphaNumericUnderscore grouperGshTemplate.myTemplate.input.0.validationType = builtin grouperGshTemplate.myTemplate.input.1.description = input2 grouperGshTemplate.myTemplate.input.1.label = Input2 grouperGshTemplate.myTemplate.input.1.name = gsh_input_input2 grouperGshTemplate.myTemplate.input.1.validationType = none grouperGshTemplate.myTemplate.moreActionsLabel = test grouperGshTemplate.myTemplate.numberOfInputs = 2 grouperGshTemplate.myTemplate.runAsType = GrouperSystem grouperGshTemplate.myTemplate.runButtonGroupOrFolder = folder grouperGshTemplate.myTemplate.securityRunType = everyone grouperGshTemplate.myTemplate.showInMoreActions = true grouperGshTemplate.myTemplate.showOnFolders = true grouperGshTemplate.myTemplate.templateDescription = test grouperGshTemplate.myTemplate.templateName = test grouperGshTemplate.myTemplate.templateVersion = V2
Config from UI
Template source
Example of template with tests
Note this uses the same config as above
Declare a method that starts with "test" that takes no inputs and returns a GshTemplateV2test implementation. You can define the classes below the main template to keep things organized. The main template can have static variables which can be shared with the tests (so things dont get out of sync). Note, the tests should not be all that destructive since you will be running these in a grouper env. (e.g. dont delete the whole registry!)
Run the tests
Run a template from a main
public static void main(String[] args) { GrouperStartup.startup(); GrouperSession.internal_callbackRootGrouperSession(new GrouperSessionHandler() { @Override public Object callback(GrouperSession grouperSession) throws GrouperSessionException { Subject subject = SubjectFinder.findByIdAndSource("10021368", "pennperson", true); Test67listservRequestCreate test67listservRequestCreate = new Test67listservRequestCreate(); GshTemplateV2input gshTemplateV2input = new GshTemplateV2input(); gshTemplateV2input.setGsh_builtin_subject(subject); GshTemplateRuntime gshTemplateRuntime = new GshTemplateRuntime(); gshTemplateRuntime.setTemplateConfigId("pennNetMailingListRequestCreate"); gshTemplateV2input.setGsh_builtin_gshTemplateRuntime(gshTemplateRuntime); gshTemplateV2input.getGsh_builtin_inputs().put("gsh_input_action", "requestList"); gshTemplateV2input.getGsh_builtin_inputs().put("gsh_input_listName", "astt_idm"); gshTemplateV2input.getGsh_builtin_inputs().put("gsh_input_existingList", true); gshTemplateV2input.getGsh_builtin_inputs().put("gsh_input_description", "Used in ASTT for registration of cloud services"); gshTemplateV2input.getGsh_builtin_inputs().put("gsh_input_requestedBy", "mchyzer"); gshTemplateV2input.getGsh_builtin_inputs().put("gsh_input_ownerListRequirement", "iscEmployee"); gshTemplateV2input.getGsh_builtin_inputs().put("gsh_input_sendersListRequirement", "iscEmployee"); gshTemplateV2input.getGsh_builtin_inputs().put("gsh_input_membersListRequirement", "iscEmployee"); gshTemplateV2input.getGsh_builtin_inputs().put("gsh_input_automaticOrgs", null); gshTemplateV2input.getGsh_builtin_inputs().put("gsh_input_automaticGroupNames", null); gshTemplateV2input.getGsh_builtin_inputs().put("gsh_input_canOptout", false); gshTemplateV2input.getGsh_builtin_inputs().put("gsh_input_optinsGroupName", null); gshTemplateV2input.getGsh_builtin_inputs().put("gsh_input_managersGroupName", null); gshTemplateV2input.getGsh_builtin_inputs().put("gsh_input_enabled", false); GshTemplateV2output gshTemplateV2output = new GshTemplateV2output(); test67listservRequestCreate.gshRunLogic(gshTemplateV2input, gshTemplateV2output); return null; } }); System.exit(0); }
Run a test from a main
public static void main(String[] args) { Test68listservTeam myGshTemplate = new Test68listservTeam(); GshTemplateExecTestOutput gshTemplateExecTestOutput = GshTemplateV2utils.gshRunTest(myGshTemplate, "testApproveRequest"); System.out.println(gshTemplateExecTestOutput.toString()); System.exit(0); }