<div dir="ltr">Hello,
<div><br></div><div>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.</div><div><br></div><div style>Using Steel Wheels, my goal is to have a "Territory Manager" role and dynamically assign Territory access (EMEA, Japan, NA,...) to each user.</div>
<div style><br></div><div style>1. First of all I added this role tag in the schema and assigned the role to user Joe:</div><div style><br></div><div style><div><Role name="Territory Manager"></div><div><span class="" style="white-space:pre">                </span><SchemaGrant access="all"></div>
<div><span class="" style="white-space:pre">                        </span><CubeGrant cube="SteelWheelsSales" access="all"></div><div><span class="" style="white-space:pre">                                </span><HierarchyGrant hierarchy="[Markets].[Markets]" access="custom" rollupPolicy="partial"></div>
<div><span class="" style="white-space:pre">                                </span><MemberGrant member="[Markets].[EMEA]" access="all" /></div><div><span class="" style="white-space:pre">                                </span></HierarchyGrant></div>
<div><span class="" style="white-space:pre">                </span></CubeGrant></div><div><span class="" style="white-space:pre">                </span></SchemaGrant></div><div><span class="" style="white-space:pre">        </span></Role></div>
</div><div style><br></div><div style>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.</div>
<div style><br></div><div style><div>public class SteelWheelsMDXConnection extends MDXConnection {</div><div><br></div><div><span class="" style="white-space:pre">        </span>@Override</div><div><span class="" style="white-space:pre">        </span>protected void init (Util.PropertyList properties) {</div>
<div><span class="" style="white-space:pre">                </span>super.init(properties);</div><div><span class="" style="white-space:pre">                </span>Connection thisConn = this.getConnection();</div><div><span class="" style="white-space:pre">                </span>Role authRole = thisConn.getSchema().lookupRole("Territory Manager");</div>
<div><span class="" style="white-space:pre">                </span>SteelWheelsCustomRole customRole = new SteelWheelsCustomRole(authRole);</div><div><span class="" style="white-space:pre">                </span>thisConn.setRole(customRole);</div><div>
<span class="" style="white-space:pre">                </span>setRole(customRole);</div><div><span class="" style="white-space:pre">        </span>}</div><div><br></div><div>}</div><div><br></div><div><div>public class SteelWheelsCustomRole extends DelegatingRole {</div>
<div><span class="" style="white-space:pre">        </span>private String territory;</div><div><span class="" style="white-space:pre">        </span>private static String HIERARCHY_NAME = "Markets";</div><div><span class="" style="white-space:pre">        </span></div>
<div><span class="" style="white-space:pre">        </span>public SteelWheelsCustomRole(Role role) {</div><div><span class="" style="white-space:pre">                </span>super(((RoleImpl) role).makeMutableClone());</div><div><span class="" style="white-space:pre">                </span>this.territory = "Japan";</div>
<div><span class="" style="white-space:pre">        </span>}</div><div><span class="" style="white-space:pre">        </span></div><div><span class="" style="white-space:pre">        </span>@Override</div><div><span class="" style="white-space:pre">        </span>public HierarchyAccess getAccessDetails(Hierarchy hierarchy) {</div>
<div><span class="" style="white-space:pre">                </span>HierarchyAccess ha = super.getAccessDetails(hierarchy);</div><div><span class="" style="white-space:pre">                </span>return (ha == null ? null : new CustomHierarchyAccess(ha));</div>
<div><span class="" style="white-space:pre">        </span>}</div><div><span class="" style="white-space:pre">        </span></div><div><span class="" style="white-space:pre">        </span>protected class CustomHierarchyAccess extends RoleImpl.DelegatingHierarchyAccess {</div>
<div><span class="" style="white-space:pre">                </span>protected HierarchyAccess ha;</div><div><span class="" style="white-space:pre">                </span></div><div><span class="" style="white-space:pre">                </span>public CustomHierarchyAccess(HierarchyAccess ha) {</div>
<div><span class="" style="white-space:pre">                        </span>super(ha);</div><div><span class="" style="white-space:pre">                        </span>this.ha = ha;</div><div><span class="" style="white-space:pre">                </span>}</div><div><span class="" style="white-space:pre">        </span></div>
<div><span class="" style="white-space:pre">                </span>@Override</div><div><span class="" style="white-space:pre">                </span>public Access getAccess(Member member) {</div><div><span class="" style="white-space:pre">                        </span>return SteelWheelsCustomRole.this.getAccess(member, ha.getAccess(member));</div>
<div><span class="" style="white-space:pre">                </span>}</div><div><span class="" style="white-space:pre">        </span>}</div><div><span class="" style="white-space:pre">        </span></div><div><span class="" style="white-space:pre">        </span>@Override</div>
<div><span class="" style="white-space:pre">        </span>public Access getAccess(Hierarchy hierarchy) {</div><div><span class="" style="white-space:pre">                </span>return role.getAccess(hierarchy);</div><div><span class="" style="white-space:pre">        </span>}</div>
<div><span class="" style="white-space:pre">        </span></div><div><span class="" style="white-space:pre">        </span>@Override</div><div><span class="" style="white-space:pre">        </span>public Access getAccess(Member member) {</div>
<div><span class="" style="white-space:pre">                </span>return getAccess(member, role.getAccess(member));</div><div><span class="" style="white-space:pre">        </span>}</div><div><span class="" style="white-space:pre">        </span></div>
<div><span class="" style="white-space:pre">        </span>protected Access getAccess(Member member, Access access) {</div><div><span class="" style="white-space:pre">                </span>String memberHierarchyName = member.getHierarchy().getName();</div>
<div><span class="" style="white-space:pre">                </span>if (memberHierarchyName.contains(HIERARCHY_NAME)) {</div><div><span class="" style="white-space:pre">                        </span>if (member.getName().equalsIgnoreCase(this.territory)) {</div>
<div><span class="" style="white-space:pre">                                </span>return Access.ALL;</div><div><span class="" style="white-space:pre">                        </span>}</div><div><span class="" style="white-space:pre">                        </span>for (Member mem : member.getAncestorMembers()) {</div>
<div><span class="" style="white-space:pre">                                </span>if (mem.getName().equalsIgnoreCase(this.territory)) {</div><div><span class="" style="white-space:pre">                                        </span>return Access.ALL;</div><div><span class="" style="white-space:pre">                                </span>}</div>
<div><span class="" style="white-space:pre">                        </span>}</div><div><span class="" style="white-space:pre">                        </span>Access acc = (access == Access.CUSTOM) ? access : Access.NONE;</div><div><span class="" style="white-space:pre">                        </span>return acc;</div>
<div><span class="" style="white-space:pre">                </span>}</div><div><span class="" style="white-space:pre">                </span>return access;</div><div><span class="" style="white-space:pre">        </span>}</div><div><span class="" style="white-space:pre">                </span></div>
<div><span class="" style="white-space:pre">        </span>@Override</div><div><span class="" style="white-space:pre">        </span>public Access getAccess(Level level) {</div><div><span class="" style="white-space:pre">                </span>return role.getAccess(level);</div>
<div><span class="" style="white-space:pre">        </span>}</div><div><span class="" style="white-space:pre">        </span></div><div><span class="" style="white-space:pre">        </span>@Override</div><div><span class="" style="white-space:pre">        </span>public boolean canAccess(OlapElement olapElement) {</div>
<div><span class="" style="white-space:pre">                </span>return true;</div><div><span class="" style="white-space:pre">                </span></div><div><span class="" style="white-space:pre">        </span>}</div><div>}</div></div><div><br></div>
<div style>3. The code executes without errors but Joe still sees EMEA only when I create a new analysis view.</div><div style><br></div><div style>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?</div>
<div style><br></div><div style>Thank you for your answers.</div><div style>Xavier Gumara</div></div></div>