You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by rw...@apache.org on 2009/05/06 09:35:46 UTC
svn commit: r772087 -
/portals/jetspeed-2/portal/trunk/components/jetspeed-profiler/src/main/java/org/apache/jetspeed/profiler/impl/JetspeedProfilerImpl.java
Author: rwatler
Date: Wed May 6 07:35:45 2009
New Revision: 772087
URL: http://svn.apache.org/viewvc?rev=772087&view=rev
Log:
JS2-676: add profiler rule cache eviction on session end and/or subject/principal change
Modified:
portals/jetspeed-2/portal/trunk/components/jetspeed-profiler/src/main/java/org/apache/jetspeed/profiler/impl/JetspeedProfilerImpl.java
Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-profiler/src/main/java/org/apache/jetspeed/profiler/impl/JetspeedProfilerImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-profiler/src/main/java/org/apache/jetspeed/profiler/impl/JetspeedProfilerImpl.java?rev=772087&r1=772086&r2=772087&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-profiler/src/main/java/org/apache/jetspeed/profiler/impl/JetspeedProfilerImpl.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-profiler/src/main/java/org/apache/jetspeed/profiler/impl/JetspeedProfilerImpl.java Wed May 6 07:35:45 2009
@@ -16,7 +16,9 @@
*/
package org.apache.jetspeed.profiler.impl;
+import java.io.Serializable;
import java.security.Principal;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -25,6 +27,10 @@
import java.util.Properties;
import javax.security.auth.Subject;
+import javax.servlet.http.HttpSessionActivationListener;
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionBindingListener;
+import javax.servlet.http.HttpSessionEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -41,7 +47,6 @@
import org.apache.jetspeed.request.RequestContext;
import org.apache.jetspeed.security.SubjectHelper;
import org.apache.jetspeed.security.UserSubjectPrincipal;
-import org.apache.jetspeed.security.impl.UserImpl;
import org.apache.ojb.broker.query.Criteria;
import org.apache.ojb.broker.query.QueryFactory;
import org.springframework.beans.BeansException;
@@ -57,6 +62,9 @@
public class JetspeedProfilerImpl extends InitablePersistenceBrokerDaoSupport
implements Profiler, BeanFactoryAware
{
+ /** Profiler context session attribute name */
+ public final static String PROFILER_CONTEXT_ATTRIBUTE_NAME = "org.apache.jetspeed.profiler.ProfilerContext";
+
/** The default rule. */
public final static String DEFAULT_RULE = "j1";
@@ -93,10 +101,15 @@
/** The configured default rule for this portal */
private String defaultRule = DEFAULT_RULE;
+ /** list of transient and persistent rules cached by principal and locator name */
private Map principalRules = Collections.synchronizedMap(new HashMap());
+ /** list of persistent rules cached by principal */
private Map rulesPerPrincipal = Collections.synchronizedMap(new HashMap());
+ /** list of all transient and persistent rules cached by principal */
+ private Map allRulesPerPrincipal = Collections.synchronizedMap(new HashMap());
+
private ProfileResolvers resolvers;
/** the default criterion bean name */
@@ -212,6 +225,9 @@
throw new ProfilerException(msg);
}
+ // setup/maintain profiler context for session end notification
+ setupProfilerContext(context);
+
// find a profiling rule for this principal
ProfilingRule rule = getRuleForPrincipal(principal, locatorName);
if (null == rule)
@@ -235,7 +251,7 @@
public ProfileLocator getDefaultProfile(RequestContext context,
String locatorName) throws ProfilerException
{
-
+ // find a profiling rule for the default principal
ProfilingRule rule = getRuleForPrincipal(DEFAULT_RULE_PRINCIPAL,
locatorName);
if (null == rule)
@@ -299,6 +315,8 @@
pr.setProfilingRule(rule);
principalRules.put(makePrincipalRuleKey(principal.getName(),
locatorName), pr);
+ // track cached principal rules
+ trackCachedPrincipalRulesPut(principal.getName(), pr);
} else
{
// Get the associated rule
@@ -357,7 +375,10 @@
getPersistenceBrokerTemplate().store(pr);
principalRules.put(makePrincipalRuleKey(principal.getName(),
locatorName), pr);
- this.rulesPerPrincipal.remove(principal.getName());
+ // track cached principal rules
+ trackCachedPrincipalRulesPut(principal.getName(), pr);
+ // reset persistent rules per principal
+ rulesPerPrincipal.remove(principal.getName());
}
private String makePrincipalRuleKey(String principal, String locator)
@@ -385,9 +406,11 @@
pr = (PrincipalRule) getPersistenceBrokerTemplate().getObjectByQuery(
QueryFactory.newQuery(getPrincipalRuleClass(), c));
+ if (pr != null) pr.getProfilingRule().setResolvers(resolvers);
principalRules.put(makePrincipalRuleKey(principal, locatorName), pr);
- if (pr != null) pr.getProfilingRule().setResolvers(resolvers);
+ // track cached principal rules
+ trackCachedPrincipalRulesPut(principal, pr);
return pr;
}
@@ -501,6 +524,10 @@
public Map getProfileLocators(RequestContext context, Principal principal)
throws ProfilerException
{
+ // setup/maintain profiler context for session end notification
+ setupProfilerContext(context);
+
+ // get profile locators
Map locators = new HashMap();
Collection rules = getRulesForPrincipal(principal);
@@ -517,8 +544,8 @@
public Map getDefaultProfileLocators(RequestContext context)
throws ProfilerException
{
+ // get default profile locators
Map locators = new HashMap();
-
Collection rules = getRulesForPrincipal(DEFAULT_RULE_PRINCIPAL);
Iterator it = rules.iterator();
@@ -571,9 +598,13 @@
throws ProfilerException
{
getPersistenceBrokerTemplate().delete(rule);
+ // reset persistent rules per principal
rulesPerPrincipal.remove(rule.getPrincipalName());
String key = this.makePrincipalRuleKey(rule.getPrincipalName(), rule.getLocatorName());
- principalRules.remove(key);
+ // remove individual rule
+ principalRules.remove(key);
+ // track cached principal rules
+ trackCachedPrincipalRulesRemoved(rule.getPrincipalName(), rule);
}
/*
@@ -738,5 +769,177 @@
}
}
+
+ /**
+ * Setup and maintain profiler context to be used to reap rule caches
+ * for principals on session end.
+ *
+ * @param context request context
+ * @throws ProfilerException when subject or principal not available
+ */
+ private void setupProfilerContext(RequestContext context) throws ProfilerException
+ {
+ // validate profiler context
+ ProfilerContext profilerContext = (ProfilerContext) context.getSessionAttribute(PROFILER_CONTEXT_ATTRIBUTE_NAME);
+ try
+ {
+ // access session principal and test for change
+ Principal principal = SubjectHelper.getBestPrincipal(context.getSubject(), UserSubjectPrincipal.class);
+ if (principal == null)
+ {
+ throw new NullPointerException("Principal not found");
+ }
+ if ((profilerContext == null) || (profilerContext.getPrincipal() != principal))
+ {
+ // setup/reset profiler context
+ context.setSessionAttribute(PROFILER_CONTEXT_ATTRIBUTE_NAME, new ProfilerContext(principal));
+ }
+ }
+ catch (Exception e)
+ {
+ String message = "Unable to access principal in pipeline: "+e;
+ log.error(message, e);
+ throw new ProfilerException(message, e);
+ }
+ }
+
+ /**
+ * Track all put rules, (persistent and transient), cached for a principal.
+ *
+ * @param principalName name of principal rules is cached under
+ * @param rule rule cached
+ */
+ private void trackCachedPrincipalRulesPut(String principalName, PrincipalRule rule)
+ {
+ if (rule != null)
+ {
+ // maintain list of all rules cached per principal
+ Collection allRules = (Collection)allRulesPerPrincipal.get(principalName);
+ if (allRules == null)
+ {
+ allRules = new ArrayList(4);
+ allRulesPerPrincipal.put(principalName, allRules);
+ }
+ allRules.add(rule);
+ }
+ }
+
+ /**
+ * Track all removed rules, (persistent and transient), cached for a principal.
+ *
+ * @param principalName name of principal rules is cached under
+ * @param rule rule cached
+ */
+ private void trackCachedPrincipalRulesRemoved(String principalName, PrincipalRule rule)
+ {
+ if (rule != null)
+ {
+ // maintain list of all rules cached per principal
+ Collection allRules = (Collection)allRulesPerPrincipal.get(principalName);
+ if (allRules != null)
+ {
+ allRules.remove(rule);
+ }
+ }
+ }
+
+ /**
+ * Clear cached profiler rule information for principal.
+ *
+ * @param principal cached profiler rule key
+ */
+ private void clearCachedPrincipalRules(Principal principal)
+ {
+ if (principal != null)
+ {
+ Collection rules = (Collection)allRulesPerPrincipal.remove(principal.getName());
+ if (rules != null)
+ {
+ rulesPerPrincipal.remove(principal.getName());
+ Iterator it = rules.iterator();
+ while (it.hasNext())
+ {
+ PrincipalRule rule = (PrincipalRule)it.next();
+ String key = this.makePrincipalRuleKey(rule.getPrincipalName(), rule.getLocatorName());
+ principalRules.remove(key);
+ }
+ }
+ }
+ }
+
+ /**
+ * ProfilerContext
+ *
+ * Class used to track session lifetime within profiler implementation
+ * so that cached profiler rule information per principal can be evicted
+ * from cache on session end.
+ */
+ public class ProfilerContext implements HttpSessionActivationListener, HttpSessionBindingListener, Serializable
+ {
+ private transient Principal principal;
+
+ /**
+ * Construct new profiler context with specified principal.
+ *
+ * @param principal profiler context principal
+ */
+ private ProfilerContext(Principal principal)
+ {
+ this.principal = principal;
+ }
+
+ /**
+ * Notification that the session has just been activated.
+ *
+ * @param event session activation event
+ */
+ public void sessionDidActivate(HttpSessionEvent event)
+ {
+ }
+
+ /**
+ * Notification that the session is about to be passivated.
+ *
+ * @param event session activation event
+ */
+ public void sessionWillPassivate(HttpSessionEvent event)
+ {
+ // clear cached principal rules on session end
+ clearCachedPrincipalRules(principal);
+ principal = null;
+ }
+
+ /**
+ * Notifies this context that it is being bound to
+ * a session and identifies the session.
+ *
+ * @param event session binding event
+ */
+ public void valueBound(HttpSessionBindingEvent event)
+ {
+ }
+ /**
+ * Notifies this context that it is being unbound
+ * from a session and identifies the session.
+ *
+ * @param event session binding event
+ */
+ public void valueUnbound(HttpSessionBindingEvent event)
+ {
+ // clear cached principal rules on session end
+ clearCachedPrincipalRules(principal);
+ principal = null;
+ }
+
+ /**
+ * Get context principal.
+ *
+ * @return context principal
+ */
+ private Principal getPrincipal()
+ {
+ return principal;
+ }
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org