use of javax.portlet.CacheControl in project uPortal by Jasig.
the class PortletRendererImpl method doRender.
protected PortletRenderResult doRender(IPortletWindowId portletWindowId, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, PortletOutputHandler portletOutputHandler, RenderPart renderPart) throws IOException {
final CacheState<CachedPortletData<PortletRenderResult>, PortletRenderResult> cacheState = renderPart.getCacheState(this.portletCacheControlService, httpServletRequest, portletWindowId);
final IPortletWindow portletWindow = this.portletWindowRegistry.getPortletWindow(httpServletRequest, portletWindowId);
enforceConfigPermission(httpServletRequest, portletWindow);
/*
* If the portlet is rendering in EXCLUSIVE WindowState ignore the provided PortletOutputHandler and
* write directly to the response.
*
* THIS IS VERY BAD AND SHOULD BE DEPRECATED ALONG WITH EXCLUSIVE WINDOW STATE
*/
if (IPortletRenderer.EXCLUSIVE.equals(portletWindow.getWindowState())) {
portletOutputHandler = new ResourcePortletOutputHandler(httpServletResponse);
}
if (cacheState.isUseCachedData()) {
return doRenderReplayCachedContent(portletWindow, httpServletRequest, cacheState, portletOutputHandler, renderPart, 0);
}
final int cacheSizeThreshold = this.portletCacheControlService.getCacheSizeThreshold();
final CachingPortletOutputHandler cachingPortletOutputHandler = new CachingPortletOutputHandler(portletOutputHandler, cacheSizeThreshold);
final CacheControl cacheControl = cacheState.getCacheControl();
// Setup the request and response
httpServletRequest = this.setupPortletRequest(httpServletRequest);
httpServletResponse = new PortletMimeHttpServletResponseWrapper(httpServletResponse, portletWindow, portletOutputHandler, cacheControl);
httpServletRequest.setAttribute(IPortletRenderer.ATTRIBUTE__PORTLET_CACHE_CONTROL, cacheControl);
httpServletRequest.setAttribute(IPortletRenderer.ATTRIBUTE__PORTLET_OUTPUT_HANDLER, cachingPortletOutputHandler);
logger.debug("Rendering portlet {} for window {}", renderPart.name(), portletWindow);
final long renderStartTime = System.nanoTime();
try {
httpServletRequest.setAttribute(PortletRequest.RENDER_PART, renderPart.getRenderPart());
this.portletContainer.doRender(portletWindow.getPlutoPortletWindow(), httpServletRequest, httpServletResponse);
} catch (PortletException pe) {
throw new PortletDispatchException("The portlet window '" + portletWindow + "' threw an exception while executing renderMarkup.", portletWindow, pe);
} catch (PortletContainerException pce) {
throw new PortletDispatchException("The portlet container threw an exception while executing renderMarkup on portlet window '" + portletWindow + "'.", portletWindow, pce);
} catch (IOException ioe) {
throw new PortletDispatchException("The portlet window '" + portletWindow + "' threw an exception while executing renderMarkup.", portletWindow, ioe);
}
final long executionTime = System.nanoTime() - renderStartTime;
// See if the portlet signaled to use the cached content
final boolean useCachedContent = cacheControl.useCachedContent();
if (useCachedContent) {
final CachedPortletData<PortletRenderResult> cachedPortletData = cacheState.getCachedPortletData();
if (cachedPortletData == null) {
throw new PortletDispatchException("The portlet window '" + portletWindow + "' indicated via CacheControl#useCachedContent " + "that the portal should render cached content, however there is no cached content to return. " + "This is a portlet bug.", portletWindow);
}
// Update the expiration time and re-store in the cache
cachedPortletData.updateExpirationTime(cacheControl.getExpirationTime());
renderPart.cachePortletOutput(portletCacheControlService, portletWindowId, httpServletRequest, cacheState, cachedPortletData);
return doRenderReplayCachedContent(portletWindow, httpServletRequest, cacheState, portletOutputHandler, renderPart, executionTime);
}
publishRenderEvent(portletWindow, httpServletRequest, renderPart, executionTime, false);
// Build the render result
final PortletRenderResult portletRenderResult = constructPortletRenderResult(httpServletRequest, executionTime);
// Check if the portlet's output should be cached
if (cacheState != null) {
boolean shouldCache = this.portletCacheControlService.shouldOutputBeCached(cacheControl);
if (shouldCache) {
final CachedPortletData<PortletRenderResult> cachedPortletData = cachingPortletOutputHandler.getCachedPortletData(portletRenderResult, cacheControl);
if (cachedPortletData != null) {
renderPart.cachePortletOutput(portletCacheControlService, portletWindowId, httpServletRequest, cacheState, cachedPortletData);
}
}
}
return portletRenderResult;
}
use of javax.portlet.CacheControl in project uPortal by Jasig.
the class PortletCacheControlServiceImplTest method testCachePrivateRenderRoundTrip.
@Test
public void testCachePrivateRenderRoundTrip() {
MockHttpServletRequest httpRequest = new MockHttpServletRequest();
MockPortletWindowId portletWindowId = new MockPortletWindowId("123");
MockPortletDefinitionId portletDefinitionId = new MockPortletDefinitionId(789);
when(portletDescriptor.getCacheScope()).thenReturn(MimeResponse.PUBLIC_SCOPE);
when(portletWindowRegistry.getPortletWindow(httpRequest, portletWindowId)).thenReturn(portletWindow);
when(portletWindow.getPortletWindowId()).thenReturn(portletWindowId);
when(portletWindow.getPortletEntity()).thenReturn(portletEntity);
when(portletWindow.getWindowState()).thenReturn(WindowState.NORMAL);
when(portletWindow.getPortletMode()).thenReturn(PortletMode.VIEW);
when(portletEntity.getPortletDefinitionId()).thenReturn(portletDefinitionId);
when(portletDefinitionRegistry.getParentPortletDescriptor(portletDefinitionId)).thenReturn(portletDescriptor);
when(urlSyntaxProvider.getPortalRequestInfo(httpRequest)).thenReturn(portalRequestInfo);
when(this.urlSyntaxProvider.getPortalRequestInfo(httpRequest)).thenReturn(portalRequestInfo);
when(portalRequestInfo.getPortletRequestInfoMap()).thenReturn(Collections.EMPTY_MAP);
// Get the initial cache state
final CacheState<CachedPortletData<PortletRenderResult>, PortletRenderResult> firstCacheState = cacheControlService.getPortletRenderState(httpRequest, portletWindowId);
// Fake Render execution
final CacheControl cacheControl = firstCacheState.getCacheControl();
cacheControl.setExpirationTime(300);
final PortletRenderResult renderResult = new PortletRenderResult("title", null, 0, 1000l);
final String output = "{ \"hello\": \"world\" }";
final CachedPortletData<PortletRenderResult> cachedPortletData = new CachedPortletData<PortletRenderResult>(renderResult, output, null, null, false, cacheControl.getETag(), cacheControl.getExpirationTime());
firstCacheState.setCachedPortletData(cachedPortletData);
assertTrue(cacheControlService.shouldOutputBeCached(cacheControl));
// Cache the results
cacheControlService.cachePortletRenderOutput(portletWindowId, httpRequest, firstCacheState, cachedPortletData);
// Check the cached results
final CacheState<CachedPortletData<PortletRenderResult>, PortletRenderResult> secondCacheState = cacheControlService.getPortletRenderState(httpRequest, portletWindowId);
assertNotNull(secondCacheState);
final CachedPortletData<PortletRenderResult> actualCachedPortletData = secondCacheState.getCachedPortletData();
assertNotNull(actualCachedPortletData);
}
use of javax.portlet.CacheControl in project uPortal by Jasig.
the class PortletRendererImplTest method doRenderMarkupCaptureNegativeExpirationTime.
/**
* No cached data exists, but mock a {@link CacheControl} with a negative value for
* expirationtime. Will trigger the portletContainer#doRender, capture the output, and give to
* the portlet cachecontrol service.
*
* <p>negative value for cacheControl expiration time means "cache forever."
*
* @throws PortletException
* @throws IOException
* @throws PortletContainerException
*/
@Test
public void doRenderMarkupCaptureNegativeExpirationTime() throws PortletException, IOException, PortletContainerException {
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
TestingCacheState<CachedPortletData<PortletRenderResult>, PortletRenderResult> cacheState = new TestingCacheState<CachedPortletData<PortletRenderResult>, PortletRenderResult>();
CacheControl cacheControl = cacheState.getCacheControl();
cacheControl.setUseCachedContent(false);
cacheControl.setExpirationTime(-1);
setupPortletExecutionMocks(request);
when(portletCacheControlService.getPortletRenderState(request, portletWindowId)).thenReturn(cacheState);
when(portletCacheControlService.shouldOutputBeCached(cacheControl)).thenReturn(true);
when(portalRequestInfo.getTargetedPortletWindowId()).thenReturn(portletWindowId);
RenderPortletOutputHandler handler = new RenderPortletOutputHandler("UTF-8");
portletRenderer.doRenderMarkup(portletWindowId, request, response, handler);
verify(portletContainer, times(1)).doRender(eq(plutoPortletWindow), isA(PortletHttpServletRequestWrapper.class), isA(PortletHttpServletResponseWrapper.class));
verify(portletCacheControlService, times(1)).getPortletRenderState(request, portletWindowId);
verify(portletCacheControlService, times(1)).getCacheSizeThreshold();
verify(portletCacheControlService, times(1)).shouldOutputBeCached(cacheControl);
verify(portletCacheControlService, times(1)).cachePortletRenderOutput(eq(portletWindowId), isA(PortletHttpServletRequestWrapper.class), eq(cacheState), isA(CachedPortletData.class));
verifyNoMoreInteractions(portletContainer, portletCacheControlService);
}
use of javax.portlet.CacheControl in project uPortal by Jasig.
the class PortletRendererImplTest method doRenderMarkupCachedContentValidationMethodExpiredTest.
/**
* Mimic workflow when data cached portlet data using "validation" method is available.
*
* @throws PortletContainerException
* @throws IOException
* @throws PortletException
*/
@Test
public void doRenderMarkupCachedContentValidationMethodExpiredTest() throws PortletException, IOException, PortletContainerException {
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
TestingCacheState<CachedPortletData<PortletRenderResult>, PortletRenderResult> cacheState = new TestingCacheState<CachedPortletData<PortletRenderResult>, PortletRenderResult>();
CacheControl cacheControl = cacheState.getCacheControl();
// by setting useCachedContent to true, we are saying even though content is expired, replay
// it anyways (since etag is still valid)
cacheControl.setUseCachedContent(true);
cacheControl.setETag("123456");
cacheControl.setExpirationTime(300);
final PortletRenderResult portletResult = new PortletRenderResult("title", null, 0, 100);
final String output = "<p>Some content</p>";
CachedPortletData<PortletRenderResult> cachedPortletData = new CachedPortletData<PortletRenderResult>(portletResult, output, null, null, false, cacheControl.getETag(), 1);
cacheState.setCachedPortletData(cachedPortletData);
final long expTime = cachedPortletData.getExpirationTime();
setupPortletExecutionMocks(request);
when(portletCacheControlService.getPortletRenderState(request, portletWindowId)).thenReturn(cacheState);
when(portalRequestInfo.getTargetedPortletWindowId()).thenReturn(portletWindowId);
RenderPortletOutputHandler handler = new RenderPortletOutputHandler("UTF-8");
portletRenderer.doRenderMarkup(portletWindowId, request, response, handler);
Assert.assertEquals(output, handler.getOutput());
// verify the expiration time has been updated
Assert.assertNotSame(expTime, cachedPortletData.getTimeStored());
verify(portletCacheControlService, times(1)).getPortletRenderState(request, portletWindowId);
verify(portletCacheControlService, times(1)).getCacheSizeThreshold();
verify(portletContainer, times(1)).doRender(eq(plutoPortletWindow), isA(PortletHttpServletRequestWrapper.class), isA(PortletHttpServletResponseWrapper.class));
verify(portletCacheControlService, times(1)).cachePortletRenderOutput(eq(portletWindowId), isA(PortletHttpServletRequestWrapper.class), eq(cacheState), isA(CachedPortletData.class));
verifyNoMoreInteractions(portletContainer, portletCacheControlService);
}
use of javax.portlet.CacheControl in project uPortal by Jasig.
the class PortletRendererImplTest method doServeResourceCachedContentValidationMethodNotModifiedInternalCacheExpiredTest.
/**
* Same as {@link #doServeResourceCachedContentValidationMethodNotModifiedTest()}, however the
* CachedPortletData is older than it's expiration time. Verify the renderer still detects the
* etag and returns 304 not modified.
*
* @throws PortletException
* @throws IOException
* @throws PortletContainerException
*/
@Test
public void doServeResourceCachedContentValidationMethodNotModifiedInternalCacheExpiredTest() throws PortletException, IOException, PortletContainerException {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("If-None-Match", "123456");
MockHttpServletResponse response = new MockHttpServletResponse();
TestingCacheState<CachedPortletResourceData<Long>, Long> cacheState = new TestingCacheState<CachedPortletResourceData<Long>, Long>();
cacheState.setBrowserSetEtag(true);
CacheControl cacheControl = cacheState.getCacheControl();
cacheControl.setUseCachedContent(true);
cacheControl.setExpirationTime(300);
cacheControl.setETag("123456");
final String output = "{ \"hello\": \"world\" }";
final CachedPortletData<Long> cachedPortletData = new CachedPortletData<Long>(1000l, output, null, "application/json", false, cacheControl.getETag(), cacheControl.getExpirationTime());
final CachedPortletResourceData<Long> cachedPortletResourceData = new CachedPortletResourceData<Long>(cachedPortletData, Collections.EMPTY_MAP, null, null, null, null);
cacheState.setCachedPortletData(cachedPortletResourceData);
setupPortletExecutionMocks(request);
when(portletCacheControlService.getPortletResourceState(request, portletWindowId)).thenReturn(cacheState);
ResourcePortletOutputHandler handler = new ResourcePortletOutputHandler(response);
portletRenderer.doServeResource(portletWindowId, request, response, handler);
Assert.assertEquals(0, response.getContentLength());
Assert.assertEquals(304, response.getStatus());
verify(portletCacheControlService, times(1)).getPortletResourceState(request, portletWindowId);
verify(portletCacheControlService, times(1)).getCacheSizeThreshold();
verify(portletContainer, times(1)).doServeResource(eq(plutoPortletWindow), isA(PortletHttpServletRequestWrapper.class), isA(PortletResourceHttpServletResponseWrapper.class));
verify(portletCacheControlService).cachePortletResourceOutput(eq(portletWindowId), isA(PortletHttpServletRequestWrapper.class), eq(cacheState), eq(cachedPortletResourceData));
verifyNoMoreInteractions(portletContainer, portletCacheControlService);
}
Aggregations