Author: taylor
Date: Tue May 26 01:20:23 2015
New Revision: 1681669
URL: http://svn.apache.org/r1681669
Log:
JS2-1325: initial implementation (read, write) of preferences caching
performance improvements
Added:
portals/jetspeed-2/portal/trunk/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/UserSessionPreferences.java
Modified:
portals/jetspeed-2/portal/trunk/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/PortletPreferencesServiceImpl.java
Modified:
portals/jetspeed-2/portal/trunk/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/PortletPreferencesServiceImpl.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/PortletPreferencesServiceImpl.java?rev=1681669&r1=1681668&r2=1681669&view=diff
==============================================================================
---
portals/jetspeed-2/portal/trunk/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/PortletPreferencesServiceImpl.java
(original)
+++
portals/jetspeed-2/portal/trunk/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/PortletPreferencesServiceImpl.java
Tue May 26 01:20:23 2015
@@ -16,7 +16,10 @@
*/
package org.apache.jetspeed.components.portletpreferences;
+import org.apache.jetspeed.Jetspeed;
import org.apache.jetspeed.JetspeedActions;
+import org.apache.jetspeed.administration.PortalConfiguration;
+import org.apache.jetspeed.administration.PortalConfigurationConstants;
import org.apache.jetspeed.cache.CacheElement;
import org.apache.jetspeed.cache.JetspeedCache;
import org.apache.jetspeed.container.PortletWindow;
@@ -26,6 +29,8 @@ import org.apache.jetspeed.om.portlet.Po
import org.apache.jetspeed.om.portlet.Preference;
import org.apache.jetspeed.om.portlet.Preferences;
import org.apache.jetspeed.om.preference.FragmentPreference;
+import org.apache.jetspeed.request.RequestContext;
+import org.apache.jetspeed.request.RequestContextComponent;
import org.apache.jetspeed.security.SubjectHelper;
import org.apache.jetspeed.security.User;
import org.apache.ojb.broker.query.Criteria;
@@ -62,6 +67,7 @@ import java.util.TreeSet;
public class PortletPreferencesServiceImpl extends PersistenceBrokerDaoSupport
implements PortletPreferencesProvider
{
+ protected static final String SESSION_CACHE_KEY =
"portlet.preferences.user.key";
protected static final String DISCRIMINATOR_PORTLET = "portlet";
protected static final String DISCRIMINATOR_ENTITY = "entity";
protected static final String DISCRIMINATOR_USER = "user";
@@ -74,6 +80,8 @@ public class PortletPreferencesServiceIm
protected static final String USER_NAME = "userName";
private PortletFactory portletFactory;
+ protected RequestContextComponent requestContextComponent;
+ protected PortalConfiguration configuration;
/**
* Cache elements are stored as element type JetspeedPreferencesMap
@@ -82,8 +90,13 @@ public class PortletPreferencesServiceIm
private List<String> preloadedApplications = null;
private boolean preloadEntities = false;
private boolean useEntityPreferences = true;
+ // JS2-1325: performance optimization to improve preference retrieval speed
+ // To go back to old behavior, set jetspeed/override.properties.
+ // Default is enabled
+ // preferences.session.cache.enabled = true
+ // since 2.3.0
+ private boolean enableSessionCache = true;
-
public boolean isUseEntityPreferences()
{
return useEntityPreferences;
@@ -101,7 +114,7 @@ public class PortletPreferencesServiceIm
this.portletFactory = portletFactory;
this.preferenceCache = preferenceCache;
}
-
+
public PortletPreferencesServiceImpl(PortletFactory portletFactory,
JetspeedCache preferenceCache, List<String> apps, boolean preloadEntities)
throws ClassNotFoundException
{
@@ -109,9 +122,21 @@ public class PortletPreferencesServiceIm
this.preloadedApplications = apps;
this.preloadEntities = preloadEntities;
}
-
+
public void init()
{
+ try {
+ configuration =
Jetspeed.getComponentManager().lookupComponent("PortalConfiguration");
+ }
+ catch (Exception e) {
+ configuration = null; // not set in some unit tests
+ }
+ if (configuration != null) {
+ enableSessionCache =
configuration.getBoolean(PortalConfigurationConstants.ENABLED_PREFERENCES_SESSION_CACHE);
+ }
+ else {
+ enableSessionCache = false;
+ }
}
public void destroy()
@@ -179,7 +204,10 @@ public class PortletPreferencesServiceIm
{
userName =
SubjectHelper.getPrincipal(window.getRequestContext().getSubject(),
User.class).getName();
}
- return retrieveUserPreferences(window, userName);
+ // JS2-1325: since 2.3.0
+ return (enableSessionCache) ?
+ retrieveUserSessionWindowPreferences(window, userName) :
+ retrieveUserPreferences(window, userName);
}
/**
@@ -353,10 +381,18 @@ public class PortletPreferencesServiceIm
}
}
getPersistenceBrokerTemplate().store(dbPref);
- }
- // remove from cache to send distributed notification
- String cacheKey = getUserPreferenceKey(appName, portletName,
entityId, userName);
- preferenceCache.remove(cacheKey);
+ }
+ if (enableSessionCache) {
+ UserSessionPreferences sessionPreferences =
getUserSessionPreferences();
+ if (sessionPreferences != null) {
+
sessionPreferences.updateWindowPreferences(window.getPortletEntityId(), map);
+ }
+ }
+ else {
+ // remove from cache to send distributed notification
+ String cacheKey = getUserPreferenceKey(appName, portletName,
entityId, userName);
+ preferenceCache.remove(cacheKey);
+ }
}
catch (Throwable t)
{
@@ -882,4 +918,74 @@ public class PortletPreferencesServiceIm
preferenceCache.remove(cacheKey);
}
+ protected UserSessionPreferences retrieveUserSessionPreferences(String
userName) {
+ RequestContext rc = null;
+ RequestContextComponent rcc = getRequestContextComponent();
+ if (rcc != null) {
+ rc = rcc.getRequestContext();
+ if (rc != null) {
+ UserSessionPreferences userPreferences =
(UserSessionPreferences) rc.getSessionAttribute(SESSION_CACHE_KEY);
+ if (userPreferences != null) {
+ // return cached values
+ return userPreferences;
+ }
+ }
+ }
+ UserSessionPreferences sessionPreferences = new
UserSessionPreferences();
+ // not found in cache, query database
+ Criteria c = new Criteria();
+ c.addEqualTo(DTYPE, DISCRIMINATOR_USER);
+ c.addEqualTo(USER_NAME, userName);
+ //query.addOrderByAscending(DTYPE);
+ QueryByCriteria query =
QueryFactory.newQuery(DatabasePreference.class, c);
+ Iterator<DatabasePreference> preferences =
getPersistenceBrokerTemplate().getIteratorByQuery(query);
+ while (preferences.hasNext())
+ {
+ DatabasePreference preference = preferences.next();
+ Map<String,PortletPreference> windowPreferences =
sessionPreferences.getWindowPreferences(preference.getEntityId());
+ if (windowPreferences == null) {
+ windowPreferences =
sessionPreferences.createWindowPreferences(preference.getEntityId());
+ }
+ windowPreferences.put(preference.getName(), new
JetspeedPreferenceImpl(preference.getName(), preference.getValues(),
preference.isReadOnly()));
+ }
+ if (rc != null) {
+ rc.setSessionAttribute(SESSION_CACHE_KEY, sessionPreferences);
+ }
+ return sessionPreferences;
+ }
+
+ protected Map<String,PortletPreference>
retrieveUserSessionWindowPreferences(PortletWindow window, String userName)
+ {
+ UserSessionPreferences sessionPreferences =
retrieveUserSessionPreferences(userName);
+ Map<String,PortletPreference> result =
sessionPreferences.getWindowPreferences(window.getPortletEntityId());
+ if (result == null) {
+ result =
sessionPreferences.createWindowPreferences(window.getPortletEntityId());
+ }
+ return result;
+ }
+
+ protected UserSessionPreferences getUserSessionPreferences() {
+ UserSessionPreferences sessionPreferences = null;
+ RequestContextComponent rcc = getRequestContextComponent();
+ if (rcc != null) {
+ RequestContext rc = rcc.getRequestContext();
+ if (rc != null) {
+ sessionPreferences = (UserSessionPreferences)
rc.getSessionAttribute(SESSION_CACHE_KEY);
+ if (sessionPreferences == null) {
+ sessionPreferences = new UserSessionPreferences();
+ rc.setSessionAttribute(SESSION_CACHE_KEY,
sessionPreferences);
+ }
+ return sessionPreferences;
+ }
+ }
+ return new UserSessionPreferences();
+ }
+
+ protected RequestContextComponent getRequestContextComponent() {
+ if (requestContextComponent == null) {
+ requestContextComponent =
Jetspeed.getComponentManager().lookupComponent("org.apache.jetspeed.request.RequestContextComponent");
+ }
+ return requestContextComponent;
+ }
+
}
Added:
portals/jetspeed-2/portal/trunk/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/UserSessionPreferences.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/UserSessionPreferences.java?rev=1681669&view=auto
==============================================================================
---
portals/jetspeed-2/portal/trunk/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/UserSessionPreferences.java
(added)
+++
portals/jetspeed-2/portal/trunk/components/jetspeed-registry/src/main/java/org/apache/jetspeed/components/portletpreferences/UserSessionPreferences.java
Tue May 26 01:20:23 2015
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.components.portletpreferences;
+
+import org.apache.pluto.container.PortletPreference;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Created by dtaylor on 5/25/15.
+ */
+public class UserSessionPreferences {
+
+ /**
+ * Portlet container requests preferences by window id. Portlet windows
can hold 0..n preferences.
+ * This map is keyed on window id an associated to the user by putting it
in the user session.
+ * Individual preferences are keyed by preference name each mapping to a
portlet preference
+ */
+ private Map<String,Map<String,PortletPreference>> windowPreferences = new
ConcurrentHashMap<>();
+
+ public Map<String,PortletPreference> getWindowPreferences(String
portletWindowId) {
+ return windowPreferences.get(portletWindowId);
+ }
+
+ public Map<String,PortletPreference> createWindowPreferences(String
portletWindowId) {
+ Map<String,PortletPreference> preferences = new HashMap<>();
+ windowPreferences.put(portletWindowId, preferences);
+ return preferences;
+ }
+
+ public Map<String,PortletPreference> updateWindowPreferences(String
portletWindowId, Map<String,PortletPreference> preferences) {
+ windowPreferences.put(portletWindowId, preferences);
+ return preferences;
+ }
+
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]