/** create and submit the portlet content rendering job to the thread pool */ protected IPortletRenderExecutionWorker startPortletRenderInternal( IPortletWindowId portletWindowId, HttpServletRequest request, HttpServletResponse response) { // first check to see if there is a Throwable in the session for this IPortletWindowId final Map<IPortletWindowId, Exception> portletFailureMap = getPortletErrorMap(request); final Exception cause = portletFailureMap.remove(portletWindowId); final IPortletRenderExecutionWorker portletRenderExecutionWorker; if (null != cause) { // previous action failed, dispatch to errorPortlet immediately portletRenderExecutionWorker = this.portletWorkerFactory.createFailureWorker(request, response, portletWindowId, cause); } else { IPortletWindow portletWindow = portletWindowRegistry.getPortletWindow(request, portletWindowId); IPortletDefinition portletDef = portletWindow.getPortletEntity().getPortletDefinition(); if (portletDef.getLifecycleState().equals(PortletLifecycleState.MAINTENANCE)) { // Prevent the portlet from rendering; replace with a helpful "Out of Service" message portletRenderExecutionWorker = this.portletWorkerFactory.createFailureWorker( request, response, portletWindowId, new MaintenanceModeException()); } else { // Happy path portletRenderExecutionWorker = this.portletWorkerFactory.createRenderWorker(request, response, portletWindowId); } } portletRenderExecutionWorker.submit(); final Map<IPortletWindowId, IPortletRenderExecutionWorker> portletRenderingMap = this.getPortletRenderingMap(request); portletRenderingMap.put(portletWindowId, portletRenderExecutionWorker); return portletRenderExecutionWorker; }
/** Checks to see if a worker has been retrieved (not orphaned) and if it is complete. */ protected void checkWorkerCompletion( HttpServletRequest request, IPortletRenderExecutionWorker portletRenderExecutionWorker) { if (!portletRenderExecutionWorker.isRetrieved()) { final IPortletWindowId portletWindowId = portletRenderExecutionWorker.getPortletWindowId(); final IPortletWindow portletWindow = this.portletWindowRegistry.getPortletWindow(request, portletWindowId); this.logger.warn( "Portlet worker started but never retrieved for {}, worker {}." + " If random portlet fnames it may be users switching tabs before page is done rendering" + " (would see separate log message with java.net.SocketException on socket write)." + " If repeatedly occurring with one portlet fname your theme layout xsl may not be including" + " a portlet present in your layout xml files (see" + " http://jasig.275507.n4.nabble.com/Portlet-worker-started-but-never-retrieved-td4580698.html)", portletWindow, portletRenderExecutionWorker); try { portletRenderExecutionWorker.get(0); } catch (Exception e) { // Ignore exception here, we just want to get this worker to complete } } if (!portletRenderExecutionWorker.isComplete()) { cancelWorker(request, portletRenderExecutionWorker); } }
/** * Returns the PortletRenderResult waiting up to the portlet's timeout * * @return The PortletRenderResult from the portlet's execution * @throws TimeoutException If the portlet's timeout was hit before a result was returned * @throws Exception The exception thrown by the portlet during execution */ protected PortletRenderResult getPortletRenderResult( IPortletWindowId portletWindowId, HttpServletRequest request, HttpServletResponse response) throws Exception { final IPortletRenderExecutionWorker tracker = getRenderedPortletBodyWorker(portletWindowId, request, response); final long timeout = getPortletRenderTimeout(portletWindowId, request); return tracker.get(timeout); }
/** * create and submit the portlet header rendering job to the thread pool * * @param portletWindowId * @param request * @param response * @return */ protected IPortletRenderExecutionWorker startPortletHeaderRenderInternal( IPortletWindowId portletWindowId, HttpServletRequest request, HttpServletResponse response) { IPortletRenderExecutionWorker portletHeaderRenderWorker = this.portletWorkerFactory.createRenderHeaderWorker(request, response, portletWindowId); portletHeaderRenderWorker.submit(); final Map<IPortletWindowId, IPortletRenderExecutionWorker> portletHeaderRenderingMap = this.getPortletHeaderRenderingMap(request); portletHeaderRenderingMap.put(portletWindowId, portletHeaderRenderWorker); return portletHeaderRenderWorker; }
/* (non-Javadoc) * @see org.apereo.portal.portlet.rendering.IPortletExecutionManager#getPortletHeadOutput(org.apereo.portal.portlet.om.IPortletWindowId, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override public String getPortletHeadOutput( IPortletWindowId portletWindowId, HttpServletRequest request, HttpServletResponse response) { if (doesPortletNeedHeaderWorker(portletWindowId, request)) { final IPortletRenderExecutionWorker tracker = getRenderedPortletHeaderWorker(portletWindowId, request, response); final long timeout = getPortletRenderTimeout(portletWindowId, request); try { final String output = tracker.getOutput(timeout); return output == null ? "" : output; } catch (Exception e) { logger.error("failed to render header output for " + portletWindowId, e); return ""; } } logger.debug(portletWindowId + " does not produce output for header"); return ""; }
/* (non-Javadoc) * @see org.apereo.portal.portlet.rendering.IPortletExecutionManager#getPortletOutput(org.apereo.portal.portlet.om.IPortletWindowId, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override public String getPortletOutput( IPortletWindowId portletWindowId, HttpServletRequest request, HttpServletResponse response) { final IPortletRenderExecutionWorker tracker = getRenderedPortletBodyWorker(portletWindowId, request, response); final long timeout = getPortletRenderTimeout(portletWindowId, request); try { final String output = tracker.getOutput(timeout); return output == null ? "" : output; } catch (Exception e) { final IPortletFailureExecutionWorker failureWorker = this.portletWorkerFactory.createFailureWorker(request, response, portletWindowId, e); // TODO publish portlet error event? try { failureWorker.submit(); return failureWorker.getOutput(timeout); } catch (Exception e1) { logger.error("Failed to render error portlet for: " + portletWindowId, e1); return "Error Portlet Unavailable. Please contact your portal administrators."; } } }