Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

invalidate menu cache if the permissions version does not matter #385

Merged
merged 1 commit into from
May 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions src/main/java/de/metas/ui/web/menu/MenuTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,25 @@

public final class MenuTree
{
public static final MenuTree of(final MenuNode rootNode)
public static final MenuTree of(final long version, final MenuNode rootNode)
{
return new MenuTree(rootNode);
return new MenuTree(version, rootNode);
}

private static final Logger logger = LogManager.getLogger(MenuTree.class);

private final long version;

private final MenuNode rootNode;
private final Map<String, MenuNode> nodesById;

private final ListMultimap<ArrayKey, MenuNode> nodesByTypeAndElementId;
private final ListMultimap<String, MenuNode> nodesByMainTableName;

private MenuTree(final MenuNode rootNode)
private MenuTree(final long version, final MenuNode rootNode)
{
super();
this.version = version;
Preconditions.checkNotNull(rootNode, "rootNode");
this.rootNode = rootNode;

Expand Down Expand Up @@ -94,8 +97,14 @@ public String toString()
{
return MoreObjects.toStringHelper(this)
.add("rootNode", rootNode)
.add("version", version)
.toString();
}

public long getVersion()
{
return version;
}

public MenuNode getRootNode()
{
Expand Down
42 changes: 23 additions & 19 deletions src/main/java/de/metas/ui/web/menu/MenuTreeLoader.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package de.metas.ui.web.menu;

import java.util.Enumeration;
import java.util.Properties;

import org.adempiere.ad.security.IUserRolePermissions;
import org.adempiere.ad.security.IUserRolePermissionsDAO;
Expand All @@ -13,13 +12,13 @@
import org.compiere.model.MTree;
import org.compiere.model.MTreeNode;
import org.compiere.model.X_AD_Menu;
import org.compiere.util.Env;
import org.slf4j.Logger;

import com.google.common.base.Preconditions;

import de.metas.logging.LogManager;
import de.metas.ui.web.menu.MenuNode.MenuNodeType;
import de.metas.ui.web.process.ProcessId;
import lombok.NonNull;

/*
* #%L
Expand All @@ -43,7 +42,7 @@
* #L%
*/

public final class MenuTreeLoader
final class MenuTreeLoader
{
/* package */static MenuTreeLoader newInstance()
{
Expand All @@ -57,39 +56,33 @@ public final class MenuTreeLoader
private static final int DEPTH_Root = 0;
private static final int DEPTH_RootChildren = 1;

private Properties _ctx;
private UserRolePermissionsKey _userRolePermissionsKey;
private IUserRolePermissions _userRolePermissions; // lazy
private String _adLanguage;
private long _version = -1;

private MenuTreeLoader()
{
super();
}

public MenuTreeLoader setCtx(final Properties ctx)
public MenuTreeLoader setUserRolePermissionsKey(final UserRolePermissionsKey userRolePermissionsKey)
{
_ctx = ctx;
_userRolePermissionsKey = userRolePermissionsKey;
return this;
}

private Properties getCtx()
{
Preconditions.checkNotNull(_ctx, "ctx");
return _ctx;
}

public MenuTreeLoader setUserRolePermissionsKey(final UserRolePermissionsKey userRolePermissionsKey)
@NonNull
private UserRolePermissionsKey getUserRolePermissionsKey()
{
_userRolePermissionsKey = userRolePermissionsKey;
return this;
return _userRolePermissionsKey;
}

private IUserRolePermissions getUserRolePermissions()
{
if (_userRolePermissions == null)
{
final UserRolePermissionsKey userRolePermissionsKey = _userRolePermissionsKey != null ? _userRolePermissionsKey : UserRolePermissionsKey.of(getCtx());
final UserRolePermissionsKey userRolePermissionsKey = getUserRolePermissionsKey();
_userRolePermissions = userRolePermissionsDAO.retrieveUserRolePermissions(userRolePermissionsKey);
}
return _userRolePermissions;
Expand All @@ -109,7 +102,8 @@ public MenuTree load()
throw new IllegalStateException("No root menu node available"); // shall not happen
}

return MenuTree.of(rootNode);
final long version = getVersion();
return MenuTree.of(version, rootNode);
}

private MenuNode createMenuNodeRecursivelly(final MTreeNode nodeModel, final int depth)
Expand Down Expand Up @@ -237,7 +231,7 @@ private MTreeNode retrieveRootNodeModel()
}

final MTree mTree = MTree.builder()
.setCtx(getCtx())
.setCtx(Env.getCtx())
.setTrxName(ITrx.TRXNAME_None)
.setAD_Tree_ID(adTreeId)
.setEditable(false)
Expand Down Expand Up @@ -265,8 +259,18 @@ public MenuTreeLoader setAD_Language(String adLanguage)
return this;
}

@NonNull
private String getAD_Language()
{
return _adLanguage;
}

private long getVersion()
{
if (_version < 0)
{
_version = userRolePermissionsDAO.getCacheVersion();
}
return _version;
}
}
32 changes: 29 additions & 3 deletions src/main/java/de/metas/ui/web/menu/MenuTreeRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import org.adempiere.ad.security.IUserRolePermissionsDAO;
import org.adempiere.ad.security.UserRolePermissionsKey;
import org.adempiere.exceptions.AdempiereException;
import org.compiere.util.Env;
import org.adempiere.util.Services;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

Expand All @@ -15,6 +17,7 @@
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

import de.metas.logging.LogManager;
import de.metas.ui.web.session.UserSession;

/*
Expand Down Expand Up @@ -42,6 +45,8 @@
@Repository
public class MenuTreeRepository
{
private static final transient Logger logger = LogManager.getLogger(MenuTreeRepository.class);

@Autowired
private UserSession userSession;

Expand All @@ -54,7 +59,6 @@ public class MenuTreeRepository
public MenuTree load(final MenuTreeKey key) throws Exception
{
return MenuTreeLoader.newInstance()
.setCtx(Env.getCtx())
.setUserRolePermissionsKey(key.getUserRolePermissionsKey())
.setAD_Language(key.getAD_Language())
.load();
Expand All @@ -73,7 +77,29 @@ public MenuTree getMenuTree(final UserRolePermissionsKey userRolePermissionsKey,
try
{
final MenuTreeKey key = new MenuTreeKey(userRolePermissionsKey, adLanguage);
return menuTrees.get(key);
MenuTree menuTree = menuTrees.get(key);

//
// If menuTree's version is not the current one, try re-acquiring it.
int retry = 3;
final long currentVersion = Services.get(IUserRolePermissionsDAO.class).getCacheVersion();
while (menuTree.getVersion() != currentVersion)
{
menuTrees.invalidate(key);
menuTree = menuTrees.get(key);

retry--;
if (retry <= 0)
{
break;
}
}
if (menuTree.getVersion() != currentVersion)
{
logger.warn("Could not acquire menu tree version {}. Returning what we got... \nmenuTree: {}\nkey={}", currentVersion, menuTree, key);
}

return menuTree;
}
catch (final ExecutionException e)
{
Expand Down