use of org.alfresco.service.cmr.rendition.RenderCallback in project alfresco-repository by Alfresco.
the class RenditionServiceIntegrationTest method testRenderValidContentThenUpdateToInvalidContent.
/**
* This test checks that for a node with an existing rendition, that if you update its content with content
* that cannot be renditioned (thumbnailed), that existing rendition nodes for failed re-renditions are removed.
* See ALF-6730.
*
* @since 3.4.2
*/
@Test
public void testRenderValidContentThenUpdateToInvalidContent() throws Exception {
transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable {
// Need to use one of the standard, persisted rendition definitions, as non-persisted rendition definitions
// do not get automatcially updated.
RenditionDefinition doclib = loadAndValidateRenditionDefinition("doclib");
// We want the rendition to be asynchronous, but we don't care about called-back data.
RenderCallback dummyCallback = new RenderCallback() {
@Override
public void handleFailedRendition(Throwable t) {
}
@Override
public void handleSuccessfulRendition(ChildAssociationRef primaryParentOfNewRendition) {
}
};
renditionService.render(nodeWithDocContent, doclib, dummyCallback);
return null;
}
}, false, true);
// Now wait for the actionService thread to complete the rendering.
Thread.sleep(5000);
// The rendition should have succeeded.
transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable {
List<ChildAssociationRef> renditions = renditionService.getRenditions(nodeWithDocContent);
assertNotNull("Renditions missing.", renditions);
assertEquals("Wrong rendition count", 1, renditions.size());
return null;
}
}, false, true);
// Now update the content to a corrupt PDF file that cannot be rendered.
transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable {
ContentWriter writer = contentService.getWriter(nodeWithDocContent, ContentModel.PROP_CONTENT, true);
writer.setMimetype(MimetypeMap.MIMETYPE_PDF);
writer.setEncoding("UTF-8");
InputStream corruptIn = applicationContext.getResource("classpath:/quick/quickCorrupt.pdf").getInputStream();
writer.putContent(corruptIn);
corruptIn.close();
return null;
}
}, false, true);
// Now wait for the actionService thread to complete the rendition removal.
Thread.sleep(5000);
transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable {
List<ChildAssociationRef> renditions = renditionService.getRenditions(nodeWithDocContent);
assertNotNull("Renditions missing.", renditions);
assertEquals("Wrong rendition count", 0, renditions.size());
return null;
}
}, false, true);
}
use of org.alfresco.service.cmr.rendition.RenderCallback in project alfresco-repository by Alfresco.
the class RenditionServiceIntegrationTest method testRenderFreemarkerTemplatePath.
@Test
public void testRenderFreemarkerTemplatePath() throws Exception {
// TODO displayName paths.
final QName renditionName1 = QName.createQName(NamespaceService.RENDITION_MODEL_1_0_URI, FreemarkerRenderingEngine.NAME + "_UpdateOnAnyPropChange");
final QName renditionName2 = QName.createQName(NamespaceService.RENDITION_MODEL_1_0_URI, FreemarkerRenderingEngine.NAME + "_UpdateOnContentPropChange");
final Pair<NodeRef, NodeRef> renditions = transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Pair<NodeRef, NodeRef>>() {
public Pair<NodeRef, NodeRef> execute() throws Throwable {
ChildAssociationRef parentAssoc = nodeService.getPrimaryParent(nodeWithFreeMarkerContent);
QName assocName = parentAssoc.getQName();
String templatePath = "/app:company_home/" + assocName.toPrefixString(namespaceService);
// create test model 1 - rendition to update on any property change
RenditionDefinition definition1 = renditionService.createRenditionDefinition(renditionName1, FreemarkerRenderingEngine.NAME);
definition1.setParameterValue(FreemarkerRenderingEngine.PARAM_TEMPLATE_PATH, templatePath);
definition1.setParameterValue(AbstractRenderingEngine.PARAM_UPDATE_RENDITIONS_ON_ANY_PROPERTY_CHANGE, Boolean.TRUE);
// create test model 2 - rendition to update on content property change
RenditionDefinition definition2 = renditionService.createRenditionDefinition(renditionName2, FreemarkerRenderingEngine.NAME);
definition2.setParameterValue(FreemarkerRenderingEngine.PARAM_TEMPLATE_PATH, templatePath);
definition2.setParameterValue(AbstractRenderingEngine.PARAM_UPDATE_RENDITIONS_ON_ANY_PROPERTY_CHANGE, Boolean.FALSE);
// for automatic update.
if (null == renditionService.loadRenditionDefinition(renditionName1)) {
renditionService.saveRenditionDefinition(definition1);
}
if (null == renditionService.loadRenditionDefinition(renditionName2)) {
renditionService.saveRenditionDefinition(definition2);
}
ChildAssociationRef renditionAssoc1 = renditionService.render(nodeWithDocContent, definition1);
assertNotNull("The rendition association was null", renditionAssoc1);
ChildAssociationRef renditionAssoc2 = renditionService.render(nodeWithDocContent, definition2);
assertNotNull("The rendition association was null", renditionAssoc2);
Pair<NodeRef, NodeRef> result = new Pair<NodeRef, NodeRef>(renditionAssoc1.getChildRef(), renditionAssoc2.getChildRef());
return result;
}
});
final String titleInitialValue = "Original test title";
transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable {
assertEquals("The source node should have title " + titleInitialValue, titleInitialValue, nodeService.getProperty(nodeWithDocContent, ContentModel.PROP_TITLE));
String output1 = readTextContent(renditions.getFirst());
assertNotNull("The rendition content was null.", output1);
assertRenditionContainsTitle(titleInitialValue, output1);
// check the output contains root node Id as expected.
assertTrue(output1.contains(nodeWithDocContent.getId()));
String output2 = readTextContent(renditions.getSecond());
assertNotNull("The rendition content was null.", output2);
assertRenditionContainsTitle(titleInitialValue, output2);
return null;
}
});
// Now change some properties on the source node and ensure that the renditions
// are updated appropriately
final String updatedTitle = "updatedTitle";
transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable {
nodeService.setProperty(nodeWithDocContent, ContentModel.PROP_TITLE, updatedTitle);
return null;
}
});
RetryingTransactionCallback<Void> checkRenditionCallback = new RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable {
String output1 = readTextContent(renditions.getFirst());
assertNotNull("The rendition content was null.", output1);
assertRenditionContainsTitle(updatedTitle, output1);
String output2 = readTextContent(renditions.getSecond());
assertNotNull("The rendition content was null.", output2);
assertRenditionContainsTitle(titleInitialValue, output2);
return null;
}
};
// Sleep to let the asynchronous action queue perform the updates to the renditions.
int count = 0;
while (count < 60) {
count++;
Thread.sleep(1000L);
// Get the renditions and check their content for the new title
try {
transactionHelper.doInTransaction(checkRenditionCallback);
// Success
break;
} catch (Exception e) {
// Failure
if (count > 60) {
throw e;
}
}
}
transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Void>() {
public Void execute() throws Throwable {
renditionService.render(nodeWithDocContent, renditionName1, new RenderCallback() {
@Override
public void handleSuccessfulRendition(ChildAssociationRef primaryParentOfNewRendition) {
assertNotNull("The rendition association was null", primaryParentOfNewRendition);
}
@Override
public void handleFailedRendition(Throwable t) {
fail("No error should be thrown: " + t.getMessage());
}
});
return null;
}
});
}
use of org.alfresco.service.cmr.rendition.RenderCallback in project alfresco-repository by Alfresco.
the class RenditionedAspect method queueUpdate.
/**
* Queue the update to happen asynchronously
*
* @param sourceNodeRef node reference
*/
private void queueUpdate(final NodeRef sourceNodeRef, final RenditionDefinition rendDefn, final ChildAssociationRef renditionAssoc) {
if (logger.isDebugEnabled() && rendDefn != null) {
StringBuilder msg = new StringBuilder();
msg.append("Queueing rendition update for node ").append(sourceNodeRef).append(": ").append(rendDefn.getRenditionName());
logger.debug(msg.toString());
}
if (rendDefn != null && !renditionService.usingRenditionService2(sourceNodeRef, rendDefn)) {
Action deleteRendition = actionService.createAction(DeleteRenditionActionExecuter.NAME);
deleteRendition.setParameterValue(DeleteRenditionActionExecuter.PARAM_RENDITION_DEFINITION_NAME, rendDefn.getRenditionName());
rendDefn.setCompensatingAction(deleteRendition);
renditionService.render(sourceNodeRef, rendDefn, new RenderCallback() {
public void handleFailedRendition(Throwable t) {
// In the event of a failed re-rendition, we will delete the rendition node
if (logger.isDebugEnabled()) {
StringBuilder msg = new StringBuilder();
msg.append("Re-rendering of node ").append(sourceNodeRef).append(" with renditionDefinition ").append(rendDefn.getRenditionName()).append(" failed. Deleting defunct rendition. ").append("The following exception is shown for informational purposes only ").append("and does not affect operation of the system.");
logger.debug(msg.toString(), t);
}
}
public void handleSuccessfulRendition(ChildAssociationRef primaryParentOfNewRendition) {
// Intentionally empty
}
});
}
}
use of org.alfresco.service.cmr.rendition.RenderCallback in project alfresco-repository by Alfresco.
the class RenditionServiceIntegrationTest method testFailedAsynchronousRendition.
/**
* @throws Exception
* @see {@link #testSuccessfulAsynchronousRendition()}
*/
@Test
public void testFailedAsynchronousRendition() throws Exception {
// see comment in method above for explanation of the countdown latch.
final CountDownLatch latch = new CountDownLatch(1);
final AsyncResultsHolder results = new AsyncResultsHolder();
final RenderCallback callback = new RenderCallback() {
public void handleFailedRendition(Throwable t) {
results.setThrowable(t);
latch.countDown();
}
public void handleSuccessfulRendition(ChildAssociationRef primaryParentOfNewRendition) {
results.setMessage("Rendition succeeded unexpectedly.");
latch.countDown();
}
};
// We're performing the render on an invalid node. We expect this to fail.
performAsyncRendition(testTargetFolder, callback, latch, results);
assertNull(results.getAssoc());
assertEquals("Expected a UnimportantTransformException", UnimportantTransformException.class, results.getThrowable().getClass());
}
use of org.alfresco.service.cmr.rendition.RenderCallback in project alfresco-repository by Alfresco.
the class RenditionServiceIntegrationTest method testSuccessfulAsynchronousRendition.
@Test
public void testSuccessfulAsynchronousRendition() throws Exception {
// There are two relevant threads here: the JUnit test thread and the background
// asynchronousActionExecution thread. It is this second thread that will do
// the rendering work and I want to make sure that any failures on that thread
// are returned to the JUnit thread in order to fail the test.
// I also need to ensure that the asynchronous rendering is complete before
// asserting anything about the results.
// The countdown latch below is the mechanism by which the JUnit test code
// waits for the completion of the other thread.
final CountDownLatch latch = new CountDownLatch(1);
final AsyncResultsHolder results = new AsyncResultsHolder();
final RenderCallback callback = new RenderCallback() {
public void handleFailedRendition(Throwable t) {
results.setMessage("Rendition failed unexpectedly.");
latch.countDown();
}
public void handleSuccessfulRendition(ChildAssociationRef primaryParentOfNewRendition) {
results.setAssoc(primaryParentOfNewRendition);
latch.countDown();
}
};
// We're performing this on a valid piece of content.
// We expect this to succeed.
performAsyncRendition(nodeWithImageContent, callback, latch, results);
assertNotNull("ChildAssociationRef was null.", results.getAssoc());
// We'll simply assert that the association has the correct parent.
assertEquals(nodeWithImageContent, results.getAssoc().getParentRef());
assertNull(results.getThrowable());
}
Aggregations