WCI Community Cache-building woes: Give Everyone access to your headers

A year ago (wow – time flies!) I promised to elaborate on some other causes of the “Error displaying Dropdown menu tabs” error in WebCenter Interaction headers (which didn’t seem to affect the Plumtree or ALUI versions that predated it).

Well, it’s time to do some more ‘splaining: In most cases I’ve seen, this has to do with the fact that the current user (guest or authenticated) doesn’t have at least SELECT access to the header portlet.  So, if you’re just looking for the executive summary of this post, the first thing to check is whether EVERYONE has at least SELECT access to the header portlet.

Ms. Cooper (my made-up 8th grade algebra teacher) always told me: “Show your work“.  Hell, even if I got the right answer the old bag would still dock me points if I didn’t.  [Before you get offended, note that I can say that because Ms. Cooper is a figment of my imagination – I have great respect for the entire teaching profession and especially every teacher I’ve ever had that wasn’t made up.  I would never refer to any of them as an “old bag”.]

So, let’s show the work:

In PTSpy, you can see the exception showing up when this condition happens and you see the “Error displaying Dropdown menu tabs” error:

at com.plumtree.server.impl.community. PTCommunityInfo.GetSecuredCommunityInfoCacheObj() in e:\buildroot\Release\portalserver\6.5.x\ portalobjects\build\x86\ src\dotnet\com\plumtree\ server\impl\community\ PTCommunityInfo.cs:line 776

The code (further down the stack trace) checks the cache and loads it “insecurely” (that is, security’s not checked at this point; they’re just loading the object in to the cache):

at com.plumtree.server.impl.core. PlumtreeObjectCache.FindOrCreateObjectInsecure (Int32 iObjectID, InternalSession internalsession) in e:\buildroot\Release\ portalserver\6.5.x\portalobjects\build\x86\ src\dotnet\com\plumtree\ server\impl\core\PlumtreeObjectCache.cs:line 178

If it doesn’t find the object – the community – in the cache, it creates it:

at com.plumtree.server.impl.community. CommunityInfoCache.InternalCreateObject (Int32 nObjectID, InternalSession internalsession) in e:\buildroot\Release\ portalserver\6.5.x\portalobjects\build\x86\ src\dotnet\com\plumtree\ server\impl\community\CommunityInfoCache.cs:line 71

As part of the community cache creation process, the style sheet for the community is also cached – from the decompiled code:

this.CacheCommunityPrefs(internalsession);
this.CacheStyleSheet(internalsession);
this.CachePages(ptComm.GetAdminFolderID(), internalsession);
this.CacheParentPeersAndSubcommunities(internalsession);

The bombing piece of code is in that CacheStyleSheet method:

private void CacheStyleSheet(InternalSession ptIS)
{
this.m_strStyleSheet = "";
if (this.m_nHeaderID > 0)
{
try
{
int nMaxAgeSecs = ((int) (XPSystem.GetCurrentTimeMilliSec() / 0x3e8L)) - GlobalSysInfo.g_dtEndUserObjectCacheTimeoutSeconds;
GadgetCacheEntry entry = (GadgetCacheEntry) GadgetCache.CACHE_INSTANCE.FindOrCreateEntryNewerThan(this.m_nHeaderID, ptIS, nMaxAgeSecs);
IPTAdminSettings ptGadget = (IPTAdminSettings) entry.GetGadget();
if (null != ptGadget)
{

From the FindOrCreateEntryNewerThan method, you can see that sometimes the gadget cache has the header already, and sometimes it has to create it (just like the community cache).

Typically, in PTSpy, immediately preceding the ERROR we see a WARNING:

*** PTBase.ThrowException *** (-2147024891) Current User does not have sufficient permission to object with id = 17264

So, if you’ve been following closely, not only will you notice that the current user needs privileges to access the header (and, by extension, the CSS cache), but the error could be intermittent – because the cache is built based on the currently logged in user. So:

  1. If the gadget is already in the cache, then the header always works because the cache entry didn’t have to be created.
  2. If the gadget is NOT in the cache, then it would depend on WHICH USER was accessing the community. If it is a user without access, then the header load would fail and consequently the style sheet couldn’t be loaded, which causes the exception to bubble all the way back up to kill the nav bar. But if the user has access, the object DOES get created in the cache, where it would stay for as long as the cache kept it around.

In other words, the CACHE is created by whatever user is accessing the community. But, if that user doesn’t have access to the HEADER portlet (and CSS object), then the code chokes.

Tags: , ,

Leave a Reply