mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-10-01 14:41:46 +00:00
ACS-9991 Allow Content and Metadata extract even if thumbnails are di… (#3536)
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -25,6 +25,24 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.rendition2;
|
package org.alfresco.repo.rendition2;
|
||||||
|
|
||||||
|
import static org.alfresco.model.ContentModel.PROP_CONTENT;
|
||||||
|
import static org.alfresco.model.RenditionModel.PROP_RENDITION_CONTENT_HASH_CODE;
|
||||||
|
import static org.alfresco.service.namespace.QName.createQName;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.model.RenditionModel;
|
import org.alfresco.model.RenditionModel;
|
||||||
import org.alfresco.repo.content.ContentServicePolicies;
|
import org.alfresco.repo.content.ContentServicePolicies;
|
||||||
@@ -51,23 +69,6 @@ import org.alfresco.service.namespace.QName;
|
|||||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
import org.alfresco.util.PropertyCheck;
|
import org.alfresco.util.PropertyCheck;
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
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_HASH_CODE;
|
|
||||||
import static org.alfresco.service.namespace.QName.createQName;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Async Rendition service. Replaces the original deprecated RenditionService.
|
* The Async Rendition service. Replaces the original deprecated RenditionService.
|
||||||
@@ -80,11 +81,19 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
|||||||
|
|
||||||
public static final QName DEFAULT_RENDITION_CONTENT_PROP = ContentModel.PROP_CONTENT;
|
public static final QName DEFAULT_RENDITION_CONTENT_PROP = ContentModel.PROP_CONTENT;
|
||||||
public static final String DEFAULT_MIMETYPE = MimetypeMap.MIMETYPE_TEXT_PLAIN;
|
public static final String DEFAULT_MIMETYPE = MimetypeMap.MIMETYPE_TEXT_PLAIN;
|
||||||
|
public static final String MIMETYPE_METADATA_EXTRACT = "alfresco-metadata-extract";
|
||||||
|
public static final String MIMETYPE_METADATA_EMBED = "alfresco-metadata-embed";
|
||||||
public static final String DEFAULT_ENCODING = "UTF-8";
|
public static final String DEFAULT_ENCODING = "UTF-8";
|
||||||
|
|
||||||
public static final int SOURCE_HAS_NO_CONTENT = -1;
|
public static final int SOURCE_HAS_NO_CONTENT = -1;
|
||||||
public static final int RENDITION2_DOES_NOT_EXIST = -2;
|
public static final int RENDITION2_DOES_NOT_EXIST = -2;
|
||||||
|
|
||||||
|
// Allowed mimetypes to support text or metadata extract transforms when thumbnails are disabled.
|
||||||
|
private static final Set<String> ALLOWED_MIMETYPES = Set.of(
|
||||||
|
MimetypeMap.MIMETYPE_TEXT_PLAIN,
|
||||||
|
MIMETYPE_METADATA_EXTRACT,
|
||||||
|
MIMETYPE_METADATA_EMBED);
|
||||||
|
|
||||||
private static Log logger = LogFactory.getLog(RenditionService2Impl.class);
|
private static Log logger = LogFactory.getLog(RenditionService2Impl.class);
|
||||||
|
|
||||||
// As Async transforms and renditions are so similar, this class provides a way to provide the code that is different.
|
// As Async transforms and renditions are so similar, this class provides a way to provide the code that is different.
|
||||||
@@ -95,12 +104,10 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
|||||||
abstract RenditionDefinition2 getRenditionDefinition();
|
abstract RenditionDefinition2 getRenditionDefinition();
|
||||||
|
|
||||||
void handleUnsupported(UnsupportedOperationException e)
|
void handleUnsupported(UnsupportedOperationException e)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
void throwIllegalStateExceptionIfAlreadyDone(int sourceContentHashCode)
|
void throwIllegalStateExceptionIfAlreadyDone(int sourceContentHashCode)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private TransactionService transactionService;
|
private TransactionService transactionService;
|
||||||
@@ -217,8 +224,7 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
|||||||
@Override
|
@Override
|
||||||
public void transform(NodeRef sourceNodeRef, TransformDefinition transformDefinition)
|
public void transform(NodeRef sourceNodeRef, TransformDefinition transformDefinition)
|
||||||
{
|
{
|
||||||
requestAsyncTransformOrRendition(sourceNodeRef, new RenderOrTransformCallBack()
|
requestAsyncTransformOrRendition(sourceNodeRef, new RenderOrTransformCallBack() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public String getName()
|
public String getName()
|
||||||
{
|
{
|
||||||
@@ -237,8 +243,7 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
|||||||
@Override
|
@Override
|
||||||
public void render(NodeRef sourceNodeRef, String renditionName)
|
public void render(NodeRef sourceNodeRef, String renditionName)
|
||||||
{
|
{
|
||||||
requestAsyncTransformOrRendition(sourceNodeRef, new RenderOrTransformCallBack()
|
requestAsyncTransformOrRendition(sourceNodeRef, new RenderOrTransformCallBack() {
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public String getName()
|
public String getName()
|
||||||
{
|
{
|
||||||
@@ -291,7 +296,7 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!isEnabled())
|
if (!isAsyncAllowed(renderOrTransform))
|
||||||
{
|
{
|
||||||
throw new RenditionService2Exception("Async transforms and renditions are disabled " +
|
throw new RenditionService2Exception("Async transforms and renditions are disabled " +
|
||||||
"(system.thumbnail.generate=false or renditionService2.enabled=false).");
|
"(system.thumbnail.generate=false or renditionService2.enabled=false).");
|
||||||
@@ -328,8 +333,7 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
|||||||
}
|
}
|
||||||
|
|
||||||
String user = AuthenticationUtil.getRunAsUser();
|
String user = AuthenticationUtil.getRunAsUser();
|
||||||
RetryingTransactionHelper.RetryingTransactionCallback callback = () ->
|
RetryingTransactionHelper.RetryingTransactionCallback callback = () -> {
|
||||||
{
|
|
||||||
int sourceContentHashCode = getSourceContentHashCode(sourceNodeRef);
|
int sourceContentHashCode = getSourceContentHashCode(sourceNodeRef);
|
||||||
if (!supported.get())
|
if (!supported.get())
|
||||||
{
|
{
|
||||||
@@ -372,9 +376,7 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
|||||||
public void failure(NodeRef sourceNodeRef, RenditionDefinition2 renditionDefinition, int transformContentHashCode)
|
public void failure(NodeRef sourceNodeRef, RenditionDefinition2 renditionDefinition, int transformContentHashCode)
|
||||||
{
|
{
|
||||||
// The original transaction may have already have failed
|
// The original transaction may have already have failed
|
||||||
AuthenticationUtil.runAsSystem((AuthenticationUtil.RunAsWork<Void>) () ->
|
AuthenticationUtil.runAsSystem((AuthenticationUtil.RunAsWork<Void>) () -> transactionService.getRetryingTransactionHelper().doInTransaction(() -> {
|
||||||
transactionService.getRetryingTransactionHelper().doInTransaction(() ->
|
|
||||||
{
|
|
||||||
consume(sourceNodeRef, null, renditionDefinition, transformContentHashCode);
|
consume(sourceNodeRef, null, renditionDefinition, transformContentHashCode);
|
||||||
return null;
|
return null;
|
||||||
}, false, true));
|
}, false, true));
|
||||||
@@ -484,9 +486,7 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes a transformation (InputStream) and attaches it as a rendition to the source node.
|
* Takes a transformation (InputStream) and attaches it as a rendition to the source node. Does nothing if there is already a newer rendition. If the transformInputStream is null, this is taken to be a transform failure.
|
||||||
* Does nothing if there is already a newer rendition.
|
|
||||||
* If the transformInputStream is null, this is taken to be a transform failure.
|
|
||||||
*/
|
*/
|
||||||
private void consumeRendition(NodeRef sourceNodeRef, int sourceContentHashCode, InputStream transformInputStream,
|
private void consumeRendition(NodeRef sourceNodeRef, int sourceContentHashCode, InputStream transformInputStream,
|
||||||
RenditionDefinition2 renditionDefinition, int transformContentHashCode)
|
RenditionDefinition2 renditionDefinition, int transformContentHashCode)
|
||||||
@@ -507,9 +507,7 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
|||||||
(transformInputStream == null ? " to null as the transform failed" : " to the transform result"));
|
(transformInputStream == null ? " to null as the transform failed" : " to the transform result"));
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthenticationUtil.runAsSystem((AuthenticationUtil.RunAsWork<Void>) () ->
|
AuthenticationUtil.runAsSystem((AuthenticationUtil.RunAsWork<Void>) () -> transactionService.getRetryingTransactionHelper().doInTransaction(() -> {
|
||||||
transactionService.getRetryingTransactionHelper().doInTransaction(() ->
|
|
||||||
{
|
|
||||||
// Ensure that the creation of a rendition does not cause updates to the modified, modifier properties on the source node
|
// Ensure that the creation of a rendition does not cause updates to the modified, modifier properties on the source node
|
||||||
NodeRef renditionNode = getRenditionNode(sourceNodeRef, renditionName);
|
NodeRef renditionNode = getRenditionNode(sourceNodeRef, renditionName);
|
||||||
boolean createRenditionNode = renditionNode == null;
|
boolean createRenditionNode = renditionNode == null;
|
||||||
@@ -555,7 +553,8 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
|||||||
long sizeOfRendition = contentReader.getSize();
|
long sizeOfRendition = contentReader.getSize();
|
||||||
if (sizeOfRendition > 0L)
|
if (sizeOfRendition > 0L)
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
logger.debug("Set rendition hashcode for " + renditionName);
|
logger.debug("Set rendition hashcode for " + renditionName);
|
||||||
}
|
}
|
||||||
nodeService.setProperty(renditionNode, RenditionModel.PROP_RENDITION_CONTENT_HASH_CODE, transformContentHashCode);
|
nodeService.setProperty(renditionNode, RenditionModel.PROP_RENDITION_CONTENT_HASH_CODE, transformContentHashCode);
|
||||||
@@ -665,8 +664,7 @@ 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
|
* 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.
|
||||||
* sequences to which they were requested, this is used work out if a rendition should be replaced.
|
|
||||||
*/
|
*/
|
||||||
private int getSourceContentHashCode(NodeRef sourceNodeRef)
|
private int getSourceContentHashCode(NodeRef sourceNodeRef)
|
||||||
{
|
{
|
||||||
@@ -685,9 +683,7 @@ 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.
|
* 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. {@code -1} is returned if there was no source content or the rendition failed.
|
||||||
* 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. {@code -1} is returned if there was no source content or the rendition failed.
|
|
||||||
*/
|
*/
|
||||||
private int getRenditionContentHashCode(NodeRef renditionNode)
|
private int getRenditionContentHashCode(NodeRef renditionNode)
|
||||||
{
|
{
|
||||||
@@ -773,11 +769,12 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method checks whether the specified source node is of a content class which has been registered for
|
* This method checks whether the specified source node is of a content class which has been registered for rendition prevention.
|
||||||
* rendition prevention.
|
|
||||||
*
|
*
|
||||||
* @param sourceNode the node to check.
|
* @param sourceNode
|
||||||
* @throws RenditionService2PreventedException if the source node is configured for rendition prevention.
|
* the node to check.
|
||||||
|
* @throws RenditionService2PreventedException
|
||||||
|
* if the source node is configured for rendition prevention.
|
||||||
*/
|
*/
|
||||||
// This code is based on the old RenditionServiceImpl.checkSourceNodeForPreventionClass(...)
|
// This code is based on the old RenditionServiceImpl.checkSourceNodeForPreventionClass(...)
|
||||||
private void checkSourceNodeForPreventionClass(NodeRef sourceNode)
|
private void checkSourceNodeForPreventionClass(NodeRef sourceNode)
|
||||||
@@ -833,8 +830,7 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates if the rendition is available. Failed renditions (there was an error) don't have a contentUrl
|
* 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 contentHashCode.
|
||||||
* and out of date renditions or those still being created don't have a matching contentHashCode.
|
|
||||||
*/
|
*/
|
||||||
public boolean isRenditionAvailable(NodeRef sourceNodeRef, NodeRef renditionNode)
|
public boolean isRenditionAvailable(NodeRef sourceNodeRef, NodeRef renditionNode)
|
||||||
{
|
{
|
||||||
@@ -899,9 +895,7 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
|||||||
@Override
|
@Override
|
||||||
public void clearRenditionContentDataInTransaction(NodeRef renditionNode)
|
public void clearRenditionContentDataInTransaction(NodeRef renditionNode)
|
||||||
{
|
{
|
||||||
AuthenticationUtil.runAsSystem((AuthenticationUtil.RunAsWork<Void>) () ->
|
AuthenticationUtil.runAsSystem((AuthenticationUtil.RunAsWork<Void>) () -> transactionService.getRetryingTransactionHelper().doInTransaction(() -> {
|
||||||
transactionService.getRetryingTransactionHelper().doInTransaction(() ->
|
|
||||||
{
|
|
||||||
clearRenditionContentData(renditionNode);
|
clearRenditionContentData(renditionNode);
|
||||||
return null;
|
return null;
|
||||||
}, false, true));
|
}, false, true));
|
||||||
@@ -950,4 +944,23 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checks if the given transform callback is a text extract transform for content indexing or metadata extract/embed.
|
||||||
|
private boolean isTextOrMetadataExtractTransform(RenderOrTransformCallBack renderOrTransform)
|
||||||
|
{
|
||||||
|
RenditionDefinition2 renditionDefinition = renderOrTransform.getRenditionDefinition();
|
||||||
|
return renditionDefinition != null && ALLOWED_MIMETYPES.contains(renditionDefinition.getTargetMimetype());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAsyncAllowed(RenderOrTransformCallBack renderOrTransform)
|
||||||
|
{
|
||||||
|
// If enabled is false, all async transforms/renditions must be blocked
|
||||||
|
if (!enabled)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If thumbnails are disabled, allow only text extract or metadata extract/embed transforms
|
||||||
|
return thumbnailsEnabled || isTextOrMetadataExtractTransform(renderOrTransform);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -25,16 +25,21 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.rendition2;
|
package org.alfresco.repo.rendition2;
|
||||||
|
|
||||||
import static org.alfresco.model.ContentModel.PROP_CONTENT;
|
|
||||||
import static org.junit.Assert.assertNotEquals;
|
import static org.junit.Assert.assertNotEquals;
|
||||||
|
|
||||||
|
import static org.alfresco.model.ContentModel.PROP_CONTENT;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.model.RenditionModel;
|
import org.alfresco.model.RenditionModel;
|
||||||
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
@@ -44,8 +49,6 @@ import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
|||||||
import org.alfresco.service.cmr.security.PermissionService;
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Integration tests for {@link RenditionService2}
|
* Integration tests for {@link RenditionService2}
|
||||||
@@ -158,8 +161,7 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati
|
|||||||
|
|
||||||
clearContent(ADMIN, sourceNodeRef);
|
clearContent(ADMIN, sourceNodeRef);
|
||||||
render(ADMIN, sourceNodeRef, DOC_LIB);
|
render(ADMIN, sourceNodeRef, DOC_LIB);
|
||||||
ChildAssociationRef assoc = AuthenticationUtil.runAs(() ->
|
ChildAssociationRef assoc = AuthenticationUtil.runAs(() -> renditionService2.getRenditionByName(sourceNodeRef, DOC_LIB), ADMIN);
|
||||||
renditionService2.getRenditionByName(sourceNodeRef, DOC_LIB), ADMIN);
|
|
||||||
waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, false);
|
waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, false);
|
||||||
assertNull("There should be no rendition as there was no content", assoc);
|
assertNull("There should be no rendition as there was no content", assoc);
|
||||||
}
|
}
|
||||||
@@ -190,8 +192,7 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati
|
|||||||
|
|
||||||
clearContent(ADMIN, sourceNodeRef);
|
clearContent(ADMIN, sourceNodeRef);
|
||||||
render(ADMIN, sourceNodeRef, DOC_LIB);
|
render(ADMIN, sourceNodeRef, DOC_LIB);
|
||||||
ChildAssociationRef assoc = AuthenticationUtil.runAs(() ->
|
ChildAssociationRef assoc = AuthenticationUtil.runAs(() -> renditionService2.getRenditionByName(sourceNodeRef, DOC_LIB), ADMIN);
|
||||||
renditionService2.getRenditionByName(sourceNodeRef, DOC_LIB), ADMIN);
|
|
||||||
waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, false);
|
waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, false);
|
||||||
assertNull("There should be no rendition as there was no content", assoc);
|
assertNull("There should be no rendition as there was no content", assoc);
|
||||||
|
|
||||||
@@ -216,8 +217,7 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati
|
|||||||
String ownerUserName = createRandomUser();
|
String ownerUserName = createRandomUser();
|
||||||
NodeRef sourceNodeRef = createSource(ownerUserName, "quick.jpg");
|
NodeRef sourceNodeRef = createSource(ownerUserName, "quick.jpg");
|
||||||
String otherUserName = createRandomUser();
|
String otherUserName = createRandomUser();
|
||||||
transactionService.getRetryingTransactionHelper().doInTransaction(() ->
|
transactionService.getRetryingTransactionHelper().doInTransaction(() -> {
|
||||||
{
|
|
||||||
permissionService.setPermission(sourceNodeRef, otherUserName, PermissionService.READ, true);
|
permissionService.setPermission(sourceNodeRef, otherUserName, PermissionService.READ, true);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
@@ -236,8 +236,7 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati
|
|||||||
String ownerUserName = createRandomUser();
|
String ownerUserName = createRandomUser();
|
||||||
NodeRef sourceNodeRef = createSource(ownerUserName, "quick.jpg");
|
NodeRef sourceNodeRef = createSource(ownerUserName, "quick.jpg");
|
||||||
String otherUserName = createRandomUser();
|
String otherUserName = createRandomUser();
|
||||||
transactionService.getRetryingTransactionHelper().doInTransaction(() ->
|
transactionService.getRetryingTransactionHelper().doInTransaction(() -> {
|
||||||
{
|
|
||||||
permissionService.setPermission(sourceNodeRef, otherUserName, PermissionService.READ, true);
|
permissionService.setPermission(sourceNodeRef, otherUserName, PermissionService.READ, true);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
@@ -257,8 +256,7 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati
|
|||||||
NodeRef sourceNodeRef = createSource(ownerUserName, "quick.jpg");
|
NodeRef sourceNodeRef = createSource(ownerUserName, "quick.jpg");
|
||||||
render(ownerUserName, sourceNodeRef, DOC_LIB);
|
render(ownerUserName, sourceNodeRef, DOC_LIB);
|
||||||
String noPermissionsUser = createRandomUser();
|
String noPermissionsUser = createRandomUser();
|
||||||
transactionService.getRetryingTransactionHelper().doInTransaction(() ->
|
transactionService.getRetryingTransactionHelper().doInTransaction(() -> {
|
||||||
{
|
|
||||||
permissionService.setPermission(sourceNodeRef, noPermissionsUser, PermissionService.ALL_PERMISSIONS, false);
|
permissionService.setPermission(sourceNodeRef, noPermissionsUser, PermissionService.ALL_PERMISSIONS, false);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
@@ -280,12 +278,9 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati
|
|||||||
NodeRef sourceNodeRef = createSource(ownerUserName, "quick.jpg");
|
NodeRef sourceNodeRef = createSource(ownerUserName, "quick.jpg");
|
||||||
final QName doclibRendDefQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "doclib");
|
final QName doclibRendDefQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "doclib");
|
||||||
transactionService.getRetryingTransactionHelper()
|
transactionService.getRetryingTransactionHelper()
|
||||||
.doInTransaction(() ->
|
.doInTransaction(() -> AuthenticationUtil.runAs(() -> renditionService.render(sourceNodeRef, doclibRendDefQName), ownerUserName));
|
||||||
AuthenticationUtil.runAs(() ->
|
|
||||||
renditionService.render(sourceNodeRef, doclibRendDefQName), ownerUserName));
|
|
||||||
|
|
||||||
NodeRef oldRendition = AuthenticationUtil.runAs(() ->
|
NodeRef oldRendition = AuthenticationUtil.runAs(() -> renditionService.getRenditionByName(sourceNodeRef, doclibRendDefQName).getChildRef(), ownerUserName);
|
||||||
renditionService.getRenditionByName(sourceNodeRef, doclibRendDefQName).getChildRef(), ownerUserName);
|
|
||||||
assertFalse("The rendition should be generated by old Rendition Service",
|
assertFalse("The rendition should be generated by old Rendition Service",
|
||||||
AuthenticationUtil.runAs(() -> nodeService.hasAspect(oldRendition, RenditionModel.ASPECT_RENDITION2), ownerUserName));
|
AuthenticationUtil.runAs(() -> nodeService.hasAspect(oldRendition, RenditionModel.ASPECT_RENDITION2), ownerUserName));
|
||||||
|
|
||||||
@@ -335,9 +330,7 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati
|
|||||||
renditionService2.setEnabled(false);
|
renditionService2.setEnabled(false);
|
||||||
|
|
||||||
// Call 'clearRenditionContentData' method directly to prove rendition content will be cleaned
|
// Call 'clearRenditionContentData' method directly to prove rendition content will be cleaned
|
||||||
AuthenticationUtil.runAs((AuthenticationUtil.RunAsWork<Void>) () ->
|
AuthenticationUtil.runAs((AuthenticationUtil.RunAsWork<Void>) () -> transactionService.getRetryingTransactionHelper().doInTransaction(() -> {
|
||||||
transactionService.getRetryingTransactionHelper().doInTransaction(() ->
|
|
||||||
{
|
|
||||||
renditionService2.clearRenditionContentData(sourceNodeRef, DOC_LIB);
|
renditionService2.clearRenditionContentData(sourceNodeRef, DOC_LIB);
|
||||||
return null;
|
return null;
|
||||||
}), ADMIN);
|
}), ADMIN);
|
||||||
@@ -356,8 +349,7 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati
|
|||||||
/**
|
/**
|
||||||
* Tests if a rendition without content (but with contentHashCode) can be generated again.
|
* Tests if a rendition without content (but with contentHashCode) can be generated again.
|
||||||
* <p>
|
* <p>
|
||||||
* If the rendition consumption receives a null InputStream, the contentHashCode should be cleaned from the
|
* If the rendition consumption receives a null InputStream, the contentHashCode should be cleaned from the rendition node, allowing new requests to generate the rendition.
|
||||||
* rendition node, allowing new requests to generate the rendition.
|
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@@ -369,8 +361,7 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati
|
|||||||
/**
|
/**
|
||||||
* Tests if a rendition without content (but with contentHashCode) can be generated again.
|
* Tests if a rendition without content (but with contentHashCode) can be generated again.
|
||||||
* <p>
|
* <p>
|
||||||
* If the rendition consumption receives a zero length InputStream, the contentHashCode should be cleaned from the
|
* If the rendition consumption receives a zero length InputStream, the contentHashCode should be cleaned from the rendition node, allowing new requests to generate the rendition.
|
||||||
* rendition node, allowing new requests to generate the rendition.
|
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@@ -492,22 +483,16 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati
|
|||||||
NodeRef sourceNodeRef = createSource(ADMIN, "quick.jpg");
|
NodeRef sourceNodeRef = createSource(ADMIN, "quick.jpg");
|
||||||
final QName doclibRendDefQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "doclib");
|
final QName doclibRendDefQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "doclib");
|
||||||
transactionService.getRetryingTransactionHelper()
|
transactionService.getRetryingTransactionHelper()
|
||||||
.doInTransaction(() ->
|
.doInTransaction(() -> AuthenticationUtil.runAs(() -> renditionService.render(sourceNodeRef, doclibRendDefQName), ADMIN));
|
||||||
AuthenticationUtil.runAs(() ->
|
|
||||||
renditionService.render(sourceNodeRef, doclibRendDefQName), ADMIN));
|
|
||||||
assertNotNull("The old renditions service did not render", waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, true));
|
assertNotNull("The old renditions service did not render", waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, true));
|
||||||
List<String> lastThumbnailModification = transactionService.getRetryingTransactionHelper()
|
List<String> lastThumbnailModification = transactionService.getRetryingTransactionHelper()
|
||||||
.doInTransaction(() ->
|
.doInTransaction(() -> AuthenticationUtil.runAs(() -> (List<String>) nodeService.getProperty(sourceNodeRef, ContentModel.PROP_LAST_THUMBNAIL_MODIFICATION_DATA), ADMIN));
|
||||||
AuthenticationUtil.runAs(() ->
|
|
||||||
(List<String>) nodeService.getProperty(sourceNodeRef, ContentModel.PROP_LAST_THUMBNAIL_MODIFICATION_DATA), ADMIN));
|
|
||||||
updateContent(ADMIN, sourceNodeRef, "quick.png");
|
updateContent(ADMIN, sourceNodeRef, "quick.png");
|
||||||
List<String> newThumbnailModification = null;
|
List<String> newThumbnailModification = null;
|
||||||
for (int i = 0; i < 5; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
newThumbnailModification = transactionService.getRetryingTransactionHelper()
|
newThumbnailModification = transactionService.getRetryingTransactionHelper()
|
||||||
.doInTransaction(() ->
|
.doInTransaction(() -> AuthenticationUtil.runAs(() -> (List<String>) nodeService.getProperty(sourceNodeRef, ContentModel.PROP_LAST_THUMBNAIL_MODIFICATION_DATA), ADMIN));
|
||||||
AuthenticationUtil.runAs(() ->
|
|
||||||
(List<String>) nodeService.getProperty(sourceNodeRef, ContentModel.PROP_LAST_THUMBNAIL_MODIFICATION_DATA), ADMIN));
|
|
||||||
if (!newThumbnailModification.equals(lastThumbnailModification))
|
if (!newThumbnailModification.equals(lastThumbnailModification))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@@ -579,9 +564,7 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati
|
|||||||
NodeRef sourceNodeRef = createSource(ADMIN, "quick.jpg");
|
NodeRef sourceNodeRef = createSource(ADMIN, "quick.jpg");
|
||||||
final QName doclibRendDefQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "doclib");
|
final QName doclibRendDefQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "doclib");
|
||||||
transactionService.getRetryingTransactionHelper()
|
transactionService.getRetryingTransactionHelper()
|
||||||
.doInTransaction(() ->
|
.doInTransaction(() -> AuthenticationUtil.runAs(() -> renditionService.render(sourceNodeRef, doclibRendDefQName), ADMIN));
|
||||||
AuthenticationUtil.runAs(() ->
|
|
||||||
renditionService.render(sourceNodeRef, doclibRendDefQName), ADMIN));
|
|
||||||
waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, true);
|
waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, true);
|
||||||
|
|
||||||
renditionService2.setEnabled(true);
|
renditionService2.setEnabled(true);
|
||||||
@@ -652,9 +635,7 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati
|
|||||||
NodeRef sourceNodeRef = createSource(ADMIN, "quick.jpg");
|
NodeRef sourceNodeRef = createSource(ADMIN, "quick.jpg");
|
||||||
final QName doclibRendDefQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "doclib");
|
final QName doclibRendDefQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "doclib");
|
||||||
transactionService.getRetryingTransactionHelper()
|
transactionService.getRetryingTransactionHelper()
|
||||||
.doInTransaction(() ->
|
.doInTransaction(() -> AuthenticationUtil.runAs(() -> renditionService.render(sourceNodeRef, doclibRendDefQName), ADMIN));
|
||||||
AuthenticationUtil.runAs(() ->
|
|
||||||
renditionService.render(sourceNodeRef, doclibRendDefQName), ADMIN));
|
|
||||||
waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, true);
|
waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, true);
|
||||||
|
|
||||||
renditionService2.setEnabled(true);
|
renditionService2.setEnabled(true);
|
||||||
@@ -682,4 +663,57 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati
|
|||||||
renditionService2.setEnabled(true);
|
renditionService2.setEnabled(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTextExtractTransformAllowedWhenThumbnailDisabled()
|
||||||
|
{
|
||||||
|
// create a source node
|
||||||
|
NodeRef sourceNodeRef = createSource(ADMIN, "quick.pdf");
|
||||||
|
assertNotNull("Node not generated", sourceNodeRef);
|
||||||
|
String replyQueue = "org.test.queue";
|
||||||
|
String targetMimetype = MimetypeMap.MIMETYPE_TEXT_PLAIN;
|
||||||
|
|
||||||
|
TransformDefinition textExtractTransform = new TransformDefinition(
|
||||||
|
targetMimetype,
|
||||||
|
java.util.Collections.emptyMap(),
|
||||||
|
"clientData",
|
||||||
|
replyQueue,
|
||||||
|
"requestId");
|
||||||
|
|
||||||
|
renditionService2.setThumbnailsEnabled(false);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Should NOT throw, as this is a text extract transform
|
||||||
|
AuthenticationUtil.runAs(() -> {
|
||||||
|
transactionService.getRetryingTransactionHelper().doInTransaction(() -> {
|
||||||
|
renditionService2.transform(sourceNodeRef, textExtractTransform);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
}, ADMIN);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
renditionService2.setThumbnailsEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMetadataExtractTransformAllowedWhenThumbnailDisabled()
|
||||||
|
{
|
||||||
|
// create a source node
|
||||||
|
NodeRef sourceNodeRef = createSource(ADMIN, "quick.pdf");
|
||||||
|
assertNotNull("Node not generated", sourceNodeRef);
|
||||||
|
renditionService2.setThumbnailsEnabled(false);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Should NOT throw, as this is a metadata extract transform
|
||||||
|
extract(ADMIN, sourceNodeRef);
|
||||||
|
waitForExtract(ADMIN, sourceNodeRef, true);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
renditionService2.setThumbnailsEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user