Jazz Forum Welcome to the Jazz Community Forum Connect and collaborate with IBM Engineering experts and users

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?

Approvers

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

0 votes



3 answers

Permanent link
Here's the test method of a policy to verify that all aprovers (both individuals and users in groups) have approved.  To make it compile you'll need to include the com.ibm.ram.repository.jar file available on the server in the <install dir>\IBM\WebSphere\AppServer\profiles\AppSrv01\installedApps\<cell>\RAM1WebApplication.ear\com.ibm.ram.repository.web.war\WEB-INF\lib directory.

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());
		Set approvingUsers = 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;
		
	}

0 votes

Comments

You will need com.ibm.ram.repository.jar file ONLY for compiling. Do not include it when installing the policy into RAM. It is already there and you will cause yourself grief.


Permanent link

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

0 votes

Comments

... if you provide more info, we may be able to help guide you on this.
what specifically is not working for you?


Permanent link
Looking at the code above, there is a minor glitch, where as it will require EVERYONE in the group to approve, in order  for the policy to to return success.  I fixed/cleaned up the code below -- simple change. 

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

0 votes

Your answer

Register or log in to post your answer.

Dashboards and work items are no longer publicly available, so some links may be invalid. We now provide similar information through other means. Learn more here.

Search context
Follow this question

By Email: 

Once you sign in you will be able to subscribe for any updates here.

By RSS:

Answers
Answers and Comments
Question details
× 10,938

Question asked: Dec 05 '12, 4:17 a.m.

Question was seen: 4,913 times

Last updated: Mar 06 '13, 11:19 a.m.

Confirmation Cancel Confirm