mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
ACS-197 / ACS-207 : Add REST API for Version Renditions (#654)
* ACS-197 / ACS-207 : Add REST API for Version Renditions - add four new endpoints for version-specific renditions and automated tests (+ve & -ve) -- GET /nodes/{nodeId}/versions/{versionId}/renditions - List renditions for a version -- POST /nodes/{nodeId}/versions/{versionId}/renditions - Create rendition for a version -- GET /nodes/{nodeId}/versions/{versionId}/renditions/{renditionId} - Get rendition information for a version -- GET /nodes/{nodeId}/versions/{versionId}/renditions/{renditionId}/content - Get rendition content for a version - note: the RenditionsImpl implementation is also tested via RenditionsTest
This commit is contained in:
@@ -18,6 +18,7 @@ branches:
|
||||
only:
|
||||
- master
|
||||
- /support\/.*/
|
||||
- /feature\/.*/
|
||||
|
||||
stages:
|
||||
- test
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -39,36 +39,61 @@ import java.util.List;
|
||||
/**
|
||||
* Renditions API
|
||||
*
|
||||
* @author Jamal Kaabi-Mofrad
|
||||
* @author Jamal Kaabi-Mofrad, janv
|
||||
*/
|
||||
public interface Renditions
|
||||
{
|
||||
String PARAM_STATUS = "status";
|
||||
|
||||
String PARAM_ATTACHMENT = "attachment";
|
||||
String PARAM_PLACEHOLDER = "placeholder";
|
||||
|
||||
/**
|
||||
* Lists all available renditions includes those that have been created and those that are yet to be created.
|
||||
*
|
||||
* @param nodeRef
|
||||
* @param nodeRef the source/live nodeRef
|
||||
* @param parameters the {@link Parameters} object to get the parameters passed into the request
|
||||
* @return the rendition results
|
||||
*/
|
||||
CollectionWithPagingInfo<Rendition> getRenditions(NodeRef nodeRef, Parameters parameters);
|
||||
|
||||
/**
|
||||
* Lists all available renditions includes those that have been created and those that are yet to be created.
|
||||
*
|
||||
* @param nodeRef the source/live nodeRef
|
||||
* @param versionId the version id (aka version label)
|
||||
* @param parameters the {@link Parameters} object to get the parameters passed into the request
|
||||
* @return the rendition results
|
||||
*/
|
||||
CollectionWithPagingInfo<Rendition> getRenditions(NodeRef nodeRef, String versionId, Parameters parameters);
|
||||
|
||||
/**
|
||||
* Gets information about a rendition of a node in the repository.
|
||||
* If there is no rendition, then returns the available/registered rendition.
|
||||
*
|
||||
* @param nodeRef
|
||||
* @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
|
||||
* @return the {@link Rendition} object
|
||||
*/
|
||||
Rendition getRendition(NodeRef nodeRef, String renditionId, Parameters parameters);
|
||||
|
||||
/**
|
||||
* Gets information about a rendition of a node in the repository.
|
||||
* If there is no rendition, then returns the available/registered rendition.
|
||||
*
|
||||
* @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
|
||||
* @return the {@link Rendition} object
|
||||
*/
|
||||
Rendition getRendition(NodeRef nodeRef, String versionId, String renditionId, Parameters parameters);
|
||||
|
||||
/**
|
||||
* Creates a rendition for the given node asynchronously.
|
||||
*
|
||||
* @param nodeRef
|
||||
* @param nodeRef the source nodeRef, ie. live node
|
||||
* @param rendition the {@link Rendition} request
|
||||
* @param parameters the {@link Parameters} object to get the parameters passed into the request
|
||||
*/
|
||||
@@ -77,18 +102,29 @@ public interface Renditions
|
||||
/**
|
||||
* Creates a rendition for the given node - either async r sync
|
||||
*
|
||||
* @param nodeRef
|
||||
* @param rendition
|
||||
* @param nodeRef the source nodeRef, ie. live node
|
||||
* @param rendition the {@link Rendition} request
|
||||
* @param executeAsync
|
||||
* @param parameters
|
||||
*/
|
||||
void createRendition(NodeRef nodeRef, Rendition rendition, boolean executeAsync, Parameters parameters);
|
||||
|
||||
/**
|
||||
* Creates a rendition for the given node - either async r sync
|
||||
*
|
||||
* @param nodeRef the source nodeRef, ie. live node
|
||||
* @param versionId the version id (aka version label)
|
||||
* @param rendition the {@link Rendition} request
|
||||
* @param executeAsync
|
||||
* @param parameters
|
||||
*/
|
||||
void createRendition(NodeRef nodeRef, String versionId, Rendition rendition, boolean executeAsync, Parameters parameters);
|
||||
|
||||
/**
|
||||
* Creates renditions that don't already exist for the given node asynchronously.
|
||||
*
|
||||
* @param nodeRef
|
||||
* @param renditions the {@link Rendition} request
|
||||
* @param nodeRef the source nodeRef, ie. live node
|
||||
* @param renditions the list of {@link Rendition} requests
|
||||
* @param parameters the {@link Parameters} object to get the parameters passed into the request
|
||||
* @throws NotFoundException if any of the rendition id do not exist.
|
||||
* @throws ConstraintViolatedException if all of the renditions already exist.
|
||||
@@ -97,23 +133,58 @@ public interface Renditions
|
||||
throws NotFoundException, ConstraintViolatedException;
|
||||
|
||||
/**
|
||||
* Downloads rendition.
|
||||
* Creates renditions that don't already exist for the given node asynchronously.
|
||||
*
|
||||
* @param sourceNodeRef the source nodeRef
|
||||
* @param renditionId the rendition id
|
||||
* @param nodeRef the source nodeRef, ie. live node
|
||||
* @param versionId the version id (aka version label)
|
||||
* @param renditions the list of {@link Rendition} requests
|
||||
* @param parameters the {@link Parameters} object to get the parameters passed into the request
|
||||
* @return the rendition stream
|
||||
* @throws NotFoundException if any of the rendition id do not exist.
|
||||
* @throws ConstraintViolatedException if all of the renditions already exist.
|
||||
*/
|
||||
BinaryResource getContent(NodeRef sourceNodeRef, String renditionId, Parameters parameters);
|
||||
void createRenditions(NodeRef nodeRef, String versionId, List<Rendition> renditions, Parameters parameters)
|
||||
throws NotFoundException, ConstraintViolatedException;
|
||||
|
||||
/**
|
||||
* Downloads rendition.
|
||||
*
|
||||
* @param sourceNodeRef the source nodeRef
|
||||
* @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
|
||||
* @return the rendition stream
|
||||
*/
|
||||
BinaryResource getContentNoValidation(NodeRef sourceNodeRef, String renditionId, Parameters parameters);
|
||||
BinaryResource getContent(NodeRef nodeRef, String renditionId, Parameters parameters);
|
||||
|
||||
/**
|
||||
* Downloads rendition.
|
||||
*
|
||||
* @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
|
||||
* @return the rendition stream
|
||||
*/
|
||||
BinaryResource getContent(NodeRef nodeRef, String versionId, String renditionId, Parameters parameters);
|
||||
|
||||
/**
|
||||
* Downloads rendition.
|
||||
*
|
||||
* @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
|
||||
* @return the rendition stream
|
||||
*/
|
||||
BinaryResource getContentNoValidation(NodeRef nodeRef, String renditionId, Parameters parameters);
|
||||
|
||||
/**
|
||||
* Downloads rendition.
|
||||
*
|
||||
* @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
|
||||
* @return the rendition stream
|
||||
*/
|
||||
BinaryResource getContentNoValidation(NodeRef nodeRef, String versionId, String renditionId, Parameters parameters);
|
||||
}
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2020 Alfresco Software LimitedP
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -34,6 +34,7 @@ import org.alfresco.repo.rendition2.RenditionDefinitionRegistry2;
|
||||
import org.alfresco.repo.rendition2.RenditionService2;
|
||||
import org.alfresco.repo.tenant.TenantService;
|
||||
import org.alfresco.repo.thumbnail.script.ScriptThumbnailService;
|
||||
import org.alfresco.repo.version.common.VersionUtil;
|
||||
import org.alfresco.rest.antlr.WhereClauseParser;
|
||||
import org.alfresco.rest.api.Nodes;
|
||||
import org.alfresco.rest.api.Renditions;
|
||||
@@ -64,6 +65,10 @@ import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.version.Version;
|
||||
import org.alfresco.service.cmr.version.VersionDoesNotExistException;
|
||||
import org.alfresco.service.cmr.version.VersionHistory;
|
||||
import org.alfresco.service.cmr.version.VersionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.alfresco.util.TempFileProvider;
|
||||
@@ -87,7 +92,7 @@ import java.util.StringJoiner;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* @author Jamal Kaabi-Mofrad
|
||||
* @author Jamal Kaabi-Mofrad, janv
|
||||
*/
|
||||
public class RenditionsImpl implements Renditions, ResourceLoaderAware
|
||||
{
|
||||
@@ -104,6 +109,7 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
|
||||
private TenantService tenantService;
|
||||
private RenditionService2 renditionService2;
|
||||
private RenditionsDataCollector renditionsDataCollector;
|
||||
private VersionService versionService;
|
||||
|
||||
public void setNodes(Nodes nodes)
|
||||
{
|
||||
@@ -151,14 +157,21 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
|
||||
PropertyCheck.mandatory(this, "renditionsDataCollector", renditionsDataCollector);
|
||||
|
||||
this.nodeService = serviceRegistry.getNodeService();
|
||||
this.versionService = serviceRegistry.getVersionService();
|
||||
this.mimetypeService = serviceRegistry.getMimetypeService();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionWithPagingInfo<Rendition> getRenditions(NodeRef nodeRef, Parameters parameters)
|
||||
{
|
||||
final NodeRef validatedNodeRef = validateNode(nodeRef.getStoreRef(), nodeRef.getId());
|
||||
ContentData contentData = getContentData(nodeRef, true);
|
||||
return getRenditions(nodeRef, null, parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionWithPagingInfo<Rendition> getRenditions(NodeRef nodeRef, String versionLabelId, Parameters parameters)
|
||||
{
|
||||
final NodeRef validatedNodeRef = validateNode(nodeRef.getStoreRef(), nodeRef.getId(), versionLabelId, parameters);
|
||||
ContentData contentData = getContentData(validatedNodeRef, true);
|
||||
String sourceMimetype = contentData.getMimetype();
|
||||
|
||||
boolean includeCreated = true;
|
||||
@@ -214,7 +227,13 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
|
||||
@Override
|
||||
public Rendition getRendition(NodeRef nodeRef, String renditionId, Parameters parameters)
|
||||
{
|
||||
final NodeRef validatedNodeRef = validateNode(nodeRef.getStoreRef(), nodeRef.getId());
|
||||
return getRendition(nodeRef, null, renditionId, parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rendition getRendition(NodeRef nodeRef, String versionLabelId, String renditionId, Parameters parameters)
|
||||
{
|
||||
final NodeRef validatedNodeRef = validateNode(nodeRef.getStoreRef(), nodeRef.getId(), versionLabelId, parameters);
|
||||
NodeRef renditionNodeRef = getRenditionByName(validatedNodeRef, renditionId, parameters);
|
||||
boolean includeNotCreated = true;
|
||||
String status = getStatus(parameters);
|
||||
@@ -272,6 +291,12 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
|
||||
|
||||
@Override
|
||||
public void createRendition(NodeRef nodeRef, Rendition rendition, boolean executeAsync, Parameters parameters)
|
||||
{
|
||||
createRendition(nodeRef, null, rendition, executeAsync, parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createRendition(NodeRef nodeRef, String versionLabelId, Rendition rendition, boolean executeAsync, Parameters parameters)
|
||||
{
|
||||
// If thumbnail generation has been configured off, then don't bother.
|
||||
if (!renditionService2.isEnabled())
|
||||
@@ -279,7 +304,7 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
|
||||
throw new DisabledServiceException("Rendition generation has been disabled.");
|
||||
}
|
||||
|
||||
final NodeRef sourceNodeRef = validateNode(nodeRef.getStoreRef(), nodeRef.getId());
|
||||
final NodeRef sourceNodeRef = validateNode(nodeRef.getStoreRef(), nodeRef.getId(), versionLabelId, parameters);
|
||||
final NodeRef renditionNodeRef = getRenditionByName(sourceNodeRef, rendition.getId(), parameters);
|
||||
if (renditionNodeRef != null)
|
||||
{
|
||||
@@ -307,6 +332,13 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
|
||||
@Override
|
||||
public void createRenditions(NodeRef nodeRef, List<Rendition> renditions, Parameters parameters)
|
||||
throws NotFoundException, ConstraintViolatedException
|
||||
{
|
||||
createRenditions(nodeRef, null, renditions, parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createRenditions(NodeRef nodeRef, String versionLabelId, List<Rendition> renditions, Parameters parameters)
|
||||
throws NotFoundException, ConstraintViolatedException
|
||||
{
|
||||
if (renditions.isEmpty())
|
||||
{
|
||||
@@ -318,7 +350,7 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
|
||||
throw new DisabledServiceException("Rendition generation has been disabled.");
|
||||
}
|
||||
|
||||
final NodeRef sourceNodeRef = validateNode(nodeRef.getStoreRef(), nodeRef.getId());
|
||||
final NodeRef sourceNodeRef = validateNode(nodeRef.getStoreRef(), nodeRef.getId(), versionLabelId, parameters);
|
||||
RenditionDefinitionRegistry2 renditionDefinitionRegistry2 = renditionService2.getRenditionDefinitionRegistry2();
|
||||
|
||||
// So that POST /nodes/{nodeId}/renditions can specify rendition names as a comma separated list just like
|
||||
@@ -349,7 +381,6 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
|
||||
List<String> renditionNamesToCreate = new ArrayList<>();
|
||||
for (String renditionName : renditionNames)
|
||||
{
|
||||
System.err.println("renditionName="+renditionName);
|
||||
if (renditionName == null)
|
||||
{
|
||||
throw new IllegalArgumentException(("Null rendition name supplied")); // 400
|
||||
@@ -417,18 +448,36 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
|
||||
@Override
|
||||
public BinaryResource getContent(NodeRef nodeRef, String renditionId, Parameters parameters)
|
||||
{
|
||||
final NodeRef validatedNodeRef = validateNode(nodeRef.getStoreRef(), nodeRef.getId());
|
||||
return getContentNoValidation(validatedNodeRef, renditionId, parameters);
|
||||
return getContent(nodeRef, null, renditionId, parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryResource getContentNoValidation(NodeRef sourceNodeRef, String renditionId, Parameters parameters)
|
||||
public BinaryResource getContent(NodeRef nodeRef, String versionLabelId, String renditionId, Parameters parameters)
|
||||
{
|
||||
NodeRef renditionNodeRef = getRenditionByName(sourceNodeRef, renditionId, parameters);
|
||||
final NodeRef validatedNodeRef = validateNode(nodeRef.getStoreRef(), nodeRef.getId(), versionLabelId, parameters);
|
||||
return getContentImpl(validatedNodeRef, renditionId, parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryResource getContentNoValidation(NodeRef nodeRef, String renditionId, Parameters parameters)
|
||||
{
|
||||
return getContentNoValidation(nodeRef, null, renditionId, parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryResource getContentNoValidation(NodeRef nodeRef, String versionLabelId, String renditionId, Parameters parameters)
|
||||
{
|
||||
nodeRef = findVersionIfApplicable(nodeRef, versionLabelId);
|
||||
return getContentImpl(nodeRef, renditionId, parameters);
|
||||
}
|
||||
|
||||
private BinaryResource getContentImpl(NodeRef nodeRef, String renditionId, Parameters parameters)
|
||||
{
|
||||
NodeRef renditionNodeRef = getRenditionByName(nodeRef, renditionId, parameters);
|
||||
|
||||
// By default set attachment header (with rendition Id) unless attachment=false
|
||||
boolean attach = true;
|
||||
String attachment = parameters.getParameter("attachment");
|
||||
String attachment = parameters.getParameter(PARAM_ATTACHMENT);
|
||||
if (attachment != null)
|
||||
{
|
||||
attach = Boolean.valueOf(attachment);
|
||||
@@ -437,7 +486,7 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
|
||||
|
||||
if (renditionNodeRef == null)
|
||||
{
|
||||
boolean isPlaceholder = Boolean.valueOf(parameters.getParameter("placeholder"));
|
||||
boolean isPlaceholder = Boolean.valueOf(parameters.getParameter(PARAM_PLACEHOLDER));
|
||||
if (!isPlaceholder)
|
||||
{
|
||||
throw new NotFoundException("Thumbnail was not found for [" + renditionId + ']');
|
||||
@@ -445,7 +494,7 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
|
||||
String sourceNodeMimeType = null;
|
||||
try
|
||||
{
|
||||
sourceNodeMimeType = (sourceNodeRef != null ? getMimeType(sourceNodeRef) : null);
|
||||
sourceNodeMimeType = (nodeRef != null ? getMimeType(nodeRef) : null);
|
||||
}
|
||||
catch (InvalidArgumentException e)
|
||||
{
|
||||
@@ -514,23 +563,25 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
|
||||
|
||||
protected NodeRef getRenditionByName(NodeRef nodeRef, String renditionId, Parameters parameters)
|
||||
{
|
||||
if (nodeRef == null)
|
||||
if (nodeRef != null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(renditionId))
|
||||
{
|
||||
throw new InvalidArgumentException("renditionId can't be null or empty.");
|
||||
}
|
||||
|
||||
ChildAssociationRef nodeRefRendition = renditionService2.getRenditionByName(nodeRef, renditionId);
|
||||
if (nodeRefRendition == null)
|
||||
if (nodeRefRendition != null)
|
||||
{
|
||||
return null;
|
||||
ContentData contentData = getContentData(nodeRefRendition.getChildRef(), false);
|
||||
if (contentData != null)
|
||||
{
|
||||
return tenantService.getName(nodeRef, nodeRefRendition.getChildRef());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tenantService.getName(nodeRef, nodeRefRendition.getChildRef());
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Rendition toApiRendition(NodeRef renditionNodeRef)
|
||||
@@ -570,16 +621,42 @@ public class RenditionsImpl implements Renditions, ResourceLoaderAware
|
||||
return apiRendition;
|
||||
}
|
||||
|
||||
public NodeRef validateNode(StoreRef storeRef, String nodeId)
|
||||
private NodeRef validateNode(StoreRef storeRef, final String nodeId, String versionLabelId, Parameters parameters)
|
||||
{
|
||||
if (nodeId == null)
|
||||
{
|
||||
throw new InvalidArgumentException("Missing nodeId");
|
||||
}
|
||||
|
||||
final NodeRef nodeRef = nodes.validateNode(storeRef, nodeId);
|
||||
NodeRef nodeRef = nodes.validateNode(storeRef, nodeId);
|
||||
// check if the node represents a file
|
||||
isContentFile(nodeRef);
|
||||
|
||||
nodeRef = findVersionIfApplicable(nodeRef, versionLabelId);
|
||||
|
||||
return nodeRef;
|
||||
}
|
||||
|
||||
private NodeRef findVersionIfApplicable(NodeRef nodeRef, String versionLabelId)
|
||||
{
|
||||
if (versionLabelId != null)
|
||||
{
|
||||
nodeRef = nodes.validateOrLookupNode(nodeRef.getId(), null);
|
||||
VersionHistory vh = versionService.getVersionHistory(nodeRef);
|
||||
if (vh != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Version v = vh.getVersion(versionLabelId);
|
||||
nodeRef = VersionUtil.convertNodeRef(v.getFrozenStateNodeRef());
|
||||
}
|
||||
catch (VersionDoesNotExistException vdne)
|
||||
{
|
||||
throw new NotFoundException("Couldn't find version: [" + nodeRef.getId() + ", " + versionLabelId + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nodeRef;
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
package org.alfresco.rest.api.nodes;
|
||||
|
||||
import org.alfresco.rest.api.Renditions;
|
||||
import org.alfresco.rest.api.model.Rendition;
|
||||
import org.alfresco.rest.framework.BinaryProperties;
|
||||
import org.alfresco.rest.framework.WebApiDescription;
|
||||
import org.alfresco.rest.framework.resource.RelationshipResource;
|
||||
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
|
||||
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceBinaryAction;
|
||||
import org.alfresco.rest.framework.resource.content.BinaryResource;
|
||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.extensions.webscripts.Status;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* Node version renditions
|
||||
*
|
||||
* - GET /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}/content
|
||||
*
|
||||
* @author janv
|
||||
*/
|
||||
@RelationshipResource(name = "renditions", entityResource = NodeVersionsRelation.class, title = "Node version renditions")
|
||||
public class NodeVersionRenditionsRelation implements RelationshipResourceAction.Read<Rendition>,
|
||||
RelationshipResourceAction.ReadById<Rendition>,
|
||||
RelationshipResourceAction.Create<Rendition>,
|
||||
RelationshipResourceBinaryAction.Read,
|
||||
InitializingBean
|
||||
{
|
||||
private Renditions renditions;
|
||||
|
||||
public void setRenditions(Renditions renditions)
|
||||
{
|
||||
this.renditions = renditions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception
|
||||
{
|
||||
PropertyCheck.mandatory(this, "renditions", renditions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CollectionWithPagingInfo<Rendition> readAll(String nodeId, Parameters parameters)
|
||||
{
|
||||
String versionId = parameters.getRelationshipId();
|
||||
|
||||
NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
|
||||
return renditions.getRenditions(nodeRef, versionId, parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rendition readById(String nodeId, String versionId, Parameters parameters)
|
||||
{
|
||||
String renditionId = parameters.getRelationship2Id();
|
||||
|
||||
NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
|
||||
return renditions.getRendition(nodeRef, versionId, renditionId, parameters);
|
||||
}
|
||||
|
||||
@WebApiDescription(title = "Create rendition", successStatus = Status.STATUS_ACCEPTED)
|
||||
@Override
|
||||
public List<Rendition> create(String nodeId, List<Rendition> entity, Parameters parameters)
|
||||
{
|
||||
String versionId = parameters.getRelationshipId();
|
||||
|
||||
NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
|
||||
renditions.createRenditions(nodeRef, versionId, entity, parameters);
|
||||
return null;
|
||||
}
|
||||
|
||||
@WebApiDescription(title = "Download rendition", description = "Download rendition")
|
||||
@BinaryProperties({ "content" })
|
||||
@Override
|
||||
public BinaryResource readProperty(String nodeId, String versionId, Parameters parameters)
|
||||
{
|
||||
String renditionId = parameters.getRelationship2Id();
|
||||
|
||||
NodeRef nodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeId);
|
||||
return renditions.getContent(nodeRef, versionId, renditionId, parameters);
|
||||
}
|
||||
}
|
@@ -1389,6 +1389,10 @@
|
||||
<property name="renditions" ref="Renditions" />
|
||||
</bean>
|
||||
|
||||
<bean class="org.alfresco.rest.api.nodes.NodeVersionRenditionsRelation">
|
||||
<property name="renditions" ref="Renditions" />
|
||||
</bean>
|
||||
|
||||
<bean class="org.alfresco.rest.api.quicksharelinks.QuickShareLinkRenditionsRelation">
|
||||
<property name="quickShareLinks" ref="QuickShareLinks"/>
|
||||
</bean>
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -25,12 +25,14 @@
|
||||
*/
|
||||
package org.alfresco.rest.api.tests;
|
||||
|
||||
import org.alfresco.rest.api.tests.client.PublicApiHttpClient;
|
||||
import static org.alfresco.rest.api.tests.util.RestApiUtil.toJsonAsString;
|
||||
import static org.alfresco.rest.api.tests.util.RestApiUtil.toJsonAsStringNonNull;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.tenant.TenantService;
|
||||
@@ -76,6 +78,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Generic methods for calling the Api (originally taken and adapted from BaseCustomModelApiTest)
|
||||
@@ -94,7 +97,9 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
|
||||
|
||||
protected static final String URL_NODES = "nodes";
|
||||
|
||||
private static final String URL_RENDITIONS = "renditions";
|
||||
protected static final String URL_RENDITIONS = "renditions";
|
||||
protected static final String URL_VERSIONS = "versions";
|
||||
|
||||
private static final String URL_CHILDREN = "children";
|
||||
private static final String URL_CONTENT = "content";
|
||||
|
||||
@@ -841,22 +846,112 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
|
||||
return RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Document.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* This test helper method uses "update binary content" to create one or more new versions. The file must already exist.
|
||||
*
|
||||
* @param userId
|
||||
* @param contentNodeId
|
||||
* @param cnt
|
||||
* @param textContentPrefix
|
||||
* @param verCnt
|
||||
* @param majorVersion
|
||||
* @param currentVersionLabel
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
protected String updateFileVersions(String userId, String contentNodeId, int cnt,
|
||||
String textContentPrefix, int verCnt,
|
||||
Boolean majorVersion, String currentVersionLabel) throws Exception
|
||||
{
|
||||
String[] parts = currentVersionLabel.split("\\.");
|
||||
|
||||
int majorVer = new Integer(parts[0]).intValue();
|
||||
int minorVer = new Integer(parts[1]).intValue();
|
||||
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put(Nodes.PARAM_OVERWRITE, "true");
|
||||
|
||||
if (majorVersion != null)
|
||||
{
|
||||
params.put(Nodes.PARAM_VERSION_MAJOR, majorVersion.toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
majorVersion = false;
|
||||
}
|
||||
|
||||
|
||||
if (majorVersion)
|
||||
{
|
||||
minorVer = 0;
|
||||
}
|
||||
|
||||
for (int i = 1; i <= cnt; i++)
|
||||
{
|
||||
if (majorVersion)
|
||||
{
|
||||
majorVer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
minorVer++;
|
||||
}
|
||||
|
||||
verCnt++;
|
||||
|
||||
params.put("comment", "my version " + verCnt);
|
||||
|
||||
String textContent = textContentPrefix + verCnt;
|
||||
|
||||
currentVersionLabel = majorVer + "." + minorVer;
|
||||
|
||||
// Update
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(textContent.getBytes());
|
||||
File txtFile = TempFileProvider.createTempFile(inputStream, getClass().getSimpleName(), ".txt");
|
||||
PublicApiHttpClient.BinaryPayload payload = new PublicApiHttpClient.BinaryPayload(txtFile);
|
||||
|
||||
HttpResponse response = putBinary(getNodeContentUrl(contentNodeId), payload, null, params, 200);
|
||||
Node nodeResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class);
|
||||
|
||||
assertTrue(nodeResp.getAspectNames().contains("cm:versionable"));
|
||||
assertNotNull(nodeResp.getProperties());
|
||||
assertEquals(currentVersionLabel, nodeResp.getProperties().get("cm:versionLabel"));
|
||||
assertEquals((majorVersion ? "MAJOR" : "MINOR"), nodeResp.getProperties().get("cm:versionType"));
|
||||
|
||||
// double-check - get version node info
|
||||
response = getSingle(getNodeVersionsUrl(contentNodeId), currentVersionLabel, null, 200);
|
||||
nodeResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class);
|
||||
assertEquals(currentVersionLabel, nodeResp.getProperties().get("cm:versionLabel"));
|
||||
assertEquals((majorVersion ? "MAJOR" : "MINOR"), nodeResp.getProperties().get("cm:versionType"));
|
||||
}
|
||||
|
||||
return currentVersionLabel;
|
||||
}
|
||||
|
||||
protected static final long PAUSE_TIME = 5000; //millisecond
|
||||
protected static final int MAX_RETRY = 20;
|
||||
|
||||
protected Rendition waitAndGetRendition(String sourceNodeId, String renditionId) throws Exception
|
||||
protected Rendition waitAndGetRendition(String sourceNodeId, String versionId, String renditionId) throws Exception
|
||||
{
|
||||
return waitAndGetRendition(sourceNodeId, renditionId, MAX_RETRY, PAUSE_TIME);
|
||||
return waitAndGetRendition(sourceNodeId, versionId, renditionId, MAX_RETRY, PAUSE_TIME);
|
||||
}
|
||||
|
||||
protected Rendition waitAndGetRendition(String sourceNodeId, String renditionId, int maxRetry, long pauseTime) throws Exception
|
||||
protected Rendition waitAndGetRendition(String sourceNodeId, String versionId, String renditionId, int maxRetry, long pauseTime) throws Exception
|
||||
{
|
||||
int retryCount = 0;
|
||||
while (retryCount < maxRetry)
|
||||
{
|
||||
try
|
||||
{
|
||||
HttpResponse response = getSingle(getNodeRenditionsUrl(sourceNodeId), renditionId, 200);
|
||||
HttpResponse response;
|
||||
if ((versionId != null) && (! versionId.isEmpty()))
|
||||
{
|
||||
response = getSingle(getNodeVersionRenditionsUrl(sourceNodeId, versionId), renditionId, 200);
|
||||
}
|
||||
else
|
||||
{
|
||||
response = getSingle(getNodeRenditionsUrl(sourceNodeId), renditionId, 200);
|
||||
}
|
||||
Rendition rendition = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Rendition.class);
|
||||
assertNotNull(rendition);
|
||||
assertEquals(Rendition.RenditionStatus.CREATED, rendition.getStatus());
|
||||
@@ -877,6 +972,11 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
|
||||
}
|
||||
|
||||
protected Rendition createAndGetRendition(String sourceNodeId, String renditionId) throws Exception
|
||||
{
|
||||
return createAndGetRendition(sourceNodeId, null, renditionId);
|
||||
}
|
||||
|
||||
protected Rendition createAndGetRendition(String sourceNodeId, String versionId, String renditionId) throws Exception
|
||||
{
|
||||
Rendition renditionRequest = new Rendition();
|
||||
renditionRequest.setId(renditionId);
|
||||
@@ -886,8 +986,16 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
|
||||
{
|
||||
try
|
||||
{
|
||||
HttpResponse res = post(getNodeRenditionsUrl(sourceNodeId), toJsonAsString(renditionRequest), 202);
|
||||
assertNull(res.getJsonResponse());
|
||||
HttpResponse response;
|
||||
if ((versionId != null) && (! versionId.isEmpty()))
|
||||
{
|
||||
response = post(getNodeVersionRenditionsUrl(sourceNodeId, versionId), toJsonAsString(renditionRequest), 202);
|
||||
}
|
||||
else
|
||||
{
|
||||
response = post(getNodeRenditionsUrl(sourceNodeId), toJsonAsString(renditionRequest), 202);
|
||||
}
|
||||
assertNull(response.getJsonResponse());
|
||||
break;
|
||||
}
|
||||
catch (AssertionError ex)
|
||||
@@ -901,7 +1009,7 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
|
||||
}
|
||||
}
|
||||
|
||||
return waitAndGetRendition(sourceNodeId, renditionId);
|
||||
return waitAndGetRendition(sourceNodeId, versionId, renditionId);
|
||||
}
|
||||
|
||||
protected String getNodeRenditionsUrl(String nodeId)
|
||||
@@ -909,6 +1017,16 @@ public abstract class AbstractBaseApiTest extends EnterpriseTestApi
|
||||
return URL_NODES + "/" + nodeId + "/" + URL_RENDITIONS;
|
||||
}
|
||||
|
||||
protected String getNodeVersionsUrl(String nodeId)
|
||||
{
|
||||
return URL_NODES + "/" + nodeId + "/" + URL_VERSIONS;
|
||||
}
|
||||
|
||||
protected String getNodeVersionRenditionsUrl(String nodeId, String versionId)
|
||||
{
|
||||
return URL_NODES + "/" + nodeId + "/" + URL_VERSIONS + "/" + versionId + "/" + URL_RENDITIONS;
|
||||
}
|
||||
|
||||
protected String getNodeChildrenUrl(String nodeId)
|
||||
{
|
||||
return URL_NODES + "/" + nodeId + "/" + URL_CHILDREN;
|
||||
|
@@ -0,0 +1,267 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.rest.api.tests;
|
||||
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.rest.AbstractSingleNetworkSiteTest;
|
||||
import org.alfresco.rest.api.Nodes;
|
||||
import org.alfresco.rest.api.tests.client.HttpResponse;
|
||||
import org.alfresco.rest.api.tests.client.PublicApiClient.Paging;
|
||||
import org.alfresco.rest.api.tests.client.PublicApiHttpClient;
|
||||
import org.alfresco.rest.api.tests.client.data.ContentInfo;
|
||||
import org.alfresco.rest.api.tests.client.data.Document;
|
||||
import org.alfresco.rest.api.tests.client.data.Node;
|
||||
import org.alfresco.rest.api.tests.client.data.Rendition;
|
||||
import org.alfresco.rest.api.tests.util.RestApiUtil;
|
||||
import static org.alfresco.rest.api.tests.util.RestApiUtil.toJsonAsString;
|
||||
import org.alfresco.util.TempFileProvider;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* V1 REST API tests for Node Version Renditions
|
||||
*
|
||||
* {@literal <host>:<port>/alfresco/api/<networkId>/public/alfresco/versions/1/nodes/{nodeId}/versions/{versionId}/renditions</li>
|
||||
*
|
||||
* @author janv
|
||||
*/
|
||||
public class NodeVersionRenditionsApiTest extends AbstractSingleNetworkSiteTest
|
||||
{
|
||||
private final static long DELAY_IN_MS = 500;
|
||||
|
||||
/**
|
||||
* Upload some versions and then create and retrieve version renditions
|
||||
*
|
||||
* <p>POST:</p>
|
||||
* @literal <host>:<port>/alfresco/api/-default-/public/alfresco/versions/1/nodes/<nodeId>/versions/<versionId>/renditions}
|
||||
*
|
||||
* <p>GET:</p>
|
||||
* {@literal <host>:<port>/alfresco/api/<networkId>/public/alfresco/versions/1/nodes/<nodeId>/versions/<versionId>/renditions}
|
||||
* {@literal <host>:<port>/alfresco/api/<networkId>/public/alfresco/versions/1/nodes/<nodeId>/versions/<versionId>/renditions/<renditionId>}
|
||||
* {@literal <host>:<port>/alfresco/api/<networkId>/public/alfresco/versions/1/nodes/<nodeId>/versions/<versionId>/renditions/<renditionId>/content}
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testUpFileVersionRenditions() throws Exception
|
||||
{
|
||||
setRequestContext(user1);
|
||||
|
||||
String myFolderNodeId = getMyNodeId();
|
||||
|
||||
// create folder
|
||||
String f1Id = createFolder(myFolderNodeId, "f1").getId();
|
||||
|
||||
try
|
||||
{
|
||||
int verCnt = 1;
|
||||
int cnt = 1;
|
||||
String versionLabel = "1.0";
|
||||
|
||||
String textContentSuffix = "Amazingly few discotheques provide jukeboxes ";
|
||||
String contentName = "content-2-" + System.currentTimeMillis();
|
||||
String content = textContentSuffix + cnt;
|
||||
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("majorVersion", "true");
|
||||
|
||||
// create a new file
|
||||
Document documentResp = createTextFile(f1Id, contentName, content, "UTF-8", params);
|
||||
String docId = documentResp.getId();
|
||||
assertTrue(documentResp.getAspectNames().contains("cm:versionable"));
|
||||
assertNotNull(documentResp.getProperties());
|
||||
assertEquals(versionLabel, documentResp.getProperties().get("cm:versionLabel"));
|
||||
|
||||
cnt = 2;
|
||||
versionLabel = updateFileVersions(user1, docId, cnt, textContentSuffix, verCnt, true, versionLabel);
|
||||
verCnt = verCnt+cnt;
|
||||
|
||||
assertEquals("3.0", versionLabel);
|
||||
assertEquals(3, verCnt);
|
||||
|
||||
// check version history count
|
||||
HttpResponse response = getAll(getNodeVersionsUrl(docId), null, null, 200);
|
||||
List<Node> nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Node.class);
|
||||
assertEquals(verCnt, nodes.size());
|
||||
|
||||
// pause briefly
|
||||
Thread.sleep(DELAY_IN_MS);
|
||||
|
||||
checkCreateAndGetVersionRendition(docId, "1.0", "doclib");
|
||||
checkCreateAndGetVersionRendition(docId, "3.0", "doclib");
|
||||
checkCreateAndGetVersionRendition(docId, "2.0", "doclib");
|
||||
|
||||
// also live node
|
||||
checkCreateAndGetVersionRendition(docId, null, "doclib");
|
||||
}
|
||||
finally
|
||||
{
|
||||
// some cleanup
|
||||
setRequestContext(user1);
|
||||
deleteNode(f1Id, true, 204);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNegative() throws Exception
|
||||
{
|
||||
AuthenticationUtil.clearCurrentSecurityContext();
|
||||
setRequestContext(null);
|
||||
|
||||
// -ve: not authenticated
|
||||
getAll(getNodeVersionRenditionsUrl("dummy", "1.0"), null, 401);
|
||||
getSingle(getNodeVersionRenditionsUrl("dummy", "1.0"), ("doclib"), null, 401);
|
||||
getSingle(getNodeVersionRenditionsUrl("dummy", "1.0"), ("doclib/content"), null, 401);
|
||||
|
||||
Rendition renditionRequest = new Rendition();
|
||||
renditionRequest.setId("doclib");
|
||||
post(getNodeVersionRenditionsUrl("dummy", "1.0"), toJsonAsString(renditionRequest), 401);
|
||||
|
||||
setRequestContext(user1);
|
||||
|
||||
String myFolderNodeId = getMyNodeId();
|
||||
|
||||
// create folder
|
||||
String f1Id = createFolder(myFolderNodeId, "f1").getId();
|
||||
|
||||
try
|
||||
{
|
||||
int verCnt = 1;
|
||||
int cnt = 1;
|
||||
String versionLabel = "1.0";
|
||||
|
||||
String textContentSuffix = "Amazingly few discotheques provide jukeboxes ";
|
||||
String contentName = "content-2-" + System.currentTimeMillis();
|
||||
String content = textContentSuffix + cnt;
|
||||
|
||||
// create a new file
|
||||
Document documentResp = createTextFile(f1Id, contentName, content, "UTF-8", null);
|
||||
String docId = documentResp.getId();
|
||||
|
||||
getAll(getNodeVersionRenditionsUrl(docId, "1.0"), null, 200);
|
||||
checkCreateAndGetVersionRendition(docId, "1.0", "doclib");
|
||||
|
||||
|
||||
// -ve: rendition already exits (409)
|
||||
renditionRequest.setId("doclib");
|
||||
post(getNodeVersionRenditionsUrl(docId, "1.0"), toJsonAsString(renditionRequest), 409);
|
||||
|
||||
// -ve: no such rendition (404)
|
||||
getSingle(getNodeVersionRenditionsUrl("dummy", "1.0"), ("dummy"), null, 404);
|
||||
getSingle(getNodeVersionRenditionsUrl("dummy", "1.0"), ("dummy/content"), null, 404);
|
||||
|
||||
renditionRequest.setId("dummy");
|
||||
post(getNodeVersionRenditionsUrl("dummy", "1.0"), toJsonAsString(renditionRequest), 404);
|
||||
|
||||
|
||||
// -ve: no such version (404)
|
||||
getAll(getNodeVersionRenditionsUrl(docId, "4.0"), null, 404);
|
||||
getSingle(getNodeVersionRenditionsUrl(docId, "4.0"), ("doclib"), null, 404);
|
||||
getSingle(getNodeVersionRenditionsUrl(docId, "4.0"), ("doclib/content"), null, 404);
|
||||
|
||||
renditionRequest.setId("doclib");
|
||||
post(getNodeVersionRenditionsUrl(docId, "4.0"), toJsonAsString(renditionRequest), 404);
|
||||
|
||||
|
||||
// -ve: no such file (404)
|
||||
getAll(getNodeVersionRenditionsUrl("dummy", "1.0"), null, 404);
|
||||
getSingle(getNodeVersionRenditionsUrl("dummy", "1.0"), ("doclib"), null, 404);
|
||||
getSingle(getNodeVersionRenditionsUrl("dummy", "1.0"), ("doclib/content"), null, 404);
|
||||
|
||||
renditionRequest.setId("doclib");
|
||||
post(getNodeVersionRenditionsUrl("dummy", "1.0"), toJsonAsString(renditionRequest), 404);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// some cleanup
|
||||
setRequestContext(user1);
|
||||
deleteNode(f1Id, true, 204);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkCreateAndGetVersionRendition(String docId, String versionId, String renditionId) throws Exception
|
||||
{
|
||||
String getRenditionsUrl;
|
||||
if ((versionId != null) && (! versionId.isEmpty()))
|
||||
{
|
||||
getRenditionsUrl = getNodeVersionRenditionsUrl(docId, versionId);
|
||||
}
|
||||
else
|
||||
{
|
||||
getRenditionsUrl = getNodeRenditionsUrl(docId);
|
||||
}
|
||||
|
||||
// List renditions for version
|
||||
Paging paging = getPaging(0, 50);
|
||||
HttpResponse response = getAll(getRenditionsUrl, paging, 200);
|
||||
List<Rendition> renditions = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Rendition.class);
|
||||
assertTrue(renditions.size() >= 5);
|
||||
|
||||
for (Rendition rendition : renditions)
|
||||
{
|
||||
assertEquals(Rendition.RenditionStatus.NOT_CREATED, rendition.getStatus());
|
||||
}
|
||||
|
||||
// Get rendition (not created yet) information for node
|
||||
response = getSingle(getRenditionsUrl, renditionId, 200);
|
||||
Rendition rendition = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Rendition.class);
|
||||
assertNotNull(rendition);
|
||||
assertEquals(Rendition.RenditionStatus.NOT_CREATED, rendition.getStatus());
|
||||
|
||||
// -ve test: try to download non-existent rendition (and no placeholder)
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("placeholder", "false");
|
||||
getSingle(getRenditionsUrl, (renditionId+"/content"), params, 404);
|
||||
|
||||
// +ve test: download placeholder instead
|
||||
params = new HashMap<>();
|
||||
params.put("placeholder", "true");
|
||||
response = getSingle(getRenditionsUrl, (renditionId+"/content"), params, 200);
|
||||
assertNotNull(response.getResponseAsBytes());
|
||||
|
||||
// Create and get version rendition
|
||||
rendition = createAndGetRendition(docId, versionId, renditionId);
|
||||
assertNotNull(rendition);
|
||||
assertEquals(Rendition.RenditionStatus.CREATED, rendition.getStatus());
|
||||
ContentInfo contentInfo = rendition.getContent();
|
||||
assertNotNull(contentInfo);
|
||||
assertEquals(MimetypeMap.MIMETYPE_IMAGE_PNG, contentInfo.getMimeType());
|
||||
assertEquals("PNG Image", contentInfo.getMimeTypeName());
|
||||
assertNotNull(contentInfo.getEncoding());
|
||||
assertTrue(contentInfo.getSizeInBytes() > 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getScope()
|
||||
{
|
||||
return "public";
|
||||
}
|
||||
}
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -61,18 +61,12 @@ import static org.junit.Assert.*;
|
||||
public class NodeVersionsApiTest extends AbstractSingleNetworkSiteTest
|
||||
{
|
||||
private static final String URL_DELETED_NODES = "deleted-nodes";
|
||||
private static final String URL_VERSIONS = "versions";
|
||||
|
||||
protected String getNodeVersionRevertUrl(String nodeId, String versionId)
|
||||
{
|
||||
return getNodeVersionsUrl(nodeId) + "/" + versionId + "/revert";
|
||||
}
|
||||
|
||||
protected String getNodeVersionsUrl(String nodeId)
|
||||
{
|
||||
return URL_NODES + "/" + nodeId + "/" + URL_VERSIONS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test version creation when uploading files (via multi-part/form-data with overwrite=true)
|
||||
*
|
||||
@@ -561,89 +555,6 @@ public class NodeVersionsApiTest extends AbstractSingleNetworkSiteTest
|
||||
return new Pair<String,String>(currentVersionLabel, docId);
|
||||
}
|
||||
|
||||
/**
|
||||
* This test helper method uses "update binary content" to create one or more new versions. The file must already exist.
|
||||
*
|
||||
* @param userId
|
||||
* @param contentNodeId
|
||||
* @param cnt
|
||||
* @param textContentPrefix
|
||||
* @param verCnt
|
||||
* @param majorVersion
|
||||
* @param currentVersionLabel
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private String updateFileVersions(String userId, String contentNodeId, int cnt,
|
||||
String textContentPrefix, int verCnt,
|
||||
Boolean majorVersion, String currentVersionLabel) throws Exception
|
||||
{
|
||||
String[] parts = currentVersionLabel.split("\\.");
|
||||
|
||||
int majorVer = new Integer(parts[0]).intValue();
|
||||
int minorVer = new Integer(parts[1]).intValue();
|
||||
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put(Nodes.PARAM_OVERWRITE, "true");
|
||||
|
||||
if (majorVersion != null)
|
||||
{
|
||||
params.put(Nodes.PARAM_VERSION_MAJOR, majorVersion.toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
majorVersion = false;
|
||||
}
|
||||
|
||||
|
||||
if (majorVersion)
|
||||
{
|
||||
minorVer = 0;
|
||||
}
|
||||
|
||||
for (int i = 1; i <= cnt; i++)
|
||||
{
|
||||
if (majorVersion)
|
||||
{
|
||||
majorVer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
minorVer++;
|
||||
}
|
||||
|
||||
verCnt++;
|
||||
|
||||
params.put("comment", "my version " + verCnt);
|
||||
|
||||
String textContent = textContentPrefix + verCnt;
|
||||
|
||||
currentVersionLabel = majorVer + "." + minorVer;
|
||||
|
||||
// Update
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(textContent.getBytes());
|
||||
File txtFile = TempFileProvider.createTempFile(inputStream, getClass().getSimpleName(), ".txt");
|
||||
PublicApiHttpClient.BinaryPayload payload = new PublicApiHttpClient.BinaryPayload(txtFile);
|
||||
|
||||
HttpResponse response = putBinary(getNodeContentUrl(contentNodeId), payload, null, params, 200);
|
||||
Node nodeResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class);
|
||||
|
||||
assertTrue(nodeResp.getAspectNames().contains("cm:versionable"));
|
||||
assertNotNull(nodeResp.getProperties());
|
||||
assertEquals(currentVersionLabel, nodeResp.getProperties().get("cm:versionLabel"));
|
||||
assertEquals((majorVersion ? "MAJOR" : "MINOR"), nodeResp.getProperties().get("cm:versionType"));
|
||||
|
||||
// double-check - get version node info
|
||||
response = getSingle(getNodeVersionsUrl(contentNodeId), currentVersionLabel, null, 200);
|
||||
nodeResp = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Node.class);
|
||||
assertEquals(currentVersionLabel, nodeResp.getProperties().get("cm:versionLabel"));
|
||||
assertEquals((majorVersion ? "MAJOR" : "MINOR"), nodeResp.getProperties().get("cm:versionType"));
|
||||
}
|
||||
|
||||
return currentVersionLabel;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests api when uploading a file and then updating with a new version
|
||||
*
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Remote API
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -548,7 +548,7 @@ public class RenditionsTest extends AbstractBaseApiTest
|
||||
String contentNodeId = document.getId();
|
||||
|
||||
// wait and check that rendition is created ...
|
||||
Rendition rendition = waitAndGetRendition(contentNodeId, renditionName);
|
||||
Rendition rendition = waitAndGetRendition(contentNodeId, null, renditionName);
|
||||
assertNotNull(rendition);
|
||||
assertEquals(RenditionStatus.CREATED, rendition.getStatus());
|
||||
|
||||
@@ -637,7 +637,7 @@ public class RenditionsTest extends AbstractBaseApiTest
|
||||
{
|
||||
for (String renditionName : renditionNames)
|
||||
{
|
||||
Rendition rendition = waitAndGetRendition(contentNodeId, renditionName);
|
||||
Rendition rendition = waitAndGetRendition(contentNodeId, null, renditionName);
|
||||
assertNotNull(rendition);
|
||||
assertEquals(RenditionStatus.CREATED, rendition.getStatus());
|
||||
}
|
||||
|
Reference in New Issue
Block a user