Search in sources :

Example 1 with RenderCallback

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);
}
Also used : ContentWriter(org.alfresco.service.cmr.repository.ContentWriter) RetryingTransactionHelper(org.alfresco.repo.transaction.RetryingTransactionHelper) InputStream(java.io.InputStream) List(java.util.List) ArrayList(java.util.ArrayList) RenderCallback(org.alfresco.service.cmr.rendition.RenderCallback) RenditionDefinition(org.alfresco.service.cmr.rendition.RenditionDefinition) CompositeRenditionDefinition(org.alfresco.service.cmr.rendition.CompositeRenditionDefinition) ChildAssociationRef(org.alfresco.service.cmr.repository.ChildAssociationRef) BaseAlfrescoSpringTest(org.alfresco.util.BaseAlfrescoSpringTest) Test(org.junit.Test) AbstractContentTransformerTest(org.alfresco.repo.content.transform.AbstractContentTransformerTest)

Example 2 with RenderCallback

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;
        }
    });
}
Also used : RetryingTransactionHelper(org.alfresco.repo.transaction.RetryingTransactionHelper) QName(org.alfresco.service.namespace.QName) RenderCallback(org.alfresco.service.cmr.rendition.RenderCallback) ChildAssociationRef(org.alfresco.service.cmr.repository.ChildAssociationRef) UnimportantTransformException(org.alfresco.repo.content.transform.UnimportantTransformException) RenditionCancelledException(org.alfresco.service.cmr.rendition.RenditionCancelledException) RenditionServiceException(org.alfresco.service.cmr.rendition.RenditionServiceException) IOException(java.io.IOException) NodeRef(org.alfresco.service.cmr.repository.NodeRef) RetryingTransactionCallback(org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback) RenditionDefinition(org.alfresco.service.cmr.rendition.RenditionDefinition) CompositeRenditionDefinition(org.alfresco.service.cmr.rendition.CompositeRenditionDefinition) Pair(org.alfresco.util.Pair) BaseAlfrescoSpringTest(org.alfresco.util.BaseAlfrescoSpringTest) Test(org.junit.Test) AbstractContentTransformerTest(org.alfresco.repo.content.transform.AbstractContentTransformerTest)

Example 3 with RenderCallback

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
            }
        });
    }
}
Also used : Action(org.alfresco.service.cmr.action.Action) RenderCallback(org.alfresco.service.cmr.rendition.RenderCallback) ChildAssociationRef(org.alfresco.service.cmr.repository.ChildAssociationRef)

Example 4 with RenderCallback

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());
}
Also used : RenderCallback(org.alfresco.service.cmr.rendition.RenderCallback) CountDownLatch(java.util.concurrent.CountDownLatch) ChildAssociationRef(org.alfresco.service.cmr.repository.ChildAssociationRef) BaseAlfrescoSpringTest(org.alfresco.util.BaseAlfrescoSpringTest) Test(org.junit.Test) AbstractContentTransformerTest(org.alfresco.repo.content.transform.AbstractContentTransformerTest)

Example 5 with RenderCallback

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());
}
Also used : RenderCallback(org.alfresco.service.cmr.rendition.RenderCallback) CountDownLatch(java.util.concurrent.CountDownLatch) ChildAssociationRef(org.alfresco.service.cmr.repository.ChildAssociationRef) BaseAlfrescoSpringTest(org.alfresco.util.BaseAlfrescoSpringTest) Test(org.junit.Test) AbstractContentTransformerTest(org.alfresco.repo.content.transform.AbstractContentTransformerTest)

Aggregations

RenderCallback (org.alfresco.service.cmr.rendition.RenderCallback)5 ChildAssociationRef (org.alfresco.service.cmr.repository.ChildAssociationRef)5 AbstractContentTransformerTest (org.alfresco.repo.content.transform.AbstractContentTransformerTest)4 BaseAlfrescoSpringTest (org.alfresco.util.BaseAlfrescoSpringTest)4 Test (org.junit.Test)4 CountDownLatch (java.util.concurrent.CountDownLatch)2 RetryingTransactionHelper (org.alfresco.repo.transaction.RetryingTransactionHelper)2 CompositeRenditionDefinition (org.alfresco.service.cmr.rendition.CompositeRenditionDefinition)2 RenditionDefinition (org.alfresco.service.cmr.rendition.RenditionDefinition)2 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 UnimportantTransformException (org.alfresco.repo.content.transform.UnimportantTransformException)1 RetryingTransactionCallback (org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback)1 Action (org.alfresco.service.cmr.action.Action)1 RenditionCancelledException (org.alfresco.service.cmr.rendition.RenditionCancelledException)1 RenditionServiceException (org.alfresco.service.cmr.rendition.RenditionServiceException)1 ContentWriter (org.alfresco.service.cmr.repository.ContentWriter)1 NodeRef (org.alfresco.service.cmr.repository.NodeRef)1