diff --git a/pom.xml b/pom.xml index 24d23189b3..03b81d862e 100644 --- a/pom.xml +++ b/pom.xml @@ -38,7 +38,7 @@ 6.2 7.5 6.1 - 8.22 + 8.25 7.1 1.1 1.0.9 diff --git a/src/main/java/org/alfresco/repo/rendition/RenditionServiceImpl.java b/src/main/java/org/alfresco/repo/rendition/RenditionServiceImpl.java index 07b9f0e071..d631f18be9 100644 --- a/src/main/java/org/alfresco/repo/rendition/RenditionServiceImpl.java +++ b/src/main/java/org/alfresco/repo/rendition/RenditionServiceImpl.java @@ -271,14 +271,16 @@ public class RenditionServiceImpl implements public ChildAssociationRef render(NodeRef sourceNode, RenditionDefinition definition) { checkSourceNodeForPreventionClass(sourceNode); - + log.debug("Original RenditionService render no callback START"); + ChildAssociationRef result = executeRenditionAction(sourceNode, definition, false); if (log.isDebugEnabled()) { log.debug("Produced rendition " + result); } - + + log.debug("Original RenditionService render no callback END"); return result; } @@ -286,14 +288,14 @@ public class RenditionServiceImpl implements RenderCallback callback) { checkSourceNodeForPreventionClass(sourceNode); - + log.debug("Original RenditionService render callback START"); + // The asynchronous render can't return a ChildAssociationRef as it is created // asynchronously after this method returns. definition.setCallback(callback); executeRenditionAction(sourceNode, definition, true); - - return; + log.debug("Original RenditionService render callback END"); } /* diff --git a/src/main/java/org/alfresco/repo/rendition2/LegacyLocalTransformClient.java b/src/main/java/org/alfresco/repo/rendition2/LegacyLocalTransformClient.java index f7cc3a6733..dccfa89c70 100644 --- a/src/main/java/org/alfresco/repo/rendition2/LegacyLocalTransformClient.java +++ b/src/main/java/org/alfresco/repo/rendition2/LegacyLocalTransformClient.java @@ -128,7 +128,7 @@ public class LegacyLocalTransformClient extends AbstractTransformClient implemen } @Override - public void transform(NodeRef sourceNodeRef, RenditionDefinition2 renditionDefinition, String user, int sourceContentUrlHashCode) + public void transform(NodeRef sourceNodeRef, RenditionDefinition2 renditionDefinition, String user, int sourceContentHashCode) { executorService.submit(() -> { @@ -155,7 +155,7 @@ public class LegacyLocalTransformClient extends AbstractTransformClient implemen contentService.transform(reader, writer, transformationOptions); InputStream inputStream = writer.getReader().getContentInputStream(); - renditionService2.consume(sourceNodeRef, inputStream, renditionDefinition, sourceContentUrlHashCode); + renditionService2.consume(sourceNodeRef, inputStream, renditionDefinition, sourceContentHashCode); } catch (Exception e) { @@ -164,7 +164,7 @@ public class LegacyLocalTransformClient extends AbstractTransformClient implemen String renditionName = renditionDefinition.getRenditionName(); logger.debug("Rendition of "+renditionName+" failed", e); } - renditionService2.failure(sourceNodeRef, renditionDefinition, sourceContentUrlHashCode); + renditionService2.failure(sourceNodeRef, renditionDefinition, sourceContentHashCode); throw e; } return null; diff --git a/src/main/java/org/alfresco/repo/rendition2/RenditionService2Impl.java b/src/main/java/org/alfresco/repo/rendition2/RenditionService2Impl.java index d35a6a5bab..b166c9e494 100644 --- a/src/main/java/org/alfresco/repo/rendition2/RenditionService2Impl.java +++ b/src/main/java/org/alfresco/repo/rendition2/RenditionService2Impl.java @@ -61,9 +61,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; import static org.alfresco.model.ContentModel.PROP_CONTENT; -import static org.alfresco.model.RenditionModel.PROP_RENDITION_CONTENT_URL_HASH_CODE; +import static org.alfresco.model.RenditionModel.PROP_RENDITION_CONTENT_HASH_CODE; import static org.alfresco.service.namespace.QName.createQName; /** @@ -209,39 +210,68 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea logger.debug("Request transform for rendition " + renditionName + " on " +sourceNodeRef); } + AtomicBoolean supported = new AtomicBoolean(true); ContentData contentData = (ContentData) nodeService.getProperty(sourceNodeRef, ContentModel.PROP_CONTENT); if (contentData != null && contentData.getContentUrl() != null) { String contentUrl = contentData.getContentUrl(); String sourceMimetype = contentData.getMimetype(); long size = contentData.getSize(); - transformClient.checkSupported(sourceNodeRef, renditionDefinition, sourceMimetype, size, contentUrl); + try + { + transformClient.checkSupported(sourceNodeRef, renditionDefinition, sourceMimetype, size, contentUrl); + } + catch (UnsupportedOperationException e) + { + NodeRef renditionNode = getRenditionNode(sourceNodeRef, renditionName); + if (renditionNode == null) + { + throw e; + } + supported.set(false); + } } String user = AuthenticationUtil.getRunAsUser(); RetryingTransactionHelper.RetryingTransactionCallback callback = () -> { - // Avoid doing extra transforms that have already been done. - int sourceContentUrlHashCode = getSourceContentUrlHashCode(sourceNodeRef); - NodeRef renditionNode = getRenditionNode(sourceNodeRef, renditionName); - int renditionContentUrlHashCode = getRenditionContentUrlHashCode(renditionNode); - if (renditionContentUrlHashCode == sourceContentUrlHashCode) - { - throw new IllegalStateException("The rendition " + renditionName + " has already been created."); - } - - // If source node has content - if (sourceContentUrlHashCode != SOURCE_HAS_NO_CONTENT) - { - transformClient.transform(sourceNodeRef, renditionDefinition, user, sourceContentUrlHashCode); - } - else + int sourceContentHashCode = getSourceContentHashCode(sourceNodeRef); + if (!supported.get()) { if (logger.isDebugEnabled()) { - logger.debug("Rendition of "+renditionName+" had no content."); + logger.debug("Rendition of " + renditionName + " is no longer supported. " + + "The mimetype might have changed or the content is now too big."); + } + failure(sourceNodeRef, renditionDefinition, sourceContentHashCode); + } + else + { + // Avoid doing extra transforms that have already been done. + NodeRef renditionNode = getRenditionNode(sourceNodeRef, renditionName); + int renditionContentHashCode = getRenditionContentHashCode(renditionNode); + if (logger.isDebugEnabled()) + { + logger.debug("Render: Source " + sourceContentHashCode + " rendition " + renditionContentHashCode+ " hashCodes"); + } + if (renditionContentHashCode == sourceContentHashCode) + { + throw new IllegalStateException("The rendition " + renditionName + " has already been created."); + } + + // If source node has content + if (sourceContentHashCode != SOURCE_HAS_NO_CONTENT) + { + transformClient.transform(sourceNodeRef, renditionDefinition, user, sourceContentHashCode); + } + else + { + if (logger.isDebugEnabled()) + { + logger.debug("Rendition of " + renditionName + " had no content."); + } + failure(sourceNodeRef, renditionDefinition, sourceContentHashCode); } - failure(sourceNodeRef, renditionDefinition, sourceContentUrlHashCode); } return null; }; @@ -254,13 +284,13 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea } } - public void failure(NodeRef sourceNodeRef, RenditionDefinition2 renditionDefinition, int transformContentUrlHashCode) + public void failure(NodeRef sourceNodeRef, RenditionDefinition2 renditionDefinition, int transformContentHashCode) { // The original transaction may have already have failed AuthenticationUtil.runAsSystem((AuthenticationUtil.RunAsWork) () -> transactionService.getRetryingTransactionHelper().doInTransaction(() -> { - consume(sourceNodeRef, null, renditionDefinition, transformContentUrlHashCode); + consume(sourceNodeRef, null, renditionDefinition, transformContentHashCode); return null; }, false, true)); } @@ -271,12 +301,15 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea * If the transformInputStream is null, this is taken to be a transform failure. */ public void consume(NodeRef sourceNodeRef, InputStream transformInputStream, RenditionDefinition2 renditionDefinition, - int transformContentUrlHashCode) + int transformContentHashCode) { String renditionName = renditionDefinition.getRenditionName(); - int sourceContentUrlHashCode = getSourceContentUrlHashCode(sourceNodeRef); - - if (transformContentUrlHashCode != sourceContentUrlHashCode) + int sourceContentHashCode = getSourceContentHashCode(sourceNodeRef); + if (logger.isDebugEnabled()) + { + logger.debug("Consume: Source " + sourceContentHashCode + " and transform's source " + transformContentHashCode+" hashcodes"); + } + if (transformContentHashCode != sourceContentHashCode) { if (logger.isDebugEnabled()) { @@ -321,7 +354,11 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea logger.debug("Added rendition2 aspect to rendition " + renditionName + " on " + sourceNodeRef); } } - nodeService.setProperty(renditionNode, RenditionModel.PROP_RENDITION_CONTENT_URL_HASH_CODE, transformContentUrlHashCode); + if (logger.isDebugEnabled()) + { + logger.debug("Set rendition hashcode " + transformContentHashCode + " and ThumbnailLastModified for " + renditionName); + } + nodeService.setProperty(renditionNode, RenditionModel.PROP_RENDITION_CONTENT_HASH_CODE, transformContentHashCode); setThumbnailLastModified(sourceNodeRef, renditionName); if (transformInputStream != null) @@ -348,6 +385,11 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea if (content != null) { nodeService.removeProperty(renditionNode, PROP_CONTENT); + nodeService.removeProperty(renditionNode, PROP_RENDITION_CONTENT_HASH_CODE); + if (logger.isDebugEnabled()) + { + logger.debug("Cleared rendition content and hashcode"); + } } } @@ -445,16 +487,17 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea * Returns the hash code of the source node's content url. As transformations may be returned in a different * sequences to which they were requested, this is used work out if a rendition should be replaced. */ - private int getSourceContentUrlHashCode(NodeRef sourceNodeRef) + private int getSourceContentHashCode(NodeRef sourceNodeRef) { int hashCode = SOURCE_HAS_NO_CONTENT; ContentData contentData = DefaultTypeConverter.INSTANCE.convert(ContentData.class, nodeService.getProperty(sourceNodeRef, PROP_CONTENT)); if (contentData != null) { - String contentUrl = contentData.getContentUrl(); - if (contentUrl != null) + // Originally we used the contentData URL, but that is not enough if the mimetype changes. + String contentString = contentData.toString(); + if (contentString != null) { - hashCode = contentUrl.hashCode(); + hashCode = contentString.hashCode(); } } return hashCode; @@ -463,13 +506,19 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea /** * Returns the hash code of source node's content url on the rendition node (node may be null) if it does not exist. * Used work out if a rendition should be replaced. {@code -2} is returned if the rendition does not exist or was - * not created by RenditionService2. + * not created by RenditionService2. {@code -1} is returned if there was no source content or the rendition failed. */ - private int getRenditionContentUrlHashCode(NodeRef renditionNode) + private int getRenditionContentHashCode(NodeRef renditionNode) { - return renditionNode == null || !nodeService.hasAspect(renditionNode, RenditionModel.ASPECT_RENDITION2) - ? RENDITION2_DOES_NOT_EXIST - : (int)nodeService.getProperty(renditionNode, PROP_RENDITION_CONTENT_URL_HASH_CODE); + if ( renditionNode == null || !nodeService.hasAspect(renditionNode, RenditionModel.ASPECT_RENDITION2)) + { + return RENDITION2_DOES_NOT_EXIST; + } + + Serializable hashCode = nodeService.getProperty(renditionNode, PROP_RENDITION_CONTENT_HASH_CODE); + return hashCode == null + ? SOURCE_HAS_NO_CONTENT + : (int)hashCode; } private NodeRef getRenditionNode(NodeRef sourceNodeRef, String renditionName) @@ -567,7 +616,7 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea /** * Indicates if the rendition is available. Failed renditions (there was an error) don't have a contentUrl - * and out of date renditions or those still being created don't have a matching contentUrlHashCode. + * and out of date renditions or those still being created don't have a matching contentHashCode. */ public boolean isRenditionAvailable(NodeRef sourceNodeRef, NodeRef renditionNode) { @@ -581,9 +630,13 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea } else { - int sourceContentUrlHashCode = getSourceContentUrlHashCode(sourceNodeRef); - int renditionContentUrlHashCode = getRenditionContentUrlHashCode(renditionNode); - if (sourceContentUrlHashCode != renditionContentUrlHashCode) + int sourceContentHashCode = getSourceContentHashCode(sourceNodeRef); + int renditionContentHashCode = getRenditionContentHashCode(renditionNode); + if (logger.isDebugEnabled()) + { + logger.debug("isRenditionAvailable source " + sourceContentHashCode + " and rendition " + renditionContentHashCode+" hashcodes"); + } + if (sourceContentHashCode != renditionContentHashCode) { available = false; } diff --git a/src/main/java/org/alfresco/repo/rendition2/SwitchingTransformClient.java b/src/main/java/org/alfresco/repo/rendition2/SwitchingTransformClient.java index 51eb3d7e37..d1f66aba76 100644 --- a/src/main/java/org/alfresco/repo/rendition2/SwitchingTransformClient.java +++ b/src/main/java/org/alfresco/repo/rendition2/SwitchingTransformClient.java @@ -62,15 +62,15 @@ public class SwitchingTransformClient implements TransformClient } @Override - public void transform(NodeRef sourceNodeRef, RenditionDefinition2 renditionDefinition, String user, int sourceContentUrlHashCode) + public void transform(NodeRef sourceNodeRef, RenditionDefinition2 renditionDefinition, String user, int sourceContentHashCode) { if (usePrimary.get()) { - primary.transform(sourceNodeRef, renditionDefinition, user, sourceContentUrlHashCode); + primary.transform(sourceNodeRef, renditionDefinition, user, sourceContentHashCode); } else { - secondary.transform(sourceNodeRef, renditionDefinition, user, sourceContentUrlHashCode); + secondary.transform(sourceNodeRef, renditionDefinition, user, sourceContentHashCode); } } } diff --git a/src/main/java/org/alfresco/repo/rendition2/TransformClient.java b/src/main/java/org/alfresco/repo/rendition2/TransformClient.java index 7198a239bc..1b9c55574c 100644 --- a/src/main/java/org/alfresco/repo/rendition2/TransformClient.java +++ b/src/main/java/org/alfresco/repo/rendition2/TransformClient.java @@ -53,7 +53,7 @@ public interface TransformClient * @param sourceNodeRef the source node * @param renditionDefinition which rendition to perform * @param user that requested the transform. - * @param sourceContentUrlHashCode the hash code of the source node's content URL. Used to check the transform result + * @param sourceContentHashCode the hash code of the source node's content URL. Used to check the transform result */ - void transform(NodeRef sourceNodeRef, RenditionDefinition2 renditionDefinition, String user, int sourceContentUrlHashCode); + void transform(NodeRef sourceNodeRef, RenditionDefinition2 renditionDefinition, String user, int sourceContentHashCode); } diff --git a/src/test/java/org/alfresco/repo/rendition2/AbstractRenditionIntegrationTest.java b/src/test/java/org/alfresco/repo/rendition2/AbstractRenditionIntegrationTest.java index 7ce7a723cb..ee723fb257 100644 --- a/src/test/java/org/alfresco/repo/rendition2/AbstractRenditionIntegrationTest.java +++ b/src/test/java/org/alfresco/repo/rendition2/AbstractRenditionIntegrationTest.java @@ -153,7 +153,7 @@ public abstract class AbstractRenditionIntegrationTest extends BaseSpringTest { NodeRef sourceNodeRef = createSource(ADMIN, testFileName); render(ADMIN, sourceNodeRef, renditionName); - waitForRendition(ADMIN, sourceNodeRef, renditionName); + waitForRendition(ADMIN, sourceNodeRef, renditionName, true); if (!expectedToPass) { fail("The " + renditionName + " rendition should NOT be supported for " + testFileName); @@ -241,11 +241,11 @@ public abstract class AbstractRenditionIntegrationTest extends BaseSpringTest } // As a given user waitForRendition for a rendition to appear. Creates new transactions to do this. - protected NodeRef waitForRendition(String user, NodeRef sourceNodeRef, String renditionName) throws AssertionFailedError + protected NodeRef waitForRendition(String user, NodeRef sourceNodeRef, String renditionName, boolean shouldExist) throws AssertionFailedError { try { - return AuthenticationUtil.runAs(() -> waitForRendition(sourceNodeRef, renditionName), user); + return AuthenticationUtil.runAs(() -> waitForRendition(sourceNodeRef, renditionName, shouldExist), user); } catch (RuntimeException e) { @@ -259,7 +259,7 @@ public abstract class AbstractRenditionIntegrationTest extends BaseSpringTest } // As the current user waitForRendition for a rendition to appear. Creates new transactions to do this. - private NodeRef waitForRendition(NodeRef sourceNodeRef, String renditionName) throws InterruptedException + private NodeRef waitForRendition(NodeRef sourceNodeRef, String renditionName, boolean shouldExist) throws InterruptedException { long maxMillis = 10000; ChildAssociationRef assoc = null; @@ -275,8 +275,16 @@ public abstract class AbstractRenditionIntegrationTest extends BaseSpringTest logger.debug("RenditionService2.getRenditionByName(...) sleep "+i); sleep(1000); } - assertNotNull("Rendition " + renditionName + " failed", assoc); - return assoc.getChildRef(); + if (shouldExist) + { + assertNotNull("Rendition " + renditionName + " failed", assoc); + return assoc.getChildRef(); + } + else + { + assertNull("Rendition " + renditionName + " did not fail", assoc); + return null; + } } protected String getTestFileName(String sourceMimetype) throws FileNotFoundException diff --git a/src/test/java/org/alfresco/repo/rendition2/LegacyLocalTransformClientIntegrationTest.java b/src/test/java/org/alfresco/repo/rendition2/LegacyLocalTransformClientIntegrationTest.java index 46dfd671cf..09570b8421 100644 --- a/src/test/java/org/alfresco/repo/rendition2/LegacyLocalTransformClientIntegrationTest.java +++ b/src/test/java/org/alfresco/repo/rendition2/LegacyLocalTransformClientIntegrationTest.java @@ -137,10 +137,10 @@ public class LegacyLocalTransformClientIntegrationTest extends AbstractRendition // split into separate transactions as the client is async NodeRef sourceNode = transactionService.getRetryingTransactionHelper().doInTransaction(() -> createContentNodeFromQuickFile(testFileName)); - int sourceContentUrlHash = DefaultTypeConverter.INSTANCE.convert( + int sourceContentHashCode = DefaultTypeConverter.INSTANCE.convert( ContentData.class, nodeService.getProperty(sourceNode, PROP_CONTENT)) - .getContentUrl().hashCode(); + .toString().hashCode(); transactionService.getRetryingTransactionHelper().doInTransaction(() -> { RenditionDefinition2 renditionDefinition = @@ -149,7 +149,7 @@ public class LegacyLocalTransformClientIntegrationTest extends AbstractRendition sourceNode, renditionDefinition, AuthenticationUtil.getAdminUserName(), - sourceContentUrlHash); + sourceContentHashCode); return null; }); ChildAssociationRef childAssociationRef = null; diff --git a/src/test/java/org/alfresco/repo/rendition2/RenditionService2IntegrationTest.java b/src/test/java/org/alfresco/repo/rendition2/RenditionService2IntegrationTest.java index 44570ee624..8b538bd47d 100644 --- a/src/test/java/org/alfresco/repo/rendition2/RenditionService2IntegrationTest.java +++ b/src/test/java/org/alfresco/repo/rendition2/RenditionService2IntegrationTest.java @@ -25,36 +25,23 @@ */ package org.alfresco.repo.rendition2; -import java.util.List; - -import junit.framework.AssertionFailedError; import org.alfresco.model.ContentModel; import org.alfresco.model.RenditionModel; -import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.permissions.AccessDeniedException; -import org.alfresco.repo.thumbnail.ThumbnailRegistry; -import org.alfresco.service.cmr.rendition.RenditionService; import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.ContentWriter; +import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; -import org.alfresco.util.ApplicationContextHelper; -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.util.ResourceUtils; -import java.io.File; -import java.io.FileNotFoundException; +import java.util.List; -import static java.lang.Thread.sleep; import static org.alfresco.model.ContentModel.PROP_CONTENT; -import static org.alfresco.repo.content.MimetypeMap.EXTENSION_BINARY; +import static org.junit.Assert.assertNotEquals; /** * Integration tests for {@link RenditionService2} @@ -148,7 +135,7 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati { NodeRef sourceNodeRef = createSource(ADMIN, "quick.jpg"); render(ADMIN, sourceNodeRef, DOC_LIB); - waitForRendition(ADMIN, sourceNodeRef, DOC_LIB); + waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, true); } @Test @@ -156,30 +143,50 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati { NodeRef sourceNodeRef = createSource(ADMIN, "quick.jpg"); render(ADMIN, sourceNodeRef, DOC_LIB); - waitForRendition(ADMIN, sourceNodeRef, DOC_LIB); + waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, true); clearContent(ADMIN, sourceNodeRef); render(ADMIN, sourceNodeRef, DOC_LIB); ChildAssociationRef assoc = AuthenticationUtil.runAs(() -> renditionService2.getRenditionByName(sourceNodeRef, DOC_LIB), ADMIN); + waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, false); assertNull("There should be no rendition as there was no content", assoc); } @Test - public void changedSourceToNonNull() + public void changedSourceToNonNull() { NodeRef sourceNodeRef = createSource(ADMIN, "quick.jpg"); render(ADMIN, sourceNodeRef, DOC_LIB); - waitForRendition(ADMIN, sourceNodeRef, DOC_LIB); + NodeRef rendition1 = waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, true); + ContentData contentData1 = DefaultTypeConverter.INSTANCE.convert(ContentData.class, nodeService.getProperty(rendition1, PROP_CONTENT)); + + updateContent(ADMIN, sourceNodeRef, "quick.png"); + render(ADMIN, sourceNodeRef, DOC_LIB); + NodeRef rendition2 = waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, true); + ContentData contentData2 = DefaultTypeConverter.INSTANCE.convert(ContentData.class, nodeService.getProperty(rendition2, PROP_CONTENT)); + + assertEquals("The rendition node should not change", rendition1, rendition2); + assertNotEquals("The content should have change", contentData1.toString(), contentData2.toString()); + } + + @Test + public void changedSourceFromNull() + { + NodeRef sourceNodeRef = createSource(ADMIN, "quick.jpg"); + render(ADMIN, sourceNodeRef, DOC_LIB); + waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, true); clearContent(ADMIN, sourceNodeRef); render(ADMIN, sourceNodeRef, DOC_LIB); ChildAssociationRef assoc = AuthenticationUtil.runAs(() -> renditionService2.getRenditionByName(sourceNodeRef, DOC_LIB), ADMIN); + waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, false); assertNull("There should be no rendition as there was no content", assoc); updateContent(ADMIN, sourceNodeRef, "quick.png"); - waitForRendition(ADMIN, sourceNodeRef, DOC_LIB); + render(ADMIN, sourceNodeRef, DOC_LIB); + waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, true); } @Test @@ -188,7 +195,7 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati String userName = createRandomUser(); NodeRef sourceNodeRef = createSource(userName, "quick.jpg"); render(userName, sourceNodeRef, DOC_LIB); - NodeRef renditionNodeRef = waitForRendition(userName, sourceNodeRef, DOC_LIB); + NodeRef renditionNodeRef = waitForRendition(userName, sourceNodeRef, DOC_LIB, true); assertNotNull("The rendition was not generated for non-admin user", renditionNodeRef); } @@ -204,9 +211,9 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati return null; }); render(ownerUserName, sourceNodeRef, DOC_LIB); - NodeRef renditionNodeRef = waitForRendition(ownerUserName, sourceNodeRef, DOC_LIB); + NodeRef renditionNodeRef = waitForRendition(ownerUserName, sourceNodeRef, DOC_LIB, true); assertNotNull("The rendition is not visible for owner of source node", renditionNodeRef); - renditionNodeRef = waitForRendition(otherUserName, sourceNodeRef, DOC_LIB); + renditionNodeRef = waitForRendition(otherUserName, sourceNodeRef, DOC_LIB, true); assertNotNull("The rendition is not visible for non-owner user with read permissions", renditionNodeRef); assertEquals("The creator of the rendition is not correct", ownerUserName, nodeService.getProperty(sourceNodeRef, ContentModel.PROP_CREATOR)); @@ -224,9 +231,9 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati return null; }); render(otherUserName, sourceNodeRef, DOC_LIB); - NodeRef renditionNodeRef = waitForRendition(ownerUserName, sourceNodeRef, DOC_LIB); + NodeRef renditionNodeRef = waitForRendition(ownerUserName, sourceNodeRef, DOC_LIB, true); assertNotNull("The rendition is not visible for owner of source node", renditionNodeRef); - renditionNodeRef = waitForRendition(otherUserName, sourceNodeRef, DOC_LIB); + renditionNodeRef = waitForRendition(otherUserName, sourceNodeRef, DOC_LIB, true); assertNotNull("The rendition is not visible for owner of rendition node", renditionNodeRef); assertEquals("The creator of the rendition is not correct", ownerUserName, nodeService.getProperty(sourceNodeRef, ContentModel.PROP_CREATOR)); @@ -246,7 +253,7 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati }); try { - waitForRendition(noPermissionsUser, sourceNodeRef, DOC_LIB); + waitForRendition(noPermissionsUser, sourceNodeRef, DOC_LIB, true); fail("The rendition should not be visible for user with no permissions"); } catch (AccessDeniedException ade) @@ -272,7 +279,7 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati AuthenticationUtil.runAs(() -> nodeService.hasAspect(oldRendition, RenditionModel.ASPECT_RENDITION2), ownerUserName)); updateContent(ownerUserName, sourceNodeRef, "quick.png"); - NodeRef newRendition = waitForRendition(ownerUserName, sourceNodeRef, DOC_LIB); + NodeRef newRendition = waitForRendition(ownerUserName, sourceNodeRef, DOC_LIB, true); assertNotNull("The rendition should be reported via RenditionService2", newRendition); Thread.sleep(200); boolean hasRenditionedAspect = false; @@ -307,7 +314,7 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati .doInTransaction(() -> AuthenticationUtil.runAs(() -> renditionService.render(sourceNodeRef, doclibRendDefQName), ADMIN)); - assertNotNull("The old renditions service did not render", waitForRendition(ADMIN, sourceNodeRef, DOC_LIB)); + assertNotNull("The old renditions service did not render", waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, true)); List lastThumbnailModification = transactionService.getRetryingTransactionHelper() .doInTransaction(() -> AuthenticationUtil.runAs(() -> @@ -349,14 +356,14 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati { NodeRef sourceNodeRef = createSource(ADMIN, "quick.jpg"); render(ADMIN, sourceNodeRef, DOC_LIB); - waitForRendition(ADMIN, sourceNodeRef, DOC_LIB); + waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, true); renditionService2.setEnabled(false); try { updateContent(ADMIN, sourceNodeRef, "quick.png"); Thread.sleep(200); - NodeRef renditionNodeRef = waitForRendition(ADMIN, sourceNodeRef, DOC_LIB); + NodeRef renditionNodeRef = waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, true); boolean hasRendition2Aspect = true; for (int i = 0; i < 5; i++) { @@ -394,12 +401,12 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati .doInTransaction(() -> AuthenticationUtil.runAs(() -> renditionService.render(sourceNodeRef, doclibRendDefQName), ADMIN)); - waitForRendition(ADMIN, sourceNodeRef, DOC_LIB); + waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, true); renditionService2.setEnabled(true); updateContent(ADMIN, sourceNodeRef, "quick.png"); - NodeRef renditionNodeRef = waitForRendition(ADMIN, sourceNodeRef, DOC_LIB); + NodeRef renditionNodeRef = waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, true); boolean hasAspect = nodeService.hasAspect(renditionNodeRef, RenditionModel.ASPECT_RENDITION2); assertFalse("Should have switched to the old rendition service", hasAspect); } @@ -419,7 +426,7 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati String ownerUserName = createRandomUser(); NodeRef sourceNodeRef = createSource(ownerUserName, "quick.jpg"); render(ownerUserName, sourceNodeRef, DOC_LIB); - NodeRef newRendition = waitForRendition(ownerUserName, sourceNodeRef, DOC_LIB); + NodeRef newRendition = waitForRendition(ownerUserName, sourceNodeRef, DOC_LIB, true); boolean hasRendition2Aspect = AuthenticationUtil.runAs(() -> nodeService.hasAspect(newRendition, RenditionModel.ASPECT_RENDITION2), ownerUserName); assertTrue("The source should have the old renditioned aspect", AuthenticationUtil.runAs(() -> nodeService.hasAspect(sourceNodeRef, RenditionModel.ASPECT_RENDITIONED), ownerUserName)); @@ -428,7 +435,7 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati { renditionService2.setEnabled(false); updateContent(ownerUserName, sourceNodeRef, "quick.png"); - NodeRef oldRendition = waitForRendition(ownerUserName, sourceNodeRef, DOC_LIB); + NodeRef oldRendition = waitForRendition(ownerUserName, sourceNodeRef, DOC_LIB, true); Thread.sleep(200); hasRendition2Aspect = false; for (int i = 0; i < 5; i++) @@ -467,12 +474,12 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati .doInTransaction(() -> AuthenticationUtil.runAs(() -> renditionService.render(sourceNodeRef, doclibRendDefQName), ADMIN)); - waitForRendition(ADMIN, sourceNodeRef, DOC_LIB); + waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, true); renditionService2.setEnabled(true); render(ADMIN, sourceNodeRef, DOC_LIB); Thread.sleep(200); - NodeRef renditionNodeRef = waitForRendition(ADMIN, sourceNodeRef, DOC_LIB); + NodeRef renditionNodeRef = waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, true); boolean hasRendition2Aspect = false; for (int i = 0; i < 5; i++) { diff --git a/src/test/java/org/alfresco/repo/thumbnail/ThumbnailServiceImplParameterTest.java b/src/test/java/org/alfresco/repo/thumbnail/ThumbnailServiceImplParameterTest.java index 75925b03d1..986229613c 100644 --- a/src/test/java/org/alfresco/repo/thumbnail/ThumbnailServiceImplParameterTest.java +++ b/src/test/java/org/alfresco/repo/thumbnail/ThumbnailServiceImplParameterTest.java @@ -26,17 +26,6 @@ package org.alfresco.repo.thumbnail; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - import org.alfresco.model.ContentModel; import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.content.transform.magick.ImageResizeOptions; @@ -45,9 +34,9 @@ import org.alfresco.repo.rendition.MockedTestServiceRegistry; import org.alfresco.repo.rendition.RenditionServiceImpl; import org.alfresco.repo.rendition.executer.AbstractRenderingEngine; import org.alfresco.repo.rendition.executer.ImageRenderingEngine; +import org.alfresco.repo.rendition2.RenditionService2Impl; import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.TransactionServiceImpl; -import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.ActionService; import org.alfresco.service.cmr.rendition.RenditionDefinition; @@ -67,6 +56,18 @@ import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + /** * Thumbnail service implementation unit test * @@ -79,6 +80,7 @@ public class ThumbnailServiceImplParameterTest { // Mocked services. private ActionService mockActionService = mock(ActionService.class); + private RenditionService2Impl mockRenditionService2 = mock(RenditionService2Impl.class); // Real services - backed by mocked services. private RenditionServiceImpl renditionService; @@ -103,6 +105,8 @@ public class ThumbnailServiceImplParameterTest renditionService.setActionService(mockActionService); renditionService.setServiceRegistry(new MockedTestServiceRegistry()); + renditionService.setRenditionService2(mockRenditionService2); + when(mockRenditionService2.isCreatedByRenditionService2(any(), any())).thenReturn(false); ThumbnailServiceImpl thumbs = new ThumbnailServiceImpl() {