mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
MNT-22696 Replace Rendition REST API (#880)
Code to reject zero byte renditions Addition of: DELETE /nodes/{nodeId}/renditions/{renditionId} DELETE /nodes/{nodeId}/versions/{versionId}/renditions/{renditionId} end points Co-authored-by: kmagdziarz <Kacper.Magdziarz@hyland.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Remote API
|
* Alfresco Remote API
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
* Copyright (C) 2005 - 2022 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
|
||||||
@@ -147,6 +147,25 @@ public interface Renditions
|
|||||||
void createRenditions(NodeRef nodeRef, String versionId, List<Rendition> renditions, Parameters parameters)
|
void createRenditions(NodeRef nodeRef, String versionId, List<Rendition> renditions, Parameters parameters)
|
||||||
throws NotFoundException, ConstraintViolatedException;
|
throws NotFoundException, ConstraintViolatedException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete the rendition node.
|
||||||
|
*
|
||||||
|
* @param nodeRef the source nodeRef, ie. live node
|
||||||
|
* @param renditionId the rendition id
|
||||||
|
* @param parameters the {@link Parameters} object to get the parameters passed into the request
|
||||||
|
*/
|
||||||
|
void deleteRendition(NodeRef nodeRef, String renditionId, Parameters parameters);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete the rendition node.
|
||||||
|
*
|
||||||
|
* @param nodeRef the source nodeRef, ie. live node
|
||||||
|
* @param versionId the version id (aka version label)
|
||||||
|
* @param renditionId the rendition id
|
||||||
|
* @param parameters the {@link Parameters} object to get the parameters passed into the request
|
||||||
|
*/
|
||||||
|
void deleteRendition(NodeRef nodeRef, String versionId, String renditionId, Parameters parameters);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Downloads rendition.
|
* Downloads rendition.
|
||||||
*
|
*
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Remote API
|
* Alfresco Remote API
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2021 Alfresco Software LimitedP
|
* Copyright (C) 2005 - 2022 Alfresco Software LimitedP
|
||||||
* %%
|
* %%
|
||||||
* 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
|
||||||
@@ -444,6 +444,31 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteRendition(NodeRef nodeRef, String renditionId, Parameters parameters)
|
||||||
|
{
|
||||||
|
deleteRendition(nodeRef, null, renditionId, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteRendition(NodeRef nodeRef, String versionId, String renditionId, Parameters parameters)
|
||||||
|
{
|
||||||
|
if (!renditionService2.isEnabled())
|
||||||
|
{
|
||||||
|
throw new DisabledServiceException("Rendition generation has been disabled.");
|
||||||
|
}
|
||||||
|
|
||||||
|
final NodeRef validatedNodeRef = validateNode(nodeRef.getStoreRef(), nodeRef.getId(), versionId, parameters);
|
||||||
|
NodeRef renditionNodeRef = getRenditionByName(validatedNodeRef, renditionId, parameters);
|
||||||
|
|
||||||
|
if (renditionNodeRef == null)
|
||||||
|
{
|
||||||
|
throw new NotFoundException(renditionId + " is not registered.");
|
||||||
|
}
|
||||||
|
|
||||||
|
renditionService2.clearRenditionContentDataInTransaction(renditionNodeRef);
|
||||||
|
}
|
||||||
|
|
||||||
private String getName(Rendition rendition)
|
private String getName(Rendition rendition)
|
||||||
{
|
{
|
||||||
String renditionName = rendition.getId();
|
String renditionName = rendition.getId();
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Remote API
|
* Alfresco Remote API
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
* Copyright (C) 2005 - 2022 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
|
||||||
@@ -65,6 +65,7 @@ public class NodeRenditionsRelation implements RelationshipResourceAction.Read<R
|
|||||||
RelationshipResourceAction.ReadById<Rendition>,
|
RelationshipResourceAction.ReadById<Rendition>,
|
||||||
RelationshipResourceAction.Create<Rendition>,
|
RelationshipResourceAction.Create<Rendition>,
|
||||||
RelationshipResourceBinaryAction.Read,
|
RelationshipResourceBinaryAction.Read,
|
||||||
|
RelationshipResourceAction.Delete,
|
||||||
InitializingBean
|
InitializingBean
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -110,6 +111,14 @@ public class NodeRenditionsRelation implements RelationshipResourceAction.Read<R
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WebApiDescription(title = "Delete rendition")
|
||||||
|
@Override
|
||||||
|
public void delete(String nodeId, String renditionId, Parameters parameters)
|
||||||
|
{
|
||||||
|
NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
|
||||||
|
renditions.deleteRendition(nodeRef, renditionId, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
@WebApiDescription(title = "Download rendition", description = "Download rendition")
|
@WebApiDescription(title = "Download rendition", description = "Download rendition")
|
||||||
@BinaryProperties({ "content" })
|
@BinaryProperties({ "content" })
|
||||||
@Override
|
@Override
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Remote API
|
* Alfresco Remote API
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
* Copyright (C) 2005 - 2022 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
|
||||||
@@ -51,6 +51,7 @@ import org.springframework.extensions.webscripts.Status;
|
|||||||
* - GET /nodes/{nodeId}/versions/{versionId}/renditions
|
* - GET /nodes/{nodeId}/versions/{versionId}/renditions
|
||||||
* - POST /nodes/{nodeId}/versions/{versionId}/renditions
|
* - POST /nodes/{nodeId}/versions/{versionId}/renditions
|
||||||
* - GET /nodes/{nodeId}/versions/{versionId}/renditions/{renditionId}
|
* - GET /nodes/{nodeId}/versions/{versionId}/renditions/{renditionId}
|
||||||
|
* - DELETE /nodes/{nodeId}/versions/{versionId}/renditions/{renditionId}
|
||||||
* - GET /nodes/{nodeId}/versions/{versionId}/renditions/{renditionId}/content
|
* - GET /nodes/{nodeId}/versions/{versionId}/renditions/{renditionId}/content
|
||||||
*
|
*
|
||||||
* @author janv
|
* @author janv
|
||||||
@@ -59,6 +60,7 @@ import org.springframework.extensions.webscripts.Status;
|
|||||||
public class NodeVersionRenditionsRelation implements RelationshipResourceAction.Read<Rendition>,
|
public class NodeVersionRenditionsRelation implements RelationshipResourceAction.Read<Rendition>,
|
||||||
RelationshipResourceAction.ReadById<Rendition>,
|
RelationshipResourceAction.ReadById<Rendition>,
|
||||||
RelationshipResourceAction.Create<Rendition>,
|
RelationshipResourceAction.Create<Rendition>,
|
||||||
|
RelationshipResourceAction.Delete,
|
||||||
RelationshipResourceBinaryAction.Read,
|
RelationshipResourceBinaryAction.Read,
|
||||||
InitializingBean
|
InitializingBean
|
||||||
{
|
{
|
||||||
@@ -115,4 +117,13 @@ public class NodeVersionRenditionsRelation implements RelationshipResourceAction
|
|||||||
return renditions.getContent(nodeRef, versionId, renditionId, parameters);
|
return renditions.getContent(nodeRef, versionId, renditionId, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WebApiDescription(title = "Delete rendition")
|
||||||
|
@Override
|
||||||
|
public void delete(String nodeId, String versionId, Parameters parameters)
|
||||||
|
{
|
||||||
|
String renditionId = parameters.getRelationship2Id();
|
||||||
|
|
||||||
|
NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
|
||||||
|
renditions.deleteRendition(nodeRef, versionId, renditionId, parameters);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Remote API
|
* Alfresco Remote API
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
* Copyright (C) 2005 - 2022 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
|
||||||
@@ -188,6 +188,8 @@ public class Params implements Parameters
|
|||||||
builder.append(this.entityId);
|
builder.append(this.entityId);
|
||||||
builder.append(", relationshipId=");
|
builder.append(", relationshipId=");
|
||||||
builder.append(this.relationshipId);
|
builder.append(this.relationshipId);
|
||||||
|
builder.append(", relationship2Id=");
|
||||||
|
builder.append(this.relationship2Id);
|
||||||
builder.append(", passedIn=");
|
builder.append(", passedIn=");
|
||||||
builder.append(this.passedIn);
|
builder.append(this.passedIn);
|
||||||
builder.append(", paging=");
|
builder.append(", paging=");
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Remote API
|
* Alfresco Remote API
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
* Copyright (C) 2005 - 2022 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
|
||||||
@@ -68,6 +68,7 @@ public class ResourceWebScriptDelete extends AbstractResourceWebScript implement
|
|||||||
final Map<String, String> resourceVars = locator.parseTemplateVars(req.getServiceMatch().getTemplateVars());
|
final Map<String, String> resourceVars = locator.parseTemplateVars(req.getServiceMatch().getTemplateVars());
|
||||||
final String entityId = resourceVars.get(ResourceLocator.ENTITY_ID);
|
final String entityId = resourceVars.get(ResourceLocator.ENTITY_ID);
|
||||||
final String relationshipId = resourceVars.get(ResourceLocator.RELATIONSHIP_ID);
|
final String relationshipId = resourceVars.get(ResourceLocator.RELATIONSHIP_ID);
|
||||||
|
final String relationship2Id = resourceVars.get(ResourceLocator.RELATIONSHIP2_ID);
|
||||||
|
|
||||||
final Params.RecognizedParams params = getRecognizedParams(req);
|
final Params.RecognizedParams params = getRecognizedParams(req);
|
||||||
|
|
||||||
@@ -78,7 +79,15 @@ public class ResourceWebScriptDelete extends AbstractResourceWebScript implement
|
|||||||
return Params.valueOf(params, entityId, relationshipId, req);
|
return Params.valueOf(params, entityId, relationshipId, req);
|
||||||
case RELATIONSHIP:
|
case RELATIONSHIP:
|
||||||
// note: relationshipId can be null - when deleting a related set/collection
|
// note: relationshipId can be null - when deleting a related set/collection
|
||||||
|
if (StringUtils.isNotBlank(relationship2Id))
|
||||||
|
{
|
||||||
|
return Params.valueOf(false, entityId, relationshipId, relationship2Id,
|
||||||
|
null, null, null, params, null, req);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return Params.valueOf(params, entityId, relationshipId, req);
|
return Params.valueOf(params, entityId, relationshipId, req);
|
||||||
|
}
|
||||||
case PROPERTY:
|
case PROPERTY:
|
||||||
final String resourceName = resourceVars.get(ResourceLocator.RELATIONSHIP_RESOURCE);
|
final String resourceName = resourceVars.get(ResourceLocator.RELATIONSHIP_RESOURCE);
|
||||||
final String propertyName = resourceVars.get(ResourceLocator.PROPERTY);
|
final String propertyName = resourceVars.get(ResourceLocator.PROPERTY);
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Remote API
|
* Alfresco Remote API
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
* Copyright (C) 2005 - 2022 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
|
||||||
@@ -1035,6 +1035,16 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
|
|||||||
return URL_NODES + "/" + nodeId + "/" + URL_RENDITIONS;
|
return URL_NODES + "/" + nodeId + "/" + URL_RENDITIONS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String getNodeRenditionIdUrl(String nodeId, String renditionID)
|
||||||
|
{
|
||||||
|
return URL_NODES + "/" + nodeId + "/" + URL_RENDITIONS + "/" + renditionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getNodeVersionRenditionIdUrl(String nodeId, String versionId, String renditionID)
|
||||||
|
{
|
||||||
|
return URL_NODES + "/" + nodeId + "/" + URL_VERSIONS + "/" + versionId + "/" + URL_RENDITIONS + "/" + renditionID;
|
||||||
|
}
|
||||||
|
|
||||||
protected String getNodeVersionsUrl(String nodeId)
|
protected String getNodeVersionsUrl(String nodeId)
|
||||||
{
|
{
|
||||||
return URL_NODES + "/" + nodeId + "/" + URL_VERSIONS;
|
return URL_NODES + "/" + nodeId + "/" + URL_VERSIONS;
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Remote API
|
* Alfresco Remote API
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
* Copyright (C) 2005 - 2022 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
|
||||||
@@ -6366,5 +6366,92 @@ public class NodeApiTest extends AbstractSingleNetworkSiteTest
|
|||||||
|
|
||||||
HttpResponse dauResponse = post(getRequestContentDirectUrl(contentNodeId), null, null, null, null, 501);
|
HttpResponse dauResponse = post(getRequestContentDirectUrl(contentNodeId), null, null, null, null, 501);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRequestDeleteRendition() throws Exception
|
||||||
|
{
|
||||||
|
setRequestContext(networkOne.getId(), user1, null);
|
||||||
|
|
||||||
|
String myNodeId = getMyNodeId();
|
||||||
|
|
||||||
|
// Create multipart request - txt file
|
||||||
|
String renditionName = "pdf";
|
||||||
|
String fileName = "quick-1.txt";
|
||||||
|
File file = getResourceFile(fileName);
|
||||||
|
MultiPartRequest reqBody = MultiPartBuilder.create()
|
||||||
|
.setFileData(new FileData(fileName, file))
|
||||||
|
.setRenditions(Collections.singletonList(renditionName))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//Upload file to user home node
|
||||||
|
HttpResponse response = post(getNodeChildrenUrl(myNodeId), reqBody.getBody(), null, reqBody.getContentType(), 201);
|
||||||
|
Document document = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||||
|
String contentNodeId = document.getId();
|
||||||
|
|
||||||
|
// wait and check that rendition is created ...
|
||||||
|
Rendition rendition = waitAndGetRendition(contentNodeId, null, renditionName);
|
||||||
|
assertNotNull(rendition);
|
||||||
|
assertEquals(Rendition.RenditionStatus.CREATED, rendition.getStatus());
|
||||||
|
|
||||||
|
//clean rendition
|
||||||
|
delete(getNodeRenditionIdUrl(contentNodeId, renditionName), null, null, null, null, 204);
|
||||||
|
//retry to double-check deletion
|
||||||
|
delete(getNodeRenditionIdUrl(contentNodeId, renditionName), null, null, null, null, 404);
|
||||||
|
|
||||||
|
//check if rendition was cleaned
|
||||||
|
HttpResponse getResponse = getSingle(getNodeRenditionIdUrl(contentNodeId, renditionName), null, 200);
|
||||||
|
Rendition renditionDeleted = RestApiUtil.parseRestApiEntry(getResponse.getJsonResponse(), Rendition.class);
|
||||||
|
assertNotNull(renditionDeleted);
|
||||||
|
assertEquals(Rendition.RenditionStatus.NOT_CREATED, renditionDeleted.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRequestVersionDeleteRendition() throws Exception
|
||||||
|
{
|
||||||
|
setRequestContext(networkOne.getId(), user1, null);
|
||||||
|
|
||||||
|
String myNodeId = getMyNodeId();
|
||||||
|
|
||||||
|
// Create multipart request - txt file
|
||||||
|
String renditionName = "pdf";
|
||||||
|
String fileName = "quick-1.txt";
|
||||||
|
File file = getResourceFile(fileName);
|
||||||
|
MultiPartRequest reqBody = MultiPartBuilder.create()
|
||||||
|
.setFileData(new FileData(fileName, file))
|
||||||
|
.setRenditions(Collections.singletonList(renditionName))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//Upload file to user home node
|
||||||
|
HttpResponse response = post(getNodeChildrenUrl(myNodeId), reqBody.getBody(), null, reqBody.getContentType(), 201);
|
||||||
|
Document document = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||||
|
String contentNodeId = document.getId();
|
||||||
|
|
||||||
|
//Update file to newer version
|
||||||
|
String content = "The quick brown fox jumps over the lazy dog\n the lazy dog jumps over the quick brown fox";
|
||||||
|
Map<String, String> params = new HashMap<>();
|
||||||
|
params.put("comment", "my version ");
|
||||||
|
|
||||||
|
document = updateTextFile(contentNodeId, content, params);
|
||||||
|
assertTrue(document.getAspectNames().contains("cm:versionable"));
|
||||||
|
assertNotNull(document.getProperties());
|
||||||
|
assertEquals("1.1", document.getProperties().get("cm:versionLabel"));
|
||||||
|
|
||||||
|
// create rendition for old version and check that rendition is created ...
|
||||||
|
Rendition renditionUpdated = createAndGetRendition(contentNodeId, "1.0", renditionName);
|
||||||
|
assertNotNull(renditionUpdated);
|
||||||
|
assertEquals(Rendition.RenditionStatus.CREATED, renditionUpdated.getStatus());
|
||||||
|
|
||||||
|
//clean rendition
|
||||||
|
delete(getNodeVersionRenditionIdUrl(contentNodeId, "1.0", renditionName), null, null, null, null, 204);
|
||||||
|
//retry to double-check deletion
|
||||||
|
delete(getNodeVersionRenditionIdUrl(contentNodeId, "1.0", renditionName), null, null, null, null, 404);
|
||||||
|
|
||||||
|
//check if rendition was cleaned
|
||||||
|
HttpResponse getResponse = getSingle(getNodeVersionRenditionIdUrl(contentNodeId, "1.0", renditionName), null, 200);
|
||||||
|
Rendition renditionDeleted = RestApiUtil.parseRestApiEntry(getResponse.getJsonResponse(), Rendition.class);
|
||||||
|
assertNotNull(renditionDeleted);
|
||||||
|
assertEquals(Rendition.RenditionStatus.NOT_CREATED, renditionDeleted.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2018 Alfresco Software Limited
|
* Copyright (C) 2005 - 2022 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
|
||||||
@@ -112,6 +112,14 @@ public interface RenditionService2
|
|||||||
@NotAuditable
|
@NotAuditable
|
||||||
ChildAssociationRef getRenditionByName(NodeRef sourceNodeRef, String renditionName);
|
ChildAssociationRef getRenditionByName(NodeRef sourceNodeRef, String renditionName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method clears source nodeRef rendition content and content hash code using supplied rendition name.
|
||||||
|
*
|
||||||
|
* @param renditionNode the rendition node
|
||||||
|
*/
|
||||||
|
@NotAuditable
|
||||||
|
void clearRenditionContentDataInTransaction(NodeRef renditionNode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates if renditions are enabled. Set using the {@code system.thumbnail.generate} value.
|
* Indicates if renditions are enabled. Set using the {@code system.thumbnail.generate} value.
|
||||||
*/
|
*/
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
* Copyright (C) 2005 - 2022 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
|
||||||
@@ -38,6 +38,7 @@ import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
|||||||
import org.alfresco.repo.util.PostTxnCallbackScheduler;
|
import org.alfresco.repo.util.PostTxnCallbackScheduler;
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
import org.alfresco.service.cmr.repository.ContentData;
|
import org.alfresco.service.cmr.repository.ContentData;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentReader;
|
||||||
import org.alfresco.service.cmr.repository.ContentService;
|
import org.alfresco.service.cmr.repository.ContentService;
|
||||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
@@ -553,12 +554,22 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
|||||||
contentWriter.setEncoding(DEFAULT_ENCODING);
|
contentWriter.setEncoding(DEFAULT_ENCODING);
|
||||||
ContentWriter renditionWriter = contentWriter;
|
ContentWriter renditionWriter = contentWriter;
|
||||||
renditionWriter.putContent(transformInputStream);
|
renditionWriter.putContent(transformInputStream);
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
|
ContentReader contentReader = renditionWriter.getReader();
|
||||||
|
long sizeOfRendition = contentReader.getSize();
|
||||||
|
if (sizeOfRendition > 0L)
|
||||||
{
|
{
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.error("Transform was zero bytes for " + renditionName + " on " + sourceNodeRef);
|
||||||
|
clearRenditionContentData(renditionNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
logger.error("Failed to copy transform InputStream into rendition " + renditionName + " on " + sourceNodeRef);
|
logger.error("Failed to copy transform InputStream into rendition " + renditionName + " on " + sourceNodeRef);
|
||||||
@@ -892,6 +903,17 @@ public class RenditionService2Impl implements RenditionService2, InitializingBea
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearRenditionContentDataInTransaction(NodeRef renditionNode)
|
||||||
|
{
|
||||||
|
AuthenticationUtil.runAsSystem((AuthenticationUtil.RunAsWork<Void>) () ->
|
||||||
|
transactionService.getRetryingTransactionHelper().doInTransaction(() ->
|
||||||
|
{
|
||||||
|
clearRenditionContentData(renditionNode);
|
||||||
|
return null;
|
||||||
|
}, false, true));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled()
|
public boolean isEnabled()
|
||||||
{
|
{
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
* Copyright (C) 2005 - 2022 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
|
||||||
@@ -28,6 +28,8 @@ package org.alfresco.repo.rendition2;
|
|||||||
import static org.alfresco.model.ContentModel.PROP_CONTENT;
|
import static org.alfresco.model.ContentModel.PROP_CONTENT;
|
||||||
import static org.junit.Assert.assertNotEquals;
|
import static org.junit.Assert.assertNotEquals;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
@@ -358,7 +360,25 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati
|
|||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testRenditionWithoutContentButWithContentHashCode()
|
public void testRenditionWithNullContentButWithContentHashCode()
|
||||||
|
{
|
||||||
|
testRenditionWithoutContentButWithContentHashCode(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if a rendition without content (but with contentHashCode) can be generated again.
|
||||||
|
* <p>
|
||||||
|
* 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.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testRenditionWithZeroContentButWithContentHashCode()
|
||||||
|
{
|
||||||
|
testRenditionWithoutContentButWithContentHashCode(new ByteArrayInputStream(new byte[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testRenditionWithoutContentButWithContentHashCode(InputStream transformInputStream)
|
||||||
{
|
{
|
||||||
// Create a node with an actual rendition
|
// Create a node with an actual rendition
|
||||||
NodeRef sourceNodeRef = createSource(ADMIN, "quick.jpg");
|
NodeRef sourceNodeRef = createSource(ADMIN, "quick.jpg");
|
||||||
@@ -379,7 +399,7 @@ public class RenditionService2IntegrationTest extends AbstractRenditionIntegrati
|
|||||||
// This is explicitly called to prove that rendition hash code will be cleaned (as opposite to previous behavior)
|
// This is explicitly called to prove that rendition hash code will be cleaned (as opposite to previous behavior)
|
||||||
RenditionDefinition2 renditionDefinition = renditionDefinitionRegistry2.getRenditionDefinition(DOC_LIB);
|
RenditionDefinition2 renditionDefinition = renditionDefinitionRegistry2.getRenditionDefinition(DOC_LIB);
|
||||||
AuthenticationUtil.runAs(() -> {
|
AuthenticationUtil.runAs(() -> {
|
||||||
renditionService2.consume(sourceNodeRef, null, renditionDefinition, contentHashCode);
|
renditionService2.consume(sourceNodeRef, transformInputStream, renditionDefinition, contentHashCode);
|
||||||
return null;
|
return null;
|
||||||
}, ADMIN);
|
}, ADMIN);
|
||||||
waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, false);
|
waitForRendition(ADMIN, sourceNodeRef, DOC_LIB, false);
|
||||||
|
Reference in New Issue
Block a user