Author: taylor
Date: Sat Jul 12 20:06:36 2014
New Revision: 1610038
URL: http://svn.apache.org/r1610038
Log:
JS2-1283: backporting changes to 2.2.3 from trunk
Modified:
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/CommonjWorkerMonitorImpl.java
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/RenderingJobImpl.java
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/WorkerImpl.java
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/WorkerMonitorImpl.java
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/RenderingJob.java
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/Worker.java
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-commons/src/main/java/org/apache/jetspeed/util/ServletRequestCleanupService.java
Modified:
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/CommonjWorkerMonitorImpl.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/CommonjWorkerMonitorImpl.java?rev=1610038&r1=1610037&r2=1610038&view=diff
==============================================================================
---
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/CommonjWorkerMonitorImpl.java
(original)
+++
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/CommonjWorkerMonitorImpl.java
Sat Jul 12 20:06:36 2014
@@ -5,9 +5,9 @@
* 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.
@@ -19,27 +19,26 @@ package org.apache.jetspeed.aggregator.i
import java.security.AccessControlContext;
import java.security.AccessController;
-import java.util.List;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.Collections;
-import java.util.Map;
import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.jetspeed.aggregator.PortletContent;
import org.apache.jetspeed.aggregator.RenderingJob;
import org.apache.jetspeed.aggregator.Worker;
import org.apache.jetspeed.aggregator.WorkerMonitor;
-import org.apache.jetspeed.aggregator.PortletContent;
-
import org.apache.jetspeed.container.PortletWindow;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import commonj.work.WorkManager;
import commonj.work.Work;
+import commonj.work.WorkEvent;
import commonj.work.WorkItem;
import commonj.work.WorkListener;
-import commonj.work.WorkEvent;
+import commonj.work.WorkManager;
/**
* The CommonjWorkerMonitorImpl is responsible for dispatching jobs to workers
@@ -51,45 +50,49 @@ import commonj.work.WorkEvent;
public class CommonjWorkerMonitorImpl implements WorkerMonitor, WorkListener
{
- public static final String ACCESS_CONTROL_CONTEXT_WORKER_ATTR =
AccessControlContext.class.getName();
+ /**
+ * @deprecated Use {@link RenderingJob#ACCESS_CONTROL_CONTEXT_WORKER_ATTR}
instead.
+ */
+ public static final String ACCESS_CONTROL_CONTEXT_WORKER_ATTR =
RenderingJob.ACCESS_CONTROL_CONTEXT_WORKER_ATTR;
+
public static final String COMMONJ_WORK_ITEM_ATTR =
WorkItem.class.getName();
public static final String WORKER_THREAD_ATTR = Worker.class.getName();
-
+
/** CommonJ Work Manamger provided by JavaEE container */
protected WorkManager workManager;
/** If true, invoke interrupt() on the worker thread when the job is
timeout. */
protected boolean interruptOnTimeout = true;
-
+
/** Enable rendering job works monitor thread for timeout checking */
protected boolean jobWorksMonitorEnabled = true;
-
+
/** Rendering job works to be monitored for timeout checking */
protected Map<WorkItem,RenderingJobCommonjWork> jobWorksMonitored =
Collections.synchronizedMap(new HashMap<WorkItem,RenderingJobCommonjWork>());
-
+
public CommonjWorkerMonitorImpl(WorkManager workManager)
{
this(workManager, true);
}
-
+
public CommonjWorkerMonitorImpl(WorkManager workManager, boolean
jobWorksMonitorEnabled)
{
this(workManager, jobWorksMonitorEnabled, true);
}
-
+
public CommonjWorkerMonitorImpl(WorkManager workManager, boolean
jobWorksMonitorEnabled, boolean interruptOnTimeout)
{
this.workManager = workManager;
this.jobWorksMonitorEnabled = jobWorksMonitorEnabled;
this.interruptOnTimeout = interruptOnTimeout;
}
-
+
/** Commons logging */
protected final static Logger log =
LoggerFactory.getLogger(CommonjWorkerMonitorImpl.class);
-
+
/** Renering Job Timeout monitor */
protected CommonjWorkerRenderingJobTimeoutMonitor jobMonitor = null;
-
+
public void start()
{
if (this.jobWorksMonitorEnabled)
@@ -108,7 +111,7 @@ public class CommonjWorkerMonitorImpl im
jobMonitor = null;
}
-
+
/**
* Assign a job to a worker and execute it or queue the job if no
* worker is available.
@@ -118,14 +121,14 @@ public class CommonjWorkerMonitorImpl im
public void process(RenderingJob job)
{
AccessControlContext context = AccessController.getContext();
- job.setWorkerAttribute(ACCESS_CONTROL_CONTEXT_WORKER_ATTR, context);
-
+
job.setWorkerAttribute(RenderingJob.ACCESS_CONTROL_CONTEXT_WORKER_ATTR,
context);
+
try
{
RenderingJobCommonjWork jobWork = new RenderingJobCommonjWork(job);
WorkItem workItem = this.workManager.schedule(jobWork, this);
job.setWorkerAttribute(COMMONJ_WORK_ITEM_ATTR, workItem);
-
+
if (this.jobWorksMonitorEnabled)
{
this.jobWorksMonitored.put(workItem, jobWork);
@@ -141,24 +144,24 @@ public class CommonjWorkerMonitorImpl im
{
return 0;
}
-
+
/**
- * Wait for all rendering jobs in the collection to finish successfully or
otherwise.
+ * Wait for all rendering jobs in the collection to finish successfully or
otherwise.
* @param renderingJobs the Collection of rendering job objects to wait
for.
*/
public void waitForRenderingJobs(List<RenderingJob> renderingJobs)
{
if (this.jobWorksMonitorEnabled)
{
- try
+ try
{
for (RenderingJob job : renderingJobs)
{
PortletContent portletContent = job.getPortletContent();
-
- synchronized (portletContent)
+
+ synchronized (portletContent)
{
- if (!portletContent.isComplete())
+ if (!portletContent.isComplete())
{
portletContent.wait();
}
@@ -174,14 +177,14 @@ public class CommonjWorkerMonitorImpl im
{
// We cannot use WorkingManager#waitForAll(workitems, timeout_ms)
for timeout.
// The second argument could be either WorkManager.IMMEDIATE or
WorkManager.INDEFINITE.
-
+
try
{
if (!renderingJobs.isEmpty())
{
Object lock = new Object();
MonitoringJobCommonjWork monitoringWork = new
MonitoringJobCommonjWork(lock, renderingJobs);
-
+
synchronized (lock)
{
this.workManager.schedule(monitoringWork, this);
@@ -195,7 +198,7 @@ public class CommonjWorkerMonitorImpl im
}
}
}
-
+
/**
* Returns a snapshot of the available jobs
* @return available jobs
@@ -204,14 +207,14 @@ public class CommonjWorkerMonitorImpl im
{
return 0;
}
-
+
public int getRunningJobsCount()
{
return 0;
}
-
+
// commonj.work.WorkListener implementations
-
+
public void workAccepted(WorkEvent we)
{
WorkItem workItem = we.getWorkItem();
@@ -228,7 +231,7 @@ public class CommonjWorkerMonitorImpl im
{
log.debug("[CommonjWorkMonitorImpl] workRejected: " + workItem);
}
-
+
if (this.jobWorksMonitorEnabled)
{
removeMonitoredJobWork(workItem);
@@ -251,18 +254,18 @@ public class CommonjWorkerMonitorImpl im
{
log.debug("[CommonjWorkMonitorImpl] workCompleted: " + workItem);
}
-
+
if (this.jobWorksMonitorEnabled)
{
removeMonitoredJobWork(workItem);
}
}
-
+
protected Object removeMonitoredJobWork(WorkItem workItem)
{
return this.jobWorksMonitored.remove(workItem);
}
-
+
class RenderingJobCommonjWork implements Work
{
@@ -277,21 +280,21 @@ public class CommonjWorkerMonitorImpl im
{
return false;
}
-
+
public void run()
{
if (jobWorksMonitorEnabled || interruptOnTimeout)
{
this.job.setWorkerAttribute(WORKER_THREAD_ATTR,
Thread.currentThread());
}
-
+
this.job.run();
}
-
+
public void release()
{
}
-
+
public RenderingJob getRenderingJob()
{
return this.job;
@@ -300,7 +303,7 @@ public class CommonjWorkerMonitorImpl im
class MonitoringJobCommonjWork implements Work
{
-
+
protected Object lock;
protected List<RenderingJob> renderingJobs;
@@ -309,12 +312,12 @@ public class CommonjWorkerMonitorImpl im
this.lock = lock;
this.renderingJobs = new ArrayList<RenderingJob>(jobs);
}
-
+
public boolean isDaemon()
{
return false;
}
-
+
public void run()
{
try
@@ -326,22 +329,22 @@ public class CommonjWorkerMonitorImpl im
RenderingJob job = it.next();
WorkItem workItem = (WorkItem)
job.getWorkerAttribute(COMMONJ_WORK_ITEM_ATTR);
int status = WorkEvent.WORK_ACCEPTED;
-
+
if (workItem != null)
{
status = workItem.getStatus();
}
-
+
boolean isTimeout = job.isTimeout();
-
+
if (isTimeout)
{
PortletContent content = job.getPortletContent();
-
+
if (interruptOnTimeout)
{
Thread worker = (Thread)
job.getWorkerAttribute(WORKER_THREAD_ATTR);
-
+
if (worker != null)
{
synchronized (content)
@@ -362,13 +365,13 @@ public class CommonjWorkerMonitorImpl im
}
}
}
-
+
if (status == WorkEvent.WORK_COMPLETED || status ==
WorkEvent.WORK_REJECTED || isTimeout)
{
it.remove();
- }
+ }
}
-
+
if (!this.renderingJobs.isEmpty())
{
synchronized (this)
@@ -377,7 +380,7 @@ public class CommonjWorkerMonitorImpl im
}
}
}
-
+
synchronized (this.lock)
{
this.lock.notify();
@@ -388,31 +391,31 @@ public class CommonjWorkerMonitorImpl im
log.error("Exceptiong during job timeout monitoring.", e);
}
}
-
+
public void release()
{
}
-
+
}
class CommonjWorkerRenderingJobTimeoutMonitor extends Thread {
long interval = 1000;
boolean shouldRun = true;
-
- CommonjWorkerRenderingJobTimeoutMonitor(long interval)
+
+ CommonjWorkerRenderingJobTimeoutMonitor(long interval)
{
super("CommonjWorkerRenderingJobTimeoutMonitor");
setDaemon(true);
- if (interval > 0)
+ if (interval > 0)
{
this.interval = interval;
}
}
/**
* Thread.stop() is deprecated.
- * This method achieves the same by setting the run varaible
"shouldRun" to false and interrupting the Thread,
+ * This method achieves the same by setting the run varaible
"shouldRun" to false and interrupting the Thread,
* effectively causing the thread to shutdown correctly.
*
*/
@@ -421,25 +424,25 @@ public class CommonjWorkerMonitorImpl im
shouldRun = false;
this.interrupt();
}
-
+
public void run()
{
while (shouldRun)
{
- try
+ try
{
List<RenderingJobCommonjWork> timeoutJobWorks = new
ArrayList<RenderingJobCommonjWork>();
-
+
for (RenderingJobCommonjWork jobWork :
jobWorksMonitored.values() )
{
RenderingJob job = jobWork.getRenderingJob();
-
+
if (job.isTimeout())
{
timeoutJobWorks.add(jobWork);
}
}
-
+
// Now, we can kill the timeout worker(s).
for (RenderingJobCommonjWork jobWork : timeoutJobWorks )
{
@@ -451,30 +454,30 @@ public class CommonjWorkerMonitorImpl im
killJobWork(jobWork);
}
}
- }
- catch (Exception e)
+ }
+ catch (Exception e)
{
log.error("Exception during job monitoring.", e);
}
-
- try
+
+ try
{
- synchronized (this)
+ synchronized (this)
{
wait(this.interval);
}
- }
- catch (InterruptedException e)
+ }
+ catch (InterruptedException e)
{
;
}
}
}
-
+
public void killJobWork(RenderingJobCommonjWork jobWork)
{
RenderingJob job = jobWork.getRenderingJob();
-
+
try
{
if (log.isWarnEnabled())
@@ -485,7 +488,7 @@ public class CommonjWorkerMonitorImpl im
PortletContent content = job.getPortletContent();
Thread worker = (Thread)
job.getWorkerAttribute(WORKER_THREAD_ATTR);
-
+
if (worker != null)
{
synchronized (content)
@@ -497,15 +500,15 @@ public class CommonjWorkerMonitorImpl im
}
}
}
- }
+ }
catch (Exception e)
{
log.error("Exceptiong during job killing.", e);
- }
- finally
+ }
+ finally
{
WorkItem workItem = (WorkItem)
job.getWorkerAttribute(COMMONJ_WORK_ITEM_ATTR);
-
+
if (workItem != null)
{
removeMonitoredJobWork(workItem);
Modified:
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/RenderingJobImpl.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/RenderingJobImpl.java?rev=1610038&r1=1610037&r2=1610038&view=diff
==============================================================================
---
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/RenderingJobImpl.java
(original)
+++
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/RenderingJobImpl.java
Sat Jul 12 20:06:36 2014
@@ -5,9 +5,9 @@
* 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.
@@ -17,27 +17,32 @@
package org.apache.jetspeed.aggregator.impl;
-import java.util.Map;
-import java.util.HashMap;
+import java.security.AccessControlContext;
+import java.security.PrivilegedAction;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import javax.portlet.UnavailableException;
+import javax.security.auth.Subject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.apache.jetspeed.aggregator.PortletContent;
import org.apache.jetspeed.aggregator.PortletRenderer;
import org.apache.jetspeed.aggregator.PortletTrackingManager;
import org.apache.jetspeed.aggregator.RenderingJob;
+import org.apache.jetspeed.container.PortletWindow;
import org.apache.jetspeed.om.page.ContentFragment;
import org.apache.jetspeed.om.page.Fragment;
+import org.apache.jetspeed.om.portlet.PortletDefinition;
import org.apache.jetspeed.request.RequestContext;
+import org.apache.jetspeed.security.JSSubject;
import org.apache.jetspeed.statistics.PortalStatistics;
+import org.apache.jetspeed.util.ServletRequestCleanupService;
import org.apache.pluto.container.PortletContainer;
-import org.apache.jetspeed.om.portlet.PortletDefinition;
-import org.apache.jetspeed.container.PortletWindow;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* The RenderingJob is responsible for storing all necessary objets for
@@ -58,7 +63,7 @@ public class RenderingJobImpl implements
protected PortletWindow window = null;
protected HttpServletRequest request = null;
protected HttpServletResponse response = null;
-
+
protected PortletContainer container = null;
protected PortletRenderer renderer = null;
protected RequestContext requestContext = null;
@@ -66,38 +71,38 @@ public class RenderingJobImpl implements
protected PortletDefinition portletDefinition;
protected PortalStatistics statistics;
-
+
protected int expirationCache = 0;
-
+
protected Map<String, Object> workerAttributes;
protected boolean parallel;
protected long startTimeMillis = 0;
protected long timeout;
-
+
public RenderingJobImpl(PortletContainer container,
PortletRenderer renderer,
PortletDefinition portletDefinition,
- HttpServletRequest request,
- HttpServletResponse response,
- RequestContext requestContext,
+ HttpServletRequest request,
+ HttpServletResponse response,
+ RequestContext requestContext,
PortletWindow window,
PortalStatistics statistics,
int expirationCache)
{
this.container = container;
this.renderer = renderer;
- this.portletTracking = renderer.getPortletTrackingManager();
+ this.portletTracking = renderer.getPortletTrackingManager();
this.statistics = statistics;
this.portletDefinition = portletDefinition;
this.request = request;
this.response = response;
- this.requestContext = requestContext;
+ this.requestContext = requestContext;
this.window = window;
this.expirationCache = expirationCache;
}
-
+
public PortletRenderer getRenderer()
{
return renderer;
@@ -132,20 +137,21 @@ public class RenderingJobImpl implements
}
/**
- * Checks if queue is empty, if not try to empty it by calling
- * the WorkerMonitor. When done, pause until next scheduled scan.
+ * Job execution entry point method.
*/
public void run()
- {
+ {
parallel = true;
boolean clearContext = requestContext.ensureThreadContext();
+
try
{
- if (this.timeout > 0)
+ if (this.timeout > 0)
{
this.startTimeMillis = System.currentTimeMillis();
}
- execute();
+
+ ServletRequestCleanupService.executeNestedRenderJob(this);
}
finally
{
@@ -153,34 +159,90 @@ public class RenderingJobImpl implements
{
requestContext.clearThreadContext();
}
+
parallel = false;
+
synchronized (window.getFragment().getPortletContent())
{
- if (log.isDebugEnabled()) log.debug("Notifying completion of
rendering job for portlet window " + this.window.getId());
+ if (log.isDebugEnabled())
+ {
+ log.debug("Notifying completion of rendering job for
portlet window " + this.window.getId());
+ }
+
window.getFragment().getPortletContent().notifyAll();
}
}
}
-
+
/**
- * <p>
- * execute
- * </p>
- *
- *
+ * The rendering job execution method.
+ * This method tries to find the underlying access control context, and
execute it as a privileged action if found.
+ * This method is invoked back by {@link ServletRequestCleanupService}
which is called in the {@link #run()} call.
*/
public void execute()
{
+ // We should try to retrieve the subject in context when this job is
executed in a worker thread.
+ // If it is being executed in the normal http request processing
thread, not in a separate worker thread,
+ // then we don't have to find the subject in context and run it with
the context.
+ Subject subject = null;
+
+ // The ACCESS_CONTROL_CONTEXT_WORKER_ATTR attribute is available only
when this job is executed in a worker thread.
+ AccessControlContext context = (AccessControlContext)
getWorkerAttribute(ACCESS_CONTROL_CONTEXT_WORKER_ATTR);
+
+ if (context != null)
+ {
+ subject = JSSubject.getSubject(context);
+ }
+
+ // If a subject found from the the ACCESS_CONTROL_CONTEXT_WORKER_ATTR
attribute from the worker executing job.
+ if (subject != null)
+ {
+ JSSubject.doAsPrivileged(subject, new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ try
+ {
+ executeInternal();
+ }
+ catch (Throwable t)
+ {
+ log.error("Job execution error", t);
+ }
+ return null;
+ }
+ }, context);
+ }
+ // Otherwise, just execute it without doing a privileged action.
+ else
+ {
+ try
+ {
+ executeInternal();
+ }
+ catch (Throwable t)
+ {
+ log.error("Job execution error", t);
+ }
+ }
+
+ }
+
+ /**
+ * The internal rendering job execution method called by {@link
#execute()}.
+ */
+ private void executeInternal()
+ {
long start = System.currentTimeMillis();
ContentFragment fragment = this.window.getFragment();
-
+
try
{
if (log.isDebugEnabled())
{
log.debug("Rendering OID "+this.window.getId()+" "+
this.request +" "+this.response);
}
- container.doRender(this.window, this.request, this.response);
+ container.doRender(this.window, this.request, this.response);
}
catch (Throwable t)
{
@@ -203,7 +265,7 @@ public class RenderingJobImpl implements
{
long end = System.currentTimeMillis();
boolean exceededTimeout =
portletTracking.exceededTimeout(end - start, window);
-
+
if (statistics != null)
{
statistics.logPortletAccess(requestContext,
fragment.getName(), PortalStatistics.HTTP_OK, end - start);
@@ -233,9 +295,9 @@ public class RenderingJobImpl implements
}
}
}
-
+
/**
- *
+ *
* <p>
* getWindow
* </p>
@@ -248,7 +310,7 @@ public class RenderingJobImpl implements
}
/**
- *
+ *
* <p>
* getPortletContent
* </p>
@@ -296,7 +358,7 @@ public class RenderingJobImpl implements
{
this.workerAttributes = Collections.synchronizedMap(new
HashMap<String, Object>());
}
-
+
if (value != null)
{
this.workerAttributes.put(name, value);
@@ -306,19 +368,19 @@ public class RenderingJobImpl implements
this.workerAttributes.remove(name);
}
}
-
+
public Object getWorkerAttribute(String name)
{
Object value = null;
-
+
if (this.workerAttributes != null)
{
value = this.workerAttributes.get(name);
}
-
+
return value;
}
-
+
public void removeWorkerAttribute(String name)
{
if (this.workerAttributes != null)
Modified:
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/WorkerImpl.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/WorkerImpl.java?rev=1610038&r1=1610037&r2=1610038&view=diff
==============================================================================
---
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/WorkerImpl.java
(original)
+++
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/WorkerImpl.java
Sat Jul 12 20:06:36 2014
@@ -5,9 +5,9 @@
* 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.
@@ -18,16 +18,12 @@
package org.apache.jetspeed.aggregator.impl;
import java.security.AccessControlContext;
-import java.security.PrivilegedAction;
-
-import javax.security.auth.Subject;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.apache.jetspeed.aggregator.RenderingJob;
import org.apache.jetspeed.aggregator.Worker;
import org.apache.jetspeed.aggregator.WorkerMonitor;
-import org.apache.jetspeed.security.JSSubject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Worker thread processes jobs and notify its WorkerMonitor when completed.
@@ -53,7 +49,11 @@ public class WorkerImpl extends Thread i
/** Job to process */
Runnable job = null;
- /** Context to process job within */
+ /**
+ * Context to process job within
+ *
+ * @deprecated AccessControlContext must not be directly accessed by a
worker thread.
+ */
private AccessControlContext context = null;
/** Monitor for this Worker */
@@ -109,6 +109,11 @@ public class WorkerImpl extends Thread i
/**
* Sets the job to execute in security context
+ *
+ * @deprecated Use only {@link #setJob(Runnable)} because
AccessControlContext must not be directly accessed by
+ * a worker thread. Instead AccessControlContext must be accessed directly
by the job implementation in order
+ * to use the AccessControlContext instance safely regardless of the
physical worker thread implementation
+ * (e.g, WorkerImpl or container managed thread by commonj worker monitor).
*/
public void setJob(Runnable job, AccessControlContext context)
{
@@ -162,39 +167,14 @@ public class WorkerImpl extends Thread i
if (this.job != null)
{
log.debug("Processing job for window :" +
((RenderingJob)job).getWindow().getId());
- Subject subject = null;
- if (this.context != null)
+
+ try
{
- subject = JSSubject.getSubject(this.context);
+ this.job.run();
}
- if (subject != null)
+ catch (Throwable t)
{
- JSSubject.doAsPrivileged(subject, new
PrivilegedAction<Object>()
- {
- public Object run()
- {
- try
- {
- WorkerImpl.this.job.run();
- }
- catch (Throwable t)
- {
- log.error("Thread error", t);
- }
- return null;
- }
- }, this.context);
- }
- else
- {
- try
- {
- this.job.run();
- }
- catch (Throwable t)
- {
- log.error("Thread error", t);
- }
+ log.error("Thread error", t);
}
}
@@ -210,5 +190,5 @@ public class WorkerImpl extends Thread i
this.running = false;
super.interrupt();
}
-
+
}
Modified:
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/WorkerMonitorImpl.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/WorkerMonitorImpl.java?rev=1610038&r1=1610037&r2=1610038&view=diff
==============================================================================
---
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/WorkerMonitorImpl.java
(original)
+++
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/WorkerMonitorImpl.java
Sat Jul 12 20:06:36 2014
@@ -5,9 +5,9 @@
* 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.
@@ -20,21 +20,20 @@ package org.apache.jetspeed.aggregator.i
import java.security.AccessControlContext;
import java.security.AccessController;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
-import java.util.LinkedList;
-import java.util.Collections;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.jetspeed.aggregator.PortletContent;
import org.apache.jetspeed.aggregator.RenderingJob;
import org.apache.jetspeed.aggregator.WorkerMonitor;
-import org.apache.jetspeed.aggregator.PortletContent;
-import org.apache.jetspeed.util.Queue;
-import org.apache.jetspeed.util.FIFOQueue;
-
import org.apache.jetspeed.container.PortletWindow;
import org.apache.jetspeed.container.PortletWindowID;
+import org.apache.jetspeed.util.FIFOQueue;
+import org.apache.jetspeed.util.Queue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* The WorkerMonitor is responsible for dispatching jobs to workers
@@ -49,7 +48,10 @@ import org.apache.jetspeed.container.Por
*/
public class WorkerMonitorImpl implements WorkerMonitor
{
- public static final String ACCESS_CONTROL_CONTEXT_WORKER_ATTR =
AccessControlContext.class.getName();
+ /**
+ * @deprecated Use {@link RenderingJob#ACCESS_CONTROL_CONTEXT_WORKER_ATTR}
instead.
+ */
+ public static final String ACCESS_CONTROL_CONTEXT_WORKER_ATTR =
RenderingJob.ACCESS_CONTROL_CONTEXT_WORKER_ATTR;
public WorkerMonitorImpl(int minWorkers, int maxWorkers, int spareWorkers,
int maxJobsPerWorker)
{
@@ -58,7 +60,7 @@ public class WorkerMonitorImpl implement
this.spareWorkers = spareWorkers;
this.maxJobsPerWorker = maxJobsPerWorker;
}
-
+
/** Commons logging */
protected final static Logger log =
LoggerFactory.getLogger(WorkerMonitorImpl.class);
@@ -67,7 +69,7 @@ public class WorkerMonitorImpl implement
/** Count of running jobs **/
protected int runningJobs = 0;
-
+
/** Minimum number of wokers to create */
protected int minWorkers = 5;
@@ -107,14 +109,14 @@ public class WorkerMonitorImpl implement
public void stop()
{
synchronized (workers)
- {
+ {
for (WorkerImpl worker : new ArrayList<WorkerImpl>(workers))
{
worker.interrupt();
}
}
synchronized (workersMonitored)
- {
+ {
for (WorkerImpl worker : new
ArrayList<WorkerImpl>(workersMonitored))
{
worker.interrupt();
@@ -189,8 +191,8 @@ public class WorkerMonitorImpl implement
WorkerImpl worker = this.getWorker();
AccessControlContext context = AccessController.getContext();
- job.setWorkerAttribute(ACCESS_CONTROL_CONTEXT_WORKER_ATTR, context);
-
+
job.setWorkerAttribute(RenderingJob.ACCESS_CONTROL_CONTEXT_WORKER_ATTR,
context);
+
if (worker==null)
{
queue.push(job);
@@ -201,7 +203,7 @@ public class WorkerMonitorImpl implement
{
synchronized (worker)
{
- worker.setJob(job, context);
+ worker.setJob(job);
if (job.getTimeout() > 0)
{
@@ -218,22 +220,22 @@ public class WorkerMonitorImpl implement
}
}
}
-
+
/**
- * Wait for all rendering jobs in the collection to finish successfully or
otherwise.
+ * Wait for all rendering jobs in the collection to finish successfully or
otherwise.
* @param renderingJobs the Collection of rendering job objects to wait
for.
*/
public void waitForRenderingJobs(List<RenderingJob> renderingJobs)
{
- try
+ try
{
for (RenderingJob job : renderingJobs)
{
PortletContent portletContent = job.getPortletContent();
-
- synchronized (portletContent)
+
+ synchronized (portletContent)
{
- if (!portletContent.isComplete())
+ if (!portletContent.isComplete())
{
portletContent.wait();
}
@@ -267,20 +269,19 @@ public class WorkerMonitorImpl implement
synchronized (worker)
{
RenderingJob job = null;
-
+
if (worker.getJobCount() < this.maxJobsPerWorker)
{
job = (RenderingJob) queue.pop();
-
+
if (job != null)
{
- AccessControlContext context = (AccessControlContext)
job.getWorkerAttribute(ACCESS_CONTROL_CONTEXT_WORKER_ATTR);
- worker.setJob(job, context);
+ worker.setJob(job);
runningJobs--;
return;
}
}
-
+
worker.setJob(null);
worker.resetJobCount();
runningJobs--;
@@ -301,7 +302,7 @@ public class WorkerMonitorImpl implement
{
return queue.size();
}
-
+
/**
* Returns a snapshot of the available jobs
* @return available jobs
@@ -310,17 +311,17 @@ public class WorkerMonitorImpl implement
{
return workers.size();
}
-
+
public int getRunningJobsCount()
{
return this.tg.activeCount();
}
-
+
class RenderingJobTimeoutMonitor extends Thread
{
long interval = 1000;
boolean shouldRun = true;
-
+
RenderingJobTimeoutMonitor(long interval)
{
super("RenderingJobTimeoutMonitor");
@@ -333,7 +334,7 @@ public class WorkerMonitorImpl implement
}
/**
* Thread.stop() is deprecated.
- * This method achieves the same by setting the run varaible
"shouldRun" to false and interrupting the Thread,
+ * This method achieves the same by setting the run varaible
"shouldRun" to false and interrupting the Thread,
* effectively causing the thread to shutdown correctly.
*
*/
@@ -342,25 +343,25 @@ public class WorkerMonitorImpl implement
shouldRun = false;
this.interrupt();
}
-
+
public void run()
{
while (shouldRun)
{
- try
+ try
{
- // Because a timeout worker can be removed
+ // Because a timeout worker can be removed
// in the workersMonitored collection during iterating,
// copy timeout workers in the following collection to
kill later.
List<WorkerImpl> timeoutWorkers = new
ArrayList<WorkerImpl>();
- synchronized (workersMonitored)
+ synchronized (workersMonitored)
{
for (WorkerImpl worker : workersMonitored)
{
RenderingJob job = (RenderingJob) worker.getJob();
-
+
if ((null != job) && (job.isTimeout()))
{
timeoutWorkers.add(worker);
@@ -379,21 +380,21 @@ public class WorkerMonitorImpl implement
killJob(worker, job);
}
}
- }
- catch (Exception e)
+ }
+ catch (Exception e)
{
log.error("Exception during job monitoring.", e);
}
-
- try
+
+ try
{
- synchronized (this)
+ synchronized (this)
{
wait(this.interval);
}
- }
- catch (InterruptedException e)
- {
+ }
+ catch (InterruptedException e)
+ {
}
}
}
@@ -410,7 +411,7 @@ public class WorkerMonitorImpl implement
}
PortletContent content = job.getPortletContent();
-
+
synchronized (content)
{
if (!content.isComplete())
@@ -419,7 +420,7 @@ public class WorkerMonitorImpl implement
content.wait();
}
}
-
+
} catch (Exception e)
{
log.error("Exceptiong during job killing.", e);
Modified:
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/RenderingJob.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/RenderingJob.java?rev=1610038&r1=1610037&r2=1610038&view=diff
==============================================================================
---
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/RenderingJob.java
(original)
+++
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/RenderingJob.java
Sat Jul 12 20:06:36 2014
@@ -5,9 +5,9 @@
* 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.
@@ -16,13 +16,15 @@
*/
package org.apache.jetspeed.aggregator;
+import java.security.AccessControlContext;
+
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.jetspeed.container.PortletWindow;
import org.apache.jetspeed.om.page.ContentFragment;
-import org.apache.jetspeed.request.RequestContext;
import org.apache.jetspeed.om.portlet.PortletDefinition;
-import org.apache.jetspeed.container.PortletWindow;
+import org.apache.jetspeed.request.RequestContext;
/**
* Worker thread processes jobs and notify its WorkerMonitor when completed.
@@ -34,11 +36,17 @@ import org.apache.jetspeed.container.Por
*/
public interface RenderingJob extends Runnable
{
+
+ /**
+ * Worker attribute name of AccessControlContext object in the current
request processing context.
+ */
+ String ACCESS_CONTROL_CONTEXT_WORKER_ATTR =
AccessControlContext.class.getName();
+
void execute();
-
+
PortletRenderer getRenderer();
-
- PortletWindow getWindow();
+
+ PortletWindow getWindow();
PortletContent getPortletContent();
@@ -47,7 +55,7 @@ public interface RenderingJob extends Ru
long getTimeout();
boolean isTimeout();
-
+
PortletDefinition getPortletDefinition();
HttpServletRequest getRequest();
@@ -61,9 +69,9 @@ public interface RenderingJob extends Ru
int getExpirationCache();
void setWorkerAttribute(String name, Object value);
-
+
Object getWorkerAttribute(String name);
-
+
void removeWorkerAttribute(String name);
}
Modified:
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/Worker.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/Worker.java?rev=1610038&r1=1610037&r2=1610038&view=diff
==============================================================================
---
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/Worker.java
(original)
+++
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/Worker.java
Sat Jul 12 20:06:36 2014
@@ -5,9 +5,9 @@
* 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.
@@ -26,7 +26,7 @@ import java.security.AccessControlContex
* @author <a href="mailto:[email protected]">David Sean Taylor</a>
* @version $Id: $
*/
-public interface Worker
+public interface Worker
{
int getJobCount();
@@ -40,14 +40,19 @@ public interface Worker
* stop after processing its current job.
*/
void setRunning(boolean status);
-
+
/**
* Sets the moitor of this worker
*/
void setMonitor(WorkerMonitor monitor);
-
+
/**
* Sets the job to execute in security context
+ *
+ * @deprecated Use only {@link #setJob(Runnable)} because
AccessControlContext must not be directly accessed by
+ * a worker thread. Instead AccessControlContext must be accessed directly
by the job implementation in order
+ * to use the AccessControlContext instance safely regardless of the
physical worker thread implementation
+ * (e.g, WorkerImpl or container managed thread by commonj worker monitor).
*/
void setJob(Runnable job, AccessControlContext context);
@@ -60,6 +65,6 @@ public interface Worker
* Retrieves the job to execute
*/
Runnable getJob();
-
+
void start();
}
Modified:
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-commons/src/main/java/org/apache/jetspeed/util/ServletRequestCleanupService.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-commons/src/main/java/org/apache/jetspeed/util/ServletRequestCleanupService.java?rev=1610038&r1=1610037&r2=1610038&view=diff
==============================================================================
---
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-commons/src/main/java/org/apache/jetspeed/util/ServletRequestCleanupService.java
(original)
+++
portals/jetspeed-2/portal/branches/JETSPEED-BRANCH-2.2.2-POST-RELEASE/jetspeed-commons/src/main/java/org/apache/jetspeed/util/ServletRequestCleanupService.java
Sat Jul 12 20:06:36 2014
@@ -26,6 +26,8 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.jetspeed.aggregator.RenderingJob;
+
/**
* @version $Id$
*
@@ -44,12 +46,12 @@ public class ServletRequestCleanupServic
}
return list;
}
-
+
public static void addCleanupCallback(ServletRequestCleanupCallback
callback)
{
List<ServletRequestCleanupCallback> callbacks = getCallbacks(false);
if (callbacks == null)
- {
+ {
callbacks = getCallbacks(true);
try
{
@@ -64,7 +66,61 @@ public class ServletRequestCleanupServic
}
callbacks.add(callback);
}
-
+
+ public static void executeNestedRenderJob(RenderingJob job)
+ {
+ if (getCallbacks(false) == null)
+ {
+ List<ServletRequestCleanupCallback> callbacks = getCallbacks(true);
+ Throwable jobException = null;
+
+ try
+ {
+ job.execute();
+ }
+ catch (Throwable t)
+ {
+ jobException = t;
+ t.fillInStackTrace();
+ }
+
+ for (ServletRequestCleanupCallback callback : callbacks)
+ {
+ try
+ {
+
callback.cleanup(job.getWindow().getPortletRequestContext().getServletContext(),
job.getRequest(), job.getResponse());
+ }
+ catch (Throwable tc)
+ {
+ try
+ {
+
JetspeedLoggerUtil.getSharedLogger(ServletRequestCleanupService.class).error("Cleanup
callback execution failed", tc);
+ }
+ catch (Throwable tl)
+ {
+ // ignore
+ }
+ }
+ }
+
+ ServletRequestCleanupService.callbacks.remove();
+
+ if (jobException != null)
+ {
+ if (jobException instanceof RuntimeException)
+ {
+ throw (RuntimeException) jobException;
+ }
+
+ throw new RuntimeException(jobException);
+ }
+ }
+ else
+ {
+ job.execute();
+ }
+ }
+
/**
* Servlet Filter doFilter delegate method which will execute registered
ServletRequestCleanupCallbacks
* after the filterChain, if any.
@@ -94,7 +150,7 @@ public class ServletRequestCleanupServic
{
filterException = tf;
tf.fillInStackTrace();
- }
+ }
for (ServletRequestCleanupCallback callback : callbacks)
{
try
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]