RAM Custom Policy: How to find approvers and their vote?
Hello,
I need to write a custom policy to do the following:
1. Identify who the approvers are (User Groups and/or Users) and
2. If any users are added as approvers directly, then they must approve.
3. If any groups are added as approvers, then at least 1 member from each approving group must have approved. (ie not all approvers within the group need to approve - only 1 needs to approve.
(Note the approvers are not standard for each asset and are typically a group defined within a community - ie APPROVER GROUP 1, APPROVER GROUP 2 but may also be an individual user (Joe Smith). Therefore the asset owner will add the reviewers and approvers.
For example:
Approvers
- Joe Smith
- Group A [Approvers]
- Group B [Approvers]
Then Joe must approve and 1 person from Group A Approvers and 1 person from Group B Approvers must approve.
Can you please advise how to do this via the API?
I have been exploring the API as follows:
Lifecycle lifecycle = asset.getLifecycle().getValue();Set <Authorization> auth = lifecycle.getReviewBoardMembers();
StateConfiguration stateConfig = LifecycleUtilities.getStateConfiguration(lifecycle, asset.getState());
ReviewConfiguration revConfig = stateConfig.getReviewConfiguration();
//if (revConfig == null) {
//revConfig = new ReviewConfiguration();
//}
Set <Reviewer> reviewers = stateConfig.getReviewers();
Reviewer r1;
r1.isVoteAllowed();
RAMAsset asset2;
RAMVote [] ramVote = asset2.getCurrentStateHistory().getVotes();
ramVote[0].getVoteChoice();
Thanks,
-Angela
3 answers
public Result test() { RAMAsset asset = getPolicyContext().getRAMAsset(); Lifecycle lifecycle = null; try { Method getLifecycleMethod = asset.getClass().getDeclaredMethod("getLifecycle"); getLifecycleMethod.setAccessible(true); lifecycle = (Lifecycle)getLifecycleMethod.invoke(asset); } catch(NoSuchMethodException e) { handleError(e); } catch (IllegalArgumentException e) { handleError(e); } catch (IllegalAccessException e) { handleError(e); } catch (InvocationTargetException e) { handleError(e); } StateConfiguration stateConfig = LifecycleUtilities.getStateConfiguration(lifecycle, asset.getState().getIdentifier()); SetapprovingUsers = new HashSet (); for(RAMVote vote : asset.getCurrentStateHistory().getVotes()) { if(VoteChoice.APPROVE.equals(vote.getVoteChoice())) { approvingUsers.add(vote.getUser().getUid()); } } Result result = new Result(this); result.setReturnCode(Result.SUCCESS); for (Reviewer reviewer : stateConfig.getReviewers()) { if(reviewer.isVoteAllowed()) { if(reviewer.getUser() != null) { if(!approvingUsers.contains(reviewer.getUser().getValue().getIdentifier())) { result.setReturnCode(Result.ERROR); break; } } else if(reviewer.getUserGroup() != null) { String groupId = JAXBLinksUtil.getUserGroupIdentifier(reviewer.getUserGroup().getHref()); UserGroupInstance userGroup = null; try { userGroup = SecurityManager.getManager().getUserGroup(Integer.parseInt(groupId)); } catch (NumberFormatException e) { handleError(e); } catch (UserGroupNotFoundException e) { handleError(e); } ClosableIterator userGroupIter = null; try { userGroupIter = userGroup.getAllUsers(UserGroupInstance.START_WITH_FIRST_USER); for(IUserInformation user : userGroupIter) { if(!approvingUsers.contains(user.getUid())) { result.setReturnCode(Result.ERROR); break; } } } finally { if(userGroupIter != null) { userGroupIter.close(); } } } } } return result; }
Hi All,
Thank you for the information. I have incorporated the code into a policy and a policy governor (which I have emailed to Sheehan Anderson).
The policy doesnt seem to be working as required.
Can you please assist?
Thanks,
-Angela
I had a simple configuration: two reviewers, two groups, policy to run on actions and updates, and a criteria for the policy to return success before moving to the next stage. (you can optionally run this policy on a timer)
As you can see ... as reviewer voted, policy worked properly
public Result test()
{
Result status = new Result(this);
status.setReturnCode(Result.ERROR);
PolicyContext policyContext = this.getPolicyContext();
RAMAsset asset = policyContext.getRAMAsset();
if (isAssetApproved(asset, status))
{
status.setMessage("Approval creteria has been met");
status.setReturnCode(Result.SUCCESS);
}
else
{
status.setMessage("Approval creteria has NOT been met");
}
return status;
}
/* An asset is approved when the following occurs:
* - If any USERS are allocated as approvers, then all users MUST approve.
* - If any GROUPS are allocated as approvers, then at least 1 member from each group MUST approve.
*/
private boolean isAssetApproved(RAMAsset asset, Result status)
{
boolean assetApproved = true;
Lifecycle lifecycle = null;
ClosableIterator<IUserInformation> userGroupIter = null;
try
{
Method getLifecycleMethod = asset.getClass().getDeclaredMethod("getLifecycle");
getLifecycleMethod.setAccessible(true);
lifecycle = (Lifecycle)getLifecycleMethod.invoke(asset);
} catch(NoSuchMethodException e) {
System.out.println("Exception: \n" + e.toString());
} catch (IllegalArgumentException e) {
System.out.println("Exception: \n" + e.toString());
} catch (IllegalAccessException e) {
System.out.println("Exception: \n" + e.toString());
} catch (InvocationTargetException e) {
System.out.println("Exception: \n" + e.toString());
}
StateConfiguration stateConfig = LifecycleUtilities.getStateConfiguration(lifecycle, asset.getState().getIdentifier());
Set<String> approvingUsers = new HashSet<String>();
for(RAMVote vote : asset.getCurrentStateHistory().getVotes())
{
if(VoteChoice.APPROVE.equals(vote.getVoteChoice()))
{
approvingUsers.add(vote.getUser().getUid());
}
}
for (Reviewer reviewer : stateConfig.getReviewers())
{
if(reviewer.isVoteAllowed())
{
if(reviewer.getUser() != null)
{
if(!approvingUsers.contains(reviewer.getUser().getValue().getIdentifier()))
{
assetApproved = false;
status.addDetail(new ResultDetail(Result.ERROR,
"<font color=red>Reviewer\t["+reviewer.getUser().getValue().getName()+"] have not approved yet</font>"));
}
else
status.addDetail(new ResultDetail(Result.SUCCESS,
"Reviewer\t["+reviewer.getUser().getValue().getName()+"] approved"));
}
else if(reviewer.getUserGroup() != null)
{
String groupId = JAXBLinksUtil.getUserGroupIdentifier(reviewer.getUserGroup().getHref());
UserGroupInstance userGroup = null;
try
{
userGroup = SecurityManager.getManager().getUserGroup(Integer.parseInt(groupId));
} catch (NumberFormatException e) {
System.out.println("Exception: \n" + e.toString());
} catch (Exception e) {
System.out.println("Exception: \n" + e.toString());
}
try
{
userGroupIter = userGroup.getAllUsers(UserGroupInstance.START_WITH_FIRST_USER);
int approvals = 0;
for(IUserInformation user : userGroupIter)
if(approvingUsers.contains(user.getUid()))
approvals++;
if (approvals < APPROVAL_GROUP_MIN) {
assetApproved = false;
status.addDetail(new ResultDetail(Result.ERROR,
"<font color=red>Group\t["+userGroup.getName()+"] did not met creteria with "+approvals+" approvals</font>"));
}
else
status.addDetail(new ResultDetail(Result.SUCCESS,
"Group\t["+userGroup.getName()+"] met approval creteria"));
}
finally
{
if(userGroupIter != null)
{
userGroupIter.close();
}
}
}
}
}
return assetApproved;
}