[Mondrian] Problem with dynamic roles extending MDXConnection

Xavier Gumara xgumara at gmail.com
Mon Jun 10 05:38:10 EDT 2013


Hello,

I am trying to implement dynamic roles in Mondrian (3.5) and Pentaho (4.8)
using a custom MDXConnection class but I can't get it to work.

Using Steel Wheels, my goal is to have a "Territory Manager" role and
dynamically assign Territory access (EMEA, Japan, NA,...) to each user.

1. First of all I added this role tag in the schema and assigned the role
to user Joe:

<Role name="Territory Manager">
<SchemaGrant access="all">
 <CubeGrant cube="SteelWheelsSales" access="all">
<HierarchyGrant hierarchy="[Markets].[Markets]" access="custom"
rollupPolicy="partial">
 <MemberGrant member="[Markets].[EMEA]" access="all" />
</HierarchyGrant>
 </CubeGrant>
</SchemaGrant>
</Role>

2. Secondly I implemented classes SteelWheelsMDXConnection
and SteelWheelsCustomRole as follows. The goal is to change the territory
Joe has access from EMEA to Japan. I modified the pentahoObjects.spring.xml
file accordingly.

public class SteelWheelsMDXConnection extends MDXConnection {

@Override
protected void init (Util.PropertyList properties) {
 super.init(properties);
Connection thisConn = this.getConnection();
Role authRole = thisConn.getSchema().lookupRole("Territory Manager");
 SteelWheelsCustomRole customRole = new SteelWheelsCustomRole(authRole);
thisConn.setRole(customRole);
 setRole(customRole);
}

}

public class SteelWheelsCustomRole extends DelegatingRole {
 private String territory;
private static String HIERARCHY_NAME = "Markets";
 public SteelWheelsCustomRole(Role role) {
super(((RoleImpl) role).makeMutableClone());
this.territory = "Japan";
 }
 @Override
public HierarchyAccess getAccessDetails(Hierarchy hierarchy) {
 HierarchyAccess ha = super.getAccessDetails(hierarchy);
return (ha == null ? null : new CustomHierarchyAccess(ha));
 }
 protected class CustomHierarchyAccess extends
RoleImpl.DelegatingHierarchyAccess {
 protected HierarchyAccess ha;
 public CustomHierarchyAccess(HierarchyAccess ha) {
 super(ha);
this.ha = ha;
}
 @Override
public Access getAccess(Member member) {
return SteelWheelsCustomRole.this.getAccess(member, ha.getAccess(member));
 }
}
 @Override
 public Access getAccess(Hierarchy hierarchy) {
return role.getAccess(hierarchy);
}
 @Override
public Access getAccess(Member member) {
 return getAccess(member, role.getAccess(member));
}
 protected Access getAccess(Member member, Access access) {
String memberHierarchyName = member.getHierarchy().getName();
 if (memberHierarchyName.contains(HIERARCHY_NAME)) {
if (member.getName().equalsIgnoreCase(this.territory)) {
 return Access.ALL;
}
for (Member mem : member.getAncestorMembers()) {
 if (mem.getName().equalsIgnoreCase(this.territory)) {
return Access.ALL;
}
 }
Access acc = (access == Access.CUSTOM) ? access : Access.NONE;
return acc;
 }
return access;
}
 @Override
public Access getAccess(Level level) {
return role.getAccess(level);
 }
 @Override
public boolean canAccess(OlapElement olapElement) {
 return true;
 }
}

3. The code executes without errors but Joe still sees EMEA only when I
create a new analysis view.

If I debug the code, I can see the "getAccess(Member member)" method only
gets called for the "All markets" member. Is this supposed to be the way to
work with dynamic roles? How can I get children members for "All markets"?
Where does access to Territories get checked when creating a new MDX
connection?

Thank you for your answers.
Xavier Gumara
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.pentaho.org/pipermail/mondrian/attachments/20130610/23dedfbf/attachment.html 


More information about the Mondrian mailing list