Skip to content

Commit

Permalink
feature/IVYPORTAL-18050-Create-cache-mechanism-for-dashboard-converte…
Browse files Browse the repository at this point in the history
…r-to-enhance-performance

_ refactor dashboard utils
_ remove unuse code
_ unify collect dashboards data into collect public and private
_ remove old cache
_ apdat new cache for getPublic and getPrivate dashboard
  • Loading branch information
nhthinh-axonivy committed Dec 11, 2024
1 parent 588bc96 commit 2a47f34
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ private MenuElement buildDashboardItem() {
String mainMenuDisplayName = mainMenuEntryService.getNameInCurrentLocale();
String mainMenuIcon = mainMenuEntryService.getMenuIcon();

var subItemDashboards = getSubItemDashboards();
List<Dashboard> subItemDashboards = getSubItemDashboards();
if (subItemDashboards.size() > 1) {
return buildDashboardGroupMenu(subItemDashboards, dashboardTitle, mainMenuDisplayName, mainMenuIcon,
currentLanguage, dashboardLink);
Expand All @@ -173,8 +173,8 @@ private String determineDashboardLink() {
}

private List<Dashboard> getSubItemDashboards() {
var dashboards = getDashboardCache().dashboards;
return dashboards.stream().filter(dashboard -> !dashboard.getIsTopMenu()).toList();
List<Dashboard> dashboards = DashboardUtils.getDashboardsWithoutMenuItem();
return dashboards;
}

private MenuElement buildDashboardGroupMenu(List<Dashboard> subItemDashboards, String defaultTitle,
Expand Down Expand Up @@ -252,37 +252,13 @@ private MenuElement buildSingleDashboardMenu(String dashboardTitle, String dashb
return dashboardMenu;
}


public PortalDashboardItemWrapper getDashboardCache() {
String sessionUserId = getSessionUserId();
IvyCacheService cacheService = IvyCacheService.getInstance();
PortalDashboardItemWrapper portalDashboardItemWrapper = null;
try {
portalDashboardItemWrapper = getPortalDashboardItemWrapper(sessionUserId, cacheService);
} catch (ClassCastException e) {
cacheService.invalidateSessionEntry(IvyCacheIdentifier.PORTAL_MENU, sessionUserId);
}

if (portalDashboardItemWrapper == null) {
synchronized(PortalDashboardItemWrapper.class) {
portalDashboardItemWrapper = new PortalDashboardItemWrapper(DashboardUtils.collectDashboards());
cacheService.setSessionCache(IvyCacheIdentifier.PORTAL_DASHBOARDS, sessionUserId, portalDashboardItemWrapper);
}
}
return portalDashboardItemWrapper;
}

public void updateDashboardCache(List<Dashboard> dashboards) {
String sessionUserId = getSessionUserId();
IvyCacheService cacheService = IvyCacheService.getInstance();

synchronized (PortalDashboardItemWrapper.class) {
cacheService.setSessionCache(IvyCacheIdentifier.PORTAL_DASHBOARDS, sessionUserId,
new PortalDashboardItemWrapper(dashboards));
}
cacheService.invalidateSessionEntry(IvyCacheIdentifier.PORTAL_PUBLIC_DASHBOARD, sessionUserId);
cacheService.invalidateSessionEntry(IvyCacheIdentifier.PORTAL_PRIVATE_DASHBOARD, sessionUserId);

cacheService.invalidateSessionEntry(IvyCacheIdentifier.PORTAL_MENU, sessionUserId);
cacheService.invalidateSessionEntry(IvyCacheIdentifier.PORTAL_DASHBOARD_CONVERTER_DATA, sessionUserId);
}

private String getSessionUserId() {
Expand All @@ -293,10 +269,6 @@ private String getSessionUserId() {
return (String) session().getAttribute(sessionIdAttribute);
}

private PortalDashboardItemWrapper getPortalDashboardItemWrapper(String sessionUserId, IvyCacheService cacheService) {
return (PortalDashboardItemWrapper) cacheService.getSessionCacheValue(IvyCacheIdentifier.PORTAL_DASHBOARDS, sessionUserId).orElse(null);
}

public String getDashboardLink() {
return PortalNavigator.getDashboardLink();
}
Expand Down Expand Up @@ -519,9 +491,6 @@ private IWorkflowSession session() {
return Ivy.session();
}

public record PortalDashboardItemWrapper(List<Dashboard> dashboards) {
}

private void buildBreadCrumbForNotification() {
setPortalHomeMenuToBreadcrumbModel();
breadcrumbModel.getElements().add(buildGenericMenuItem("/ch.ivy.addon.portalkit.ui.jsf/notifications/notificationTitle"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.faces.context.FacesContext;
Expand Down Expand Up @@ -107,8 +106,8 @@ public static List<Application> getThirdPartyApps() {
}

public static List<SubMenuItem> callSubMenuItemsProcess() {

subMenuItems = getSubmenuList();
List<SubMenuItem> subMenuItems = new ArrayList<>();
subMenuItems = getSubmenuList();
return subMenuItems;
}

Expand All @@ -126,9 +125,6 @@ public static void navigateToTargetPage(boolean isClickOnBreadcrumb, String dest
navigateToTargetPage(params);
}

private record PortalSubMenuItemWrapper(Locale loadedLocale, List<SubMenuItem> portalSubMenuItems) {
}

private static List<SubMenuItem> getSubmenuList() {
String currentLanguage = UserUtils.getUserLanguage();
List<SubMenuItem> subMenuItems = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import com.axonivy.portal.dto.dashboard.filter.DashboardFilter;
import com.axonivy.portal.service.DeepLTranslationService;

import ch.addon.portal.generic.menu.MenuView;
import ch.ivy.addon.portal.generic.navigation.PortalNavigator;
import ch.ivy.addon.portalkit.constant.PortalConstants;
import ch.ivy.addon.portalkit.dto.DisplayName;
Expand All @@ -44,7 +43,6 @@
import ch.ivy.addon.portalkit.enums.TaskEmptyMessage;
import ch.ivy.addon.portalkit.exporter.Exporter;
import ch.ivy.addon.portalkit.ivydata.service.impl.LanguageService;
import ch.ivy.addon.portalkit.jsf.ManagedBeans;
import ch.ivy.addon.portalkit.service.GlobalSettingService;
import ch.ivy.addon.portalkit.service.WidgetFilterService;
import ch.ivy.addon.portalkit.support.HtmlParser;
Expand Down Expand Up @@ -89,12 +87,6 @@ public void init() {
currentDashboardIndex = 0;
dashboards = collectDashboards();


if (isReadOnlyMode) {
MenuView menuView = (MenuView) ManagedBeans.get("menuView");
menuView.updateDashboardCache(dashboards);
}

if (CollectionUtils.isNotEmpty(DashboardUtils.getDashboardsWithoutMenuItem())) {
updateSelectedDashboardIdFromSessionAttribute();
currentDashboardIndex = findIndexOfDashboardById(selectedDashboardId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@ public final class IvyCacheIdentifier {
public static final String ROLES_IN_SECURITY_CONTEXT = "ROLES_IN_SECURITY_CONTEXT";
public static final String PORTAL_MENU = "PORTAL_MENU";
public static final String PORTAL_CUSTOM_MENU = "PORTAL_CUSTOM_MENU";
public static final String PORTAL_DASHBOARDS = "PORTAL_DASHBOARDS";
public static final String PORTAL_DASHBOARDS_MENU_ITEM = "PORTAL_DASHBOARDS_MENU_ITEM";
public static final String PORTAL_DASHBOARD_CONVERTER_DATA = "PORTAL_DASHBOARD_CONVERTER_DATA";

public static final String PORTAL_PUBLIC_DASHBOARD = "PORTAL_PUBLIC_DASHBOARD";
public static final String PORTAL_PRIVATE_DASHBOARD = "PORTAL_PRIVATE_DASHBOARD";
// for caching locales
public static final String PORTAL_CONTENT_LOCALES = "PORTAL_CONTENT_LOCALES";
public static final String PORTAL_FORMATTING_LOCALES = "PORTAL_FORMATTING_LOCALES";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ public void setTemplateId(String templateId) {
}

public Boolean getIsTopMenu() {
return isTopMenu;
return isTopMenu != null ? isTopMenu : false;
}

public void setIsTopMenu(Boolean isTopMenu) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import java.util.function.Consumer;
Expand All @@ -21,12 +22,14 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import ch.ivy.addon.portalkit.constant.IvyCacheIdentifier;
import ch.ivy.addon.portalkit.dto.dashboard.Dashboard;
import ch.ivy.addon.portalkit.dto.dashboard.DashboardOrder;
import ch.ivy.addon.portalkit.dto.dashboard.DashboardTemplate;
import ch.ivy.addon.portalkit.enums.PortalVariable;
import ch.ivy.addon.portalkit.enums.SessionAttribute;
import ch.ivy.addon.portalkit.persistence.converter.BusinessEntityConverter;
import ch.ivy.addon.portalkit.service.IvyCacheService;
import ch.ivyteam.ivy.environment.Ivy;
import ch.ivyteam.ivy.security.ISecurityConstants;
import ch.ivyteam.ivy.security.IUser;
Expand All @@ -49,17 +52,72 @@ public class DashboardUtils {
public final static String DEFAULT_CASE_LIST_DASHBOARD = "default-case-list-dashboard";

public static List<Dashboard> getPublicDashboards() {
String dashboardJson = Ivy.var().get(PortalVariable.DASHBOARD.key);
List<Dashboard> dashboards = jsonToDashboards(dashboardJson);
addDefaultTaskCaseListDashboardsIfMissing(dashboards);
setDashboardAsPublic(dashboards);
return dashboards;
Locale requestLocale = Ivy.session().getContentLocale();
String sessionIdAttribute = SessionAttribute.SESSION_IDENTIFIER.toString();
if (Ivy.session().getAttribute(sessionIdAttribute) == null) {
Ivy.session().setAttribute(sessionIdAttribute, UUID.randomUUID().toString());
}
String sessionUserId = (String) Ivy.session().getAttribute(sessionIdAttribute);
IvyCacheService cacheService = IvyCacheService.getInstance();
PortalPublicDashboardWrapper portalPublicDashboardWrapper = null;
try {
portalPublicDashboardWrapper = (PortalPublicDashboardWrapper) cacheService
.getSessionCacheValue(IvyCacheIdentifier.PORTAL_PUBLIC_DASHBOARD, sessionUserId).orElse(null);
} catch (ClassCastException e) {
cacheService.invalidateSessionEntry(IvyCacheIdentifier.PORTAL_PUBLIC_DASHBOARD, sessionUserId);
}

if (portalPublicDashboardWrapper == null || !requestLocale.equals(portalPublicDashboardWrapper.loadedLocale)) {
synchronized (PortalPublicDashboardWrapper.class) {
List<Dashboard> dashboards = new ArrayList<>();
try {
String dashboardJson = Ivy.var().get(PortalVariable.DASHBOARD.key);
dashboards = jsonToDashboards(dashboardJson);
ensureDefaultIsTopMenu(dashboards);
addDefaultTaskCaseListDashboardsIfMissing(dashboards);
setDashboardAsPublic(dashboards);
} catch (Exception e) {
Ivy.log().error("Cannot load Public Dashboards {0}", e.getMessage());
}
portalPublicDashboardWrapper = new PortalPublicDashboardWrapper(requestLocale, dashboards);
cacheService.setSessionCache(IvyCacheIdentifier.PORTAL_PUBLIC_DASHBOARD, sessionUserId,
portalPublicDashboardWrapper);
}
}
return portalPublicDashboardWrapper.dashboards();
}

public static List<Dashboard> getPrivateDashboards() {
String dashboardInUserProperty = readDashboardBySessionUser();
List<Dashboard> dashboards = jsonToDashboards(dashboardInUserProperty);
return dashboards;
Locale requestLocale = Ivy.session().getContentLocale();
String sessionIdAttribute = SessionAttribute.SESSION_IDENTIFIER.toString();
if (Ivy.session().getAttribute(sessionIdAttribute) == null) {
Ivy.session().setAttribute(sessionIdAttribute, UUID.randomUUID().toString());
}
String sessionUserId = (String) Ivy.session().getAttribute(sessionIdAttribute);
IvyCacheService cacheService = IvyCacheService.getInstance();
PortalPrivateDashboardWrapper portalPrivateDashboardWrapper = null;
try {
portalPrivateDashboardWrapper = (PortalPrivateDashboardWrapper) cacheService
.getSessionCacheValue(IvyCacheIdentifier.PORTAL_PRIVATE_DASHBOARD, sessionUserId).orElse(null);
} catch (ClassCastException e) {
cacheService.invalidateSessionEntry(IvyCacheIdentifier.PORTAL_PRIVATE_DASHBOARD, sessionUserId);
}

if (portalPrivateDashboardWrapper == null || !requestLocale.equals(portalPrivateDashboardWrapper.loadedLocale)) {
synchronized (PortalPublicDashboardWrapper.class) {
List<Dashboard> dashboards = new ArrayList<>();
try {
String dashboardInUserProperty = readDashboardBySessionUser();
dashboards = jsonToDashboards(dashboardInUserProperty);
} catch (Exception e) {
Ivy.log().error("Cannot load Public Dashboards {0}", e.getMessage());
}
portalPrivateDashboardWrapper = new PortalPrivateDashboardWrapper(requestLocale, dashboards);
cacheService.setSessionCache(IvyCacheIdentifier.PORTAL_PRIVATE_DASHBOARD, sessionUserId,
portalPrivateDashboardWrapper);
}
}
return portalPrivateDashboardWrapper.dashboards();
}

public static List<Dashboard> getVisibleDashboards(boolean isPublic) {
Expand All @@ -81,7 +139,7 @@ public static List<Dashboard> collectDashboards() {
Dashboard currentDashboard = idToDashboard.remove(dashboardOrder.getDashboardId());
if (dashboardOrder.isVisible() && currentDashboard != null) {
collectedDashboards.add(currentDashboard);
}
}
}
collectedDashboards.addAll(idToDashboard.values());
addDefaultTaskCaseListDashboardsIfMissing(collectedDashboards);
Expand All @@ -102,7 +160,7 @@ public static void highlightDashboardMenuItem(String selectedDashboardId) {

private static List<Dashboard> jsonToDashboards(String dashboardJson) {
if (StringUtils.isBlank(dashboardJson)) {
return new ArrayList<>();
return new ArrayList<>();
}
try {
ObjectMapper mapper = new ObjectMapper();
Expand All @@ -122,7 +180,7 @@ private static Consumer<Dashboard> initDefaultPermission() {
ArrayList<String> defaultPermissions = new ArrayList<>();
defaultPermissions.add(ISecurityConstants.TOP_LEVEL_ROLE_NAME);
dashboard.setPermissions(defaultPermissions);
}
}
};
}

Expand Down Expand Up @@ -191,26 +249,21 @@ public static void updateSelectedDashboardToSession(String selectedMenuItemId) {
}

public static void storeDashboardInSession(String dashboardId) {
Ivy.log().error("ADADA1" + dashboardId);
boolean isMain = isMainDashboard(dashboardId, true);
boolean isMain = isMainDashboard(dashboardId, false);
storeDashboardInSession(dashboardId, isMain);
}

public static void storeDashboardInSession(String dashboardId, boolean isMainDashboard) {
Ivy.session().setAttribute(SessionAttribute.SELECTED_DASHBOARD_ID.toString(), dashboardId);

if (!isMainDashboard) {

Ivy.session().setAttribute(SessionAttribute.SELECTED_SUB_DASHBOARD_ID.toString(), dashboardId);
}
}

public static boolean isMainDashboard(String dashboardId, boolean defaultValue) {
if (StringUtils.isEmpty(dashboardId)) {

return false;
}

return collectMainDashboards().stream().filter(dashboard -> dashboardId.equals(dashboard.getId()))
.map(Dashboard::getIsTopMenu).findFirst().orElse(defaultValue);
}
Expand Down Expand Up @@ -263,4 +316,20 @@ public static void updatePropertiesToNullIfCurrentValueIsDefaultValue(List<Dashb
}
}
}

private static void ensureDefaultIsTopMenu(List<Dashboard> dashboards) {
if (dashboards != null) {
dashboards.forEach(dashboard -> {
if (dashboard.getIsTopMenu() == null) {
dashboard.setIsTopMenu(false);
}
});
}
}

private record PortalPrivateDashboardWrapper(Locale loadedLocale, List<Dashboard> dashboards) {
}
private record PortalPublicDashboardWrapper(Locale loadedLocale, List<Dashboard> dashboards) {
}

}

0 comments on commit 2a47f34

Please sign in to comment.