mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
Merged 5.2.N (5.2.2) to HEAD (5.2)
134671 cpopa: Merged WEBAPP-API (5.2.1) to 5.2.N (5.2.1) 134630 cpopa: APPSREPO-105 : Add an API to download multiple file/folders as a zip - Added an API for creating a download, retrieving download info and canceling a download git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@137348 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -509,7 +509,26 @@
|
|||||||
</list>
|
</list>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
<bean id="downloads" class="org.alfresco.rest.api.impl.DownloadsImpl">
|
||||||
|
<property name="downloadService" ref="DownloadService"/>
|
||||||
|
<property name="nodeService" ref="NodeService"/>
|
||||||
|
<property name="nodes" ref="Nodes" />
|
||||||
|
<property name="permissionService" ref="permissionService"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="Downloads" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||||
|
<property name="proxyInterfaces">
|
||||||
|
<value>org.alfresco.rest.api.Downloads</value>
|
||||||
|
</property>
|
||||||
|
<property name="target">
|
||||||
|
<ref bean="downloads" />
|
||||||
|
</property>
|
||||||
|
<property name="interceptorNames">
|
||||||
|
<list>
|
||||||
|
<idref bean="legacyExceptionInterceptor" />
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
<bean id="deletedNodes" class="org.alfresco.rest.api.impl.DeletedNodesImpl">
|
<bean id="deletedNodes" class="org.alfresco.rest.api.impl.DeletedNodesImpl">
|
||||||
<property name="nodes" ref="Nodes" />
|
<property name="nodes" ref="Nodes" />
|
||||||
<property name="nodeService" ref="NodeService" />
|
<property name="nodeService" ref="NodeService" />
|
||||||
@@ -772,6 +791,10 @@
|
|||||||
|
|
||||||
<!-- API webscripts -->
|
<!-- API webscripts -->
|
||||||
|
|
||||||
|
<bean class="org.alfresco.rest.api.downloads.DownloadsEntityResource">
|
||||||
|
<property name="downloads" ref="Downloads" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean class="org.alfresco.rest.api.sites.SiteEntityResource">
|
<bean class="org.alfresco.rest.api.sites.SiteEntityResource">
|
||||||
<property name="sites" ref="Sites" />
|
<property name="sites" ref="Sites" />
|
||||||
</bean>
|
</bean>
|
||||||
|
59
source/java/org/alfresco/rest/api/Downloads.java
Normal file
59
source/java/org/alfresco/rest/api/Downloads.java
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Remote API
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2016 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;
|
||||||
|
|
||||||
|
import org.alfresco.rest.api.model.Download;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* downloads API
|
||||||
|
*
|
||||||
|
* @author cpopa
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface Downloads
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Creates a download:download node.
|
||||||
|
*
|
||||||
|
* @param download
|
||||||
|
* @return information about the newly created download:download node
|
||||||
|
*/
|
||||||
|
Download createDownloadNode(Download download);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get status info about a download node.
|
||||||
|
*
|
||||||
|
* @param downloadNodeId
|
||||||
|
* @return status info about a download:download node
|
||||||
|
*/
|
||||||
|
Download getDownloadStatus(String downloadNodeId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop the zip creation if still in progress
|
||||||
|
* @param downloadNodeId
|
||||||
|
*/
|
||||||
|
void cancel(String downloadNodeId);
|
||||||
|
}
|
@@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Remote API
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2016 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.downloads;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.alfresco.rest.api.Downloads;
|
||||||
|
import org.alfresco.rest.api.model.Download;
|
||||||
|
import org.alfresco.rest.framework.WebApiDescription;
|
||||||
|
import org.alfresco.rest.framework.WebApiParam;
|
||||||
|
import org.alfresco.rest.framework.core.ResourceParameter;
|
||||||
|
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
|
||||||
|
import org.alfresco.rest.framework.resource.EntityResource;
|
||||||
|
import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction;
|
||||||
|
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||||
|
import org.alfresco.util.ParameterCheck;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author cpopa
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@EntityResource(name = "downloads", title = "Downloads")
|
||||||
|
public class DownloadsEntityResource implements EntityResourceAction.Create<Download>, EntityResourceAction.ReadById<Download>, EntityResourceAction.Delete, InitializingBean
|
||||||
|
{
|
||||||
|
private Downloads downloads;
|
||||||
|
|
||||||
|
public void setDownloads(Downloads downloads)
|
||||||
|
{
|
||||||
|
this.downloads = downloads;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet()
|
||||||
|
{
|
||||||
|
ParameterCheck.mandatory("downloads", this.downloads);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@WebApiDescription(title = "Create download", description = "Create a download node whose content will be a zip which is being created asynchronously.", successStatus = HttpServletResponse.SC_ACCEPTED)
|
||||||
|
@WebApiParam(name = "entity", title = "Download request", description = "Download request which contains the node ids for the zip elements.",
|
||||||
|
kind = ResourceParameter.KIND.HTTP_BODY_OBJECT, allowMultiple = false)
|
||||||
|
public List<Download> create(List<Download> entity, Parameters parameters)
|
||||||
|
{
|
||||||
|
Download downloadNode = downloads.createDownloadNode(entity.get(0));
|
||||||
|
return Collections.singletonList(downloadNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@WebApiDescription(title = "Get download information", description = "Get information about the progress of the zip creation.")
|
||||||
|
@WebApiParam(name = "nodeId", title = "Download nodeId")
|
||||||
|
public Download readById(String nodeId, Parameters parameters) throws EntityNotFoundException
|
||||||
|
{
|
||||||
|
return downloads.getDownloadStatus(nodeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@WebApiDescription(title = "Cancel download", description = "Stop the zip creation if still in progress.", successStatus = HttpServletResponse.SC_ACCEPTED)
|
||||||
|
@Override
|
||||||
|
public void delete(String nodeId, Parameters parameters)
|
||||||
|
{
|
||||||
|
downloads.cancel(nodeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Remote API
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2016 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%
|
||||||
|
*/
|
||||||
|
|
||||||
|
@WebApi(name="alfresco", scope=Api.SCOPE.PUBLIC, version=1)
|
||||||
|
package org.alfresco.rest.api.downloads;
|
||||||
|
import org.alfresco.rest.framework.Api;
|
||||||
|
import org.alfresco.rest.framework.WebApi;
|
175
source/java/org/alfresco/rest/api/impl/DownloadsImpl.java
Normal file
175
source/java/org/alfresco/rest/api/impl/DownloadsImpl.java
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Remote API
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2016 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.impl;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.download.DownloadModel;
|
||||||
|
import org.alfresco.rest.api.Downloads;
|
||||||
|
import org.alfresco.rest.api.Nodes;
|
||||||
|
import org.alfresco.rest.api.model.Download;
|
||||||
|
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
||||||
|
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
|
||||||
|
import org.alfresco.service.cmr.download.DownloadService;
|
||||||
|
import org.alfresco.service.cmr.download.DownloadStatus;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.security.AccessStatus;
|
||||||
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author cpopa
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DownloadsImpl implements Downloads
|
||||||
|
{
|
||||||
|
private DownloadService downloadService;
|
||||||
|
private NodeService nodeService;
|
||||||
|
private Nodes nodes;
|
||||||
|
private PermissionService permissionService;
|
||||||
|
public static final String DEFAULT_ARCHIVE_NAME = "archive.zip";
|
||||||
|
public static final String DEFAULT_ARCHIVE_EXTENSION = ".zip";
|
||||||
|
|
||||||
|
public void setDownloadService(DownloadService downloadService)
|
||||||
|
{
|
||||||
|
this.downloadService = downloadService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNodeService(NodeService nodeService)
|
||||||
|
{
|
||||||
|
this.nodeService = nodeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNodes(Nodes nodes)
|
||||||
|
{
|
||||||
|
this.nodes = nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPermissionService(PermissionService permissionService)
|
||||||
|
{
|
||||||
|
this.permissionService = permissionService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Download createDownloadNode(Download download)
|
||||||
|
{
|
||||||
|
checkEmptyNodeIds(download);
|
||||||
|
|
||||||
|
checkDuplicateNodeId(download);
|
||||||
|
|
||||||
|
NodeRef[] zipContentNodeRefs = validateAndGetNodeRefs(download);
|
||||||
|
|
||||||
|
checkNodeIdsReadPermission(zipContentNodeRefs);
|
||||||
|
|
||||||
|
NodeRef zipNodeRef = downloadService.createDownload(zipContentNodeRefs, true);
|
||||||
|
|
||||||
|
String archiveName = zipContentNodeRefs.length > 1 ?
|
||||||
|
DEFAULT_ARCHIVE_NAME :
|
||||||
|
nodeService.getProperty(zipContentNodeRefs[0], ContentModel.PROP_NAME) + DEFAULT_ARCHIVE_EXTENSION;
|
||||||
|
|
||||||
|
nodeService.setProperty(zipNodeRef, ContentModel.PROP_NAME, archiveName);
|
||||||
|
Download downloadInfo = getStatus(zipNodeRef);
|
||||||
|
return downloadInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Download getDownloadStatus(String downloadNodeId)
|
||||||
|
{
|
||||||
|
NodeRef downloadNodeRef = nodes.validateNode(downloadNodeId);
|
||||||
|
|
||||||
|
checkIsDownloadNodeType(downloadNodeRef);
|
||||||
|
|
||||||
|
Download downloadInfo = getStatus(downloadNodeRef);
|
||||||
|
return downloadInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel(String downloadNodeId)
|
||||||
|
{
|
||||||
|
NodeRef downloadNodeRef = nodes.validateNode(downloadNodeId);
|
||||||
|
checkIsDownloadNodeType(downloadNodeRef);
|
||||||
|
|
||||||
|
downloadService.cancelDownload(downloadNodeRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected NodeRef[] validateAndGetNodeRefs(Download download)
|
||||||
|
{
|
||||||
|
return download.getNodeIds().stream()
|
||||||
|
.map(nodeRef -> nodes.validateNode(nodeRef))
|
||||||
|
.toArray(NodeRef[]::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkNodeIdsReadPermission(NodeRef[] zipContentNodeRefs)
|
||||||
|
{
|
||||||
|
for (NodeRef nodeRef : zipContentNodeRefs)
|
||||||
|
{
|
||||||
|
if (permissionService.hasReadPermission(nodeRef).equals(AccessStatus.DENIED)){
|
||||||
|
throw new PermissionDeniedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkDuplicateNodeId(Download download)
|
||||||
|
{
|
||||||
|
if(download.getNodeIds().size() != new HashSet<String>(download.getNodeIds()).size()){
|
||||||
|
throw new InvalidArgumentException("Cannot specify the same nodeId twice");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkEmptyNodeIds(Download download)
|
||||||
|
{
|
||||||
|
if (download.getNodeIds().size() == 0)
|
||||||
|
{
|
||||||
|
throw new InvalidArgumentException("Cannot create an archive with 0 entries.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void checkIsDownloadNodeType(NodeRef downloadNodeRef)
|
||||||
|
{
|
||||||
|
QName nodeIdType = this.nodeService.getType(downloadNodeRef);
|
||||||
|
|
||||||
|
if(!nodeIdType.equals(DownloadModel.TYPE_DOWNLOAD)){
|
||||||
|
throw new InvalidArgumentException("Please specify the nodeId of a download node.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Download getStatus(NodeRef downloadNodeRef)
|
||||||
|
{
|
||||||
|
DownloadStatus status = downloadService.getDownloadStatus(downloadNodeRef);
|
||||||
|
Download downloadInfo = new Download();
|
||||||
|
downloadInfo.setDownloadId(downloadNodeRef.getId());
|
||||||
|
downloadInfo.setDone(status.getDone());
|
||||||
|
downloadInfo.setFilesAdded(status.getFilesAdded());
|
||||||
|
downloadInfo.setStatus(status.getStatus());
|
||||||
|
downloadInfo.setTotalFiles(status.getTotalFiles());
|
||||||
|
downloadInfo.setTotal(status.getTotal());
|
||||||
|
return downloadInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
131
source/java/org/alfresco/rest/api/model/Download.java
Normal file
131
source/java/org/alfresco/rest/api/model/Download.java
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Remote API
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2016 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.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.alfresco.service.cmr.download.DownloadStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a download entity
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Download
|
||||||
|
{
|
||||||
|
private String downloadId;
|
||||||
|
private List<String> nodeIds;
|
||||||
|
private DownloadStatus.Status status;
|
||||||
|
private long done;
|
||||||
|
private long total;
|
||||||
|
private long filesAdded;
|
||||||
|
private long totalFiles;
|
||||||
|
|
||||||
|
public String getDownloadId()
|
||||||
|
{
|
||||||
|
return downloadId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDownloadId(String downloadId)
|
||||||
|
{
|
||||||
|
this.downloadId = downloadId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getNodeIds()
|
||||||
|
{
|
||||||
|
return nodeIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNodeIds(List<String> nodeIds)
|
||||||
|
{
|
||||||
|
this.nodeIds = nodeIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DownloadStatus.Status getStatus()
|
||||||
|
{
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(DownloadStatus.Status status)
|
||||||
|
{
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getDone()
|
||||||
|
{
|
||||||
|
return done;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDone(long done)
|
||||||
|
{
|
||||||
|
this.done = done;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTotal()
|
||||||
|
{
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotal(long total)
|
||||||
|
{
|
||||||
|
this.total = total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getFilesAdded()
|
||||||
|
{
|
||||||
|
return filesAdded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFilesAdded(long filesAdded)
|
||||||
|
{
|
||||||
|
this.filesAdded = filesAdded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTotalFiles()
|
||||||
|
{
|
||||||
|
return totalFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotalFiles(long totalFiles)
|
||||||
|
{
|
||||||
|
this.totalFiles = totalFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuilder builder = new StringBuilder(150);
|
||||||
|
builder.append("Download [downloadId=").append(downloadId)
|
||||||
|
.append(", nodeIds=").append(nodeIds)
|
||||||
|
.append(", status=").append(status)
|
||||||
|
.append(", done=").append(done)
|
||||||
|
.append(", total=").append(total)
|
||||||
|
.append(", filesAdded=").append(filesAdded)
|
||||||
|
.append(", totalFiles=").append(totalFiles)
|
||||||
|
.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
@@ -74,7 +74,8 @@ import org.junit.runners.Suite;
|
|||||||
TestSiteMembershipRequests.class,
|
TestSiteMembershipRequests.class,
|
||||||
TestFavourites.class,
|
TestFavourites.class,
|
||||||
TestPublicApi128.class,
|
TestPublicApi128.class,
|
||||||
TestPublicApiCaching.class
|
TestPublicApiCaching.class,
|
||||||
|
TestDownloads.class
|
||||||
})
|
})
|
||||||
public class ApiTest
|
public class ApiTest
|
||||||
{
|
{
|
||||||
|
520
source/test-java/org/alfresco/rest/api/tests/TestDownloads.java
Normal file
520
source/test-java/org/alfresco/rest/api/tests/TestDownloads.java
Normal file
@@ -0,0 +1,520 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Remote API
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2016 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 static java.lang.String.format;
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
import static javax.servlet.http.HttpServletResponse.SC_ACCEPTED;
|
||||||
|
import static javax.servlet.http.HttpServletResponse.SC_OK;
|
||||||
|
import static org.alfresco.rest.api.impl.DownloadsImpl.DEFAULT_ARCHIVE_EXTENSION;
|
||||||
|
import static org.alfresco.rest.api.impl.DownloadsImpl.DEFAULT_ARCHIVE_NAME;
|
||||||
|
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.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.alfresco.repo.tenant.TenantUtil;
|
||||||
|
import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork;
|
||||||
|
import org.alfresco.rest.api.model.AssocChild;
|
||||||
|
import org.alfresco.rest.api.model.Download;
|
||||||
|
import org.alfresco.rest.api.nodes.NodesEntityResource;
|
||||||
|
import org.alfresco.rest.api.tests.client.HttpResponse;
|
||||||
|
import org.alfresco.rest.api.tests.client.PublicApiException;
|
||||||
|
import org.alfresco.rest.api.tests.client.RequestContext;
|
||||||
|
import org.alfresco.rest.api.tests.client.data.Document;
|
||||||
|
import org.alfresco.rest.api.tests.client.data.Folder;
|
||||||
|
import org.alfresco.rest.api.tests.util.RestApiUtil;
|
||||||
|
import org.alfresco.rest.framework.core.exceptions.ApiException;
|
||||||
|
import org.alfresco.service.cmr.download.DownloadStatus;
|
||||||
|
import org.alfresco.service.cmr.site.SiteVisibility;
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.FixMethodOrder;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runners.MethodSorters;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the /downloads API
|
||||||
|
*
|
||||||
|
* @author cpopa
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||||
|
public class TestDownloads extends AbstractBaseApiTest
|
||||||
|
{
|
||||||
|
public static final String NODES_SECONDARY_CHILDREN = "nodes/%s/secondary-children";
|
||||||
|
|
||||||
|
public static final String API_DOWNLOADS = "downloads";
|
||||||
|
|
||||||
|
private static final String DOC4_NAME = "docTest4.txt";
|
||||||
|
private static final String SUB_FOLDER1_NAME = "subFolder1";
|
||||||
|
private static final String DOC3_NAME = "docTest3.txt";
|
||||||
|
private static final String FOLDER1_NAME = "folder1";
|
||||||
|
private static final String FOLDER3_NAME = "folder3";
|
||||||
|
private static final String ZIPPABLE_DOC1_NAME = "docTest1.txt";
|
||||||
|
private static final String DUMMY_CONTENT = "dummy content";
|
||||||
|
private org.alfresco.rest.api.Nodes nodesApi;
|
||||||
|
private String zippableDocId1;
|
||||||
|
private String zippableDocId2;
|
||||||
|
private String zippableDocId3_InFolder1;
|
||||||
|
private String zippableFolderId1;
|
||||||
|
private String zippableFolderId2_InFolder1;
|
||||||
|
private String zippableDocId4_InFolder2;
|
||||||
|
private String zippableFolderId3;
|
||||||
|
private String zippableDoc_user2;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setupTest() throws IOException, Exception{
|
||||||
|
nodesApi = applicationContext.getBean("Nodes", org.alfresco.rest.api.Nodes.class);
|
||||||
|
|
||||||
|
setRequestContext(user1);
|
||||||
|
|
||||||
|
Document zippableDoc1 = createTextFile(tDocLibNodeId, ZIPPABLE_DOC1_NAME, DUMMY_CONTENT);
|
||||||
|
zippableDocId1 = zippableDoc1.getId();
|
||||||
|
zippableDocId2 = createTextFile(tDocLibNodeId, "docTest2", DUMMY_CONTENT).getId();
|
||||||
|
|
||||||
|
Folder zippableFolder1 = createFolder(tDocLibNodeId, FOLDER1_NAME);
|
||||||
|
zippableFolderId1 = zippableFolder1.getId();
|
||||||
|
zippableDocId3_InFolder1 = createTextFile(zippableFolderId1, DOC3_NAME, DUMMY_CONTENT).getId();
|
||||||
|
|
||||||
|
Folder zippableFolder2_InFolder1 = createFolder(zippableFolderId1, SUB_FOLDER1_NAME);
|
||||||
|
zippableFolderId2_InFolder1 = zippableFolder2_InFolder1.getId();
|
||||||
|
|
||||||
|
zippableDocId4_InFolder2 = createTextFile(zippableFolderId2_InFolder1, DOC4_NAME, DUMMY_CONTENT).getId();
|
||||||
|
|
||||||
|
Folder zippableFolder3 = createFolder(tDocLibNodeId, FOLDER3_NAME);
|
||||||
|
zippableFolderId3 = zippableFolder3.getId();
|
||||||
|
|
||||||
|
setRequestContext(user2);
|
||||||
|
String user2Site = createSite ("TestSite B - " + RUNID, SiteVisibility.PRIVATE).getId();
|
||||||
|
String user2DocLib = getSiteContainerNodeId(user2Site, "documentLibrary");
|
||||||
|
zippableDoc_user2 = createTextFile(user2DocLib, "user2doc", DUMMY_CONTENT).getId();
|
||||||
|
|
||||||
|
setRequestContext(user1);
|
||||||
|
AssocChild secChild = new AssocChild(zippableDoc1.getId(), ASSOC_TYPE_CM_CONTAINS);
|
||||||
|
post(format(NODES_SECONDARY_CHILDREN, zippableFolder3.getId()), toJsonAsStringNonNull(secChild), HttpServletResponse.SC_CREATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the creation of download nodes.
|
||||||
|
*
|
||||||
|
* <p>POST:</p>
|
||||||
|
* {@literal <host>:<port>/alfresco/api/-default-/private/alfresco/versions/1/downloads}
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void test001CreateDownload() throws Exception
|
||||||
|
{
|
||||||
|
//test creating a download with a single file
|
||||||
|
Download download = createDownload(HttpServletResponse.SC_ACCEPTED, zippableDocId1);
|
||||||
|
|
||||||
|
assertPendingDownloadProps(download);
|
||||||
|
|
||||||
|
assertValidZipNodeid(download);
|
||||||
|
|
||||||
|
assertDoneDownload(download, 1, 13);
|
||||||
|
|
||||||
|
//test creating a multiple file archive
|
||||||
|
download = createDownload(HttpServletResponse.SC_ACCEPTED, zippableDocId1, zippableDocId2);
|
||||||
|
|
||||||
|
assertPendingDownloadProps(download);
|
||||||
|
|
||||||
|
assertValidZipNodeid(download);
|
||||||
|
|
||||||
|
assertDoneDownload(download, 2, 26);
|
||||||
|
|
||||||
|
//test creating a zero file archive
|
||||||
|
createDownload(HttpServletResponse.SC_BAD_REQUEST);
|
||||||
|
|
||||||
|
//test creating an archive with the same file twice
|
||||||
|
download = createDownload(HttpServletResponse.SC_BAD_REQUEST, zippableDocId1, zippableDocId1);
|
||||||
|
|
||||||
|
//test creating an archive with a folder and a file which is contained in the folder
|
||||||
|
download = createDownload(HttpServletResponse.SC_ACCEPTED, zippableFolderId1, zippableDocId3_InFolder1);
|
||||||
|
|
||||||
|
assertPendingDownloadProps(download);
|
||||||
|
|
||||||
|
assertValidZipNodeid(download);
|
||||||
|
|
||||||
|
assertDoneDownload(download, 3, 39);
|
||||||
|
|
||||||
|
//test creating an archive with a file and a folder containing that file but only as a secondary parent child association
|
||||||
|
download = createDownload(HttpServletResponse.SC_ACCEPTED, zippableDocId1, zippableFolderId3);
|
||||||
|
|
||||||
|
assertPendingDownloadProps(download);
|
||||||
|
|
||||||
|
assertValidZipNodeid(download);
|
||||||
|
|
||||||
|
assertDoneDownload(download, 2, 26);
|
||||||
|
|
||||||
|
//test creating an archive with two files, one of which user1 does not have permissions for
|
||||||
|
download = createDownload(HttpServletResponse.SC_FORBIDDEN, zippableDocId1, zippableDoc_user2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests retrieving info about a download node
|
||||||
|
*
|
||||||
|
* <p>GET:</p>
|
||||||
|
* {@literal <host>:<port>/alfresco/api/-default-/private/alfresco/versions/1/downloads/<download_id>}
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void test002GetDownloadInfo() throws Exception
|
||||||
|
{
|
||||||
|
Download download = createDownload(HttpServletResponse.SC_ACCEPTED, zippableFolderId1, zippableFolderId2_InFolder1, zippableDocId4_InFolder2);
|
||||||
|
|
||||||
|
//test retrieving information about an ongoing download
|
||||||
|
assertInProgressDownload(download, 4, 52);
|
||||||
|
|
||||||
|
//test retrieving information about a finished download
|
||||||
|
assertDoneDownload(download, 4, 52);
|
||||||
|
|
||||||
|
//test retrieving the status of a cancelled download
|
||||||
|
download = createDownload(HttpServletResponse.SC_ACCEPTED, zippableFolderId1, zippableDocId3_InFolder1);
|
||||||
|
assertCancelledDownload(download, 3, 39);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests canceling a download.
|
||||||
|
*
|
||||||
|
* <p>DELETE:</p>
|
||||||
|
* {@literal <host>:<port>/alfresco/api/-default-/private/alfresco/versions/1/downloads/<download_id>}
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void test003CancelDownload() throws Exception
|
||||||
|
{
|
||||||
|
//cancel a running download operation
|
||||||
|
Download download = createDownload(HttpServletResponse.SC_ACCEPTED, zippableDocId1, zippableDocId2);
|
||||||
|
|
||||||
|
cancel(download.getDownloadId());
|
||||||
|
|
||||||
|
assertCancelledDownload(download, 2, 26);
|
||||||
|
|
||||||
|
//cancel a completed download - should have no effect
|
||||||
|
download = createDownload(HttpServletResponse.SC_ACCEPTED, zippableDocId1, zippableDocId2);
|
||||||
|
|
||||||
|
assertDoneDownload(download, 2, 26);
|
||||||
|
|
||||||
|
cancel(download.getDownloadId());
|
||||||
|
|
||||||
|
Thread.sleep(500);
|
||||||
|
|
||||||
|
Download downloadStatus = getDownload(download.getDownloadId());
|
||||||
|
|
||||||
|
assertTrue("A cancel operation on a DONE download has no effect.", downloadStatus.getStatus().equals(DownloadStatus.Status.DONE));
|
||||||
|
|
||||||
|
//cancel a node which is not of a download type
|
||||||
|
cancel(HttpServletResponse.SC_BAD_REQUEST, zippableDocId1);
|
||||||
|
|
||||||
|
//user2 canceling user1 download operation - should not be allowed
|
||||||
|
download = createDownload(HttpServletResponse.SC_ACCEPTED, zippableDocId1);
|
||||||
|
|
||||||
|
publicApiClient.setRequestContext(new RequestContext(networkOne.getId(), user2));
|
||||||
|
|
||||||
|
cancel(HttpServletResponse.SC_FORBIDDEN, download.getDownloadId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests downloading the content of a download node(a zip) using the /nodes API:
|
||||||
|
*
|
||||||
|
* <p>GET:</p>
|
||||||
|
* {@literal <host>:<port>/alfresco/api/<networkId>/public/alfresco/versions/1/nodes/<nodeId>/content}
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void test004GetDownloadContent() throws Exception{
|
||||||
|
|
||||||
|
//test downloading the content of a 1 file zip
|
||||||
|
Download download = createDownload(HttpServletResponse.SC_ACCEPTED, zippableDocId1);
|
||||||
|
|
||||||
|
assertDoneDownload(download, 1, 13);
|
||||||
|
|
||||||
|
HttpResponse response = downloadContent(download);
|
||||||
|
|
||||||
|
ZipInputStream zipStream = getZipStreamFromResponse(response);
|
||||||
|
|
||||||
|
ZipEntry zipEntry = zipStream.getNextEntry();
|
||||||
|
|
||||||
|
assertEquals("Zip entry name is not correct", ZIPPABLE_DOC1_NAME, zipEntry.getName());
|
||||||
|
|
||||||
|
assertTrue("Zip entry size is not correct", zipEntry.getCompressedSize() <= 13);
|
||||||
|
|
||||||
|
assertTrue("No more entries should be in this zip", zipStream.getNextEntry() == null);
|
||||||
|
zipStream.close();
|
||||||
|
|
||||||
|
Map<String, String> responseHeaders = response.getHeaders();
|
||||||
|
|
||||||
|
assertNotNull(responseHeaders);
|
||||||
|
|
||||||
|
assertEquals(format("attachment; filename=\"%s\"; filename*=UTF-8''%s", ZIPPABLE_DOC1_NAME + DEFAULT_ARCHIVE_EXTENSION,
|
||||||
|
ZIPPABLE_DOC1_NAME + DEFAULT_ARCHIVE_EXTENSION),
|
||||||
|
responseHeaders.get("Content-Disposition"));
|
||||||
|
|
||||||
|
//test downloading the content of a multiple file zip
|
||||||
|
download = createDownload(HttpServletResponse.SC_ACCEPTED, zippableFolderId1, zippableDocId3_InFolder1);
|
||||||
|
|
||||||
|
assertDoneDownload(download, 3, 39);
|
||||||
|
|
||||||
|
response = downloadContent(download);
|
||||||
|
|
||||||
|
zipStream = getZipStreamFromResponse(response);
|
||||||
|
|
||||||
|
assertEquals("Zip entry name is not correct", FOLDER1_NAME + "/", zipStream.getNextEntry().getName());
|
||||||
|
assertEquals("Zip entry name is not correct", FOLDER1_NAME + "/" + DOC3_NAME, zipStream.getNextEntry().getName());
|
||||||
|
assertEquals("Zip entry name is not correct", FOLDER1_NAME + "/" + SUB_FOLDER1_NAME + "/", zipStream.getNextEntry().getName());
|
||||||
|
assertEquals("Zip entry name is not correct", FOLDER1_NAME + "/" + SUB_FOLDER1_NAME + "/" + DOC4_NAME, zipStream.getNextEntry().getName());
|
||||||
|
assertEquals("Zip entry name is not correct", DOC3_NAME, zipStream.getNextEntry().getName());
|
||||||
|
|
||||||
|
assertTrue("No more entries should be in this zip", zipStream.getNextEntry() == null);
|
||||||
|
zipStream.close();
|
||||||
|
|
||||||
|
responseHeaders = response.getHeaders();
|
||||||
|
|
||||||
|
assertNotNull(responseHeaders);
|
||||||
|
|
||||||
|
assertEquals(format("attachment; filename=\"%s\"; filename*=UTF-8''%s", DEFAULT_ARCHIVE_NAME,
|
||||||
|
DEFAULT_ARCHIVE_NAME),
|
||||||
|
responseHeaders.get("Content-Disposition"));
|
||||||
|
|
||||||
|
//test download the content of a zip which has a secondary child
|
||||||
|
download = createDownload(HttpServletResponse.SC_ACCEPTED, zippableDocId1, zippableFolderId3);
|
||||||
|
assertDoneDownload(download, 2, 26);
|
||||||
|
|
||||||
|
response = downloadContent(download);
|
||||||
|
|
||||||
|
zipStream = getZipStreamFromResponse(response);
|
||||||
|
|
||||||
|
assertEquals("Zip entry name is not correct", ZIPPABLE_DOC1_NAME, zipStream.getNextEntry().getName());
|
||||||
|
assertEquals("Zip entry name is not correct", FOLDER3_NAME + "/", zipStream.getNextEntry().getName());
|
||||||
|
assertEquals("Zip entry name is not correct", FOLDER3_NAME + "/" + ZIPPABLE_DOC1_NAME, zipStream.getNextEntry().getName());
|
||||||
|
assertTrue("No more entries should be in this zip", zipStream.getNextEntry() == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected ZipInputStream getZipStreamFromResponse(HttpResponse response)
|
||||||
|
{
|
||||||
|
return new ZipInputStream(new ByteArrayInputStream(response.getResponseAsBytes()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected HttpResponse downloadContent(Download download) throws Exception
|
||||||
|
{
|
||||||
|
return getSingle(NodesEntityResource.class, download.getDownloadId() + "/content", null, HttpServletResponse.SC_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests deleting a download node using the /nodes API:
|
||||||
|
*
|
||||||
|
* <p>DELETE:</p>
|
||||||
|
* {@literal <host>:<port>/alfresco/api/<networkId>/public/alfresco/versions/1/nodes/<nodeId>}
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void test005DeleteDownloadNode() throws Exception{
|
||||||
|
|
||||||
|
//test deleting a download node
|
||||||
|
Download download = createDownload(HttpServletResponse.SC_ACCEPTED, zippableDocId1);
|
||||||
|
|
||||||
|
assertDoneDownload(download, 1, 13);
|
||||||
|
|
||||||
|
deleteNode(download.getDownloadId(), true, HttpServletResponse.SC_NO_CONTENT);
|
||||||
|
|
||||||
|
getDownload(download.getDownloadId(), HttpServletResponse.SC_NOT_FOUND);
|
||||||
|
|
||||||
|
//test user2 deleting a download node created by user1
|
||||||
|
download = createDownload(HttpServletResponse.SC_ACCEPTED, zippableDocId1);
|
||||||
|
|
||||||
|
assertDoneDownload(download, 1, 13);
|
||||||
|
|
||||||
|
publicApiClient.setRequestContext(new RequestContext(networkOne.getId(), user2));
|
||||||
|
|
||||||
|
deleteNode(download.getDownloadId(), true, HttpServletResponse.SC_FORBIDDEN);
|
||||||
|
|
||||||
|
assertDoneDownload(download, 1, 13);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertDoneDownload(Download download, int expectedFilesAdded, int expectedTotal) throws Exception, InterruptedException
|
||||||
|
{
|
||||||
|
for(int i = 0; i<=40; i++){
|
||||||
|
if (i == 40)
|
||||||
|
{
|
||||||
|
fail("Download should be DONE by now.");
|
||||||
|
}
|
||||||
|
Download downloadStatus = getDownload(download.getDownloadId());
|
||||||
|
if (!downloadStatus.getStatus().equals(DownloadStatus.Status.DONE)){
|
||||||
|
Thread.sleep(50);
|
||||||
|
}else{
|
||||||
|
assertTrue("The number of bytes added in the archive does not match the total", downloadStatus.getDone() == downloadStatus.getTotal());
|
||||||
|
assertEquals("The number of files added in the archive should be " + expectedFilesAdded, expectedFilesAdded, downloadStatus.getFilesAdded());
|
||||||
|
assertEquals("The total number of bytes should be " + expectedTotal, expectedTotal, downloadStatus.getTotal());
|
||||||
|
assertEquals("The total number of files of the final archive should be " + expectedFilesAdded, expectedFilesAdded, downloadStatus.getTotalFiles());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void assertCancelledDownload(Download download, int expectedTotalFiles, int expectedTotal) throws PublicApiException, Exception, InterruptedException
|
||||||
|
{
|
||||||
|
cancel(download.getDownloadId());
|
||||||
|
for(int i = 0; i<=40; i++){
|
||||||
|
if (i == 40)
|
||||||
|
{
|
||||||
|
fail("Download should be CANCELLED by now.");
|
||||||
|
}
|
||||||
|
Download downloadStatus = getDownload(download.getDownloadId());
|
||||||
|
if (!downloadStatus.getStatus().equals(DownloadStatus.Status.CANCELLED)){
|
||||||
|
Thread.sleep(50);
|
||||||
|
}else{
|
||||||
|
assertTrue("The total bytes added to the archive by now should be greater than 0", downloadStatus.getDone() > 0 && downloadStatus.getDone() <= downloadStatus.getTotal());
|
||||||
|
assertTrue("The download is in progress, there should still be files to be added.", downloadStatus.getFilesAdded() < downloadStatus.getTotalFiles());
|
||||||
|
assertEquals("The total number of bytes should be " + expectedTotal, expectedTotal, downloadStatus.getTotal());
|
||||||
|
assertEquals("The total number of files to be added to the archive should be " + expectedTotalFiles, expectedTotalFiles, downloadStatus.getTotalFiles());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertInProgressDownload(Download download, int expectedTotalFiles, int expectedTotal) throws Exception, InterruptedException
|
||||||
|
{
|
||||||
|
for(int i = 0; i<=40; i++){
|
||||||
|
if (i == 40)
|
||||||
|
{
|
||||||
|
fail("Download creation is taking too long.Download status should be at least IN_PROGRESS by now.");
|
||||||
|
}
|
||||||
|
Download downloadStatus = getDownload(download.getDownloadId());
|
||||||
|
if (!downloadStatus.getStatus().equals(DownloadStatus.Status.IN_PROGRESS)){
|
||||||
|
Thread.sleep(50);
|
||||||
|
}else{
|
||||||
|
//'done' can be equal to the 'total' even though the status is IN_PROGRESS. See ZipDownloadExporter line 239
|
||||||
|
assertTrue("The total bytes added to the archive by now should be greater than 0", downloadStatus.getDone() > 0 && downloadStatus.getDone() <= downloadStatus.getTotal());
|
||||||
|
assertTrue("The download is in progress, there should still be files to be added.", downloadStatus.getFilesAdded() < downloadStatus.getTotalFiles());
|
||||||
|
assertEquals("The total number of bytes should be " + expectedTotal, expectedTotal, downloadStatus.getTotal());
|
||||||
|
assertEquals("The total number of files to be added to the archive should be " + expectedTotalFiles, expectedTotalFiles, downloadStatus.getTotalFiles());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setRequestContext(String user)
|
||||||
|
{
|
||||||
|
setRequestContext(networkOne.getId(), user, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertValidZipNodeid(Download download)
|
||||||
|
{
|
||||||
|
try{
|
||||||
|
TenantUtil.runAsUserTenant(new TenantRunAsWork<Void>()
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void doWork() throws Exception
|
||||||
|
{
|
||||||
|
nodesApi.validateNode(download.getDownloadId());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, user1, networkOne.getId());
|
||||||
|
|
||||||
|
}catch(ApiException ex){
|
||||||
|
org.junit.Assert.fail("The download nodeid is not valid." + ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertPendingDownloadProps(Download download)
|
||||||
|
{
|
||||||
|
assertEquals("The download request hasn't been processed yet, the status is not correct", DownloadStatus.Status.PENDING, download.getStatus());
|
||||||
|
assertEquals("Should be 0, the download req hasn't been processed yet", 0, download.getDone());
|
||||||
|
assertEquals("Should be 0, the download req hasn't been processed yet", 0, download.getFilesAdded());
|
||||||
|
assertEquals("Should be 0, the download req hasn't been processed yet", 0, download.getTotal());
|
||||||
|
assertEquals("Should be 0, the download req hasn't been processed yet", 0, download.getTotalFiles());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getScope()
|
||||||
|
{
|
||||||
|
return "public";
|
||||||
|
}
|
||||||
|
|
||||||
|
private Download createDownload(int expectedStatus, String ... nodeIds) throws Exception
|
||||||
|
{
|
||||||
|
Download downloadRequest = new Download();
|
||||||
|
downloadRequest.setNodeIds(Arrays.asList(nodeIds));
|
||||||
|
|
||||||
|
setRequestContext(user1);
|
||||||
|
|
||||||
|
Download download = create(downloadRequest, expectedStatus);
|
||||||
|
return download;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Download create(Download download, int expectedStatus) throws Exception
|
||||||
|
{
|
||||||
|
HttpResponse response = post(API_DOWNLOADS, RestApiUtil.toJsonAsStringNonNull(download), expectedStatus);
|
||||||
|
return getDownloadFromResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Download getDownload(String downloadId, int expectedStatus) throws Exception
|
||||||
|
{
|
||||||
|
HttpResponse response = getSingle(API_DOWNLOADS, downloadId, expectedStatus);
|
||||||
|
|
||||||
|
return getDownloadFromResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Download getDownload(String downloadId) throws Exception
|
||||||
|
{
|
||||||
|
return getDownload(downloadId, HttpServletResponse.SC_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancel(String downloadId) throws Exception
|
||||||
|
{
|
||||||
|
cancel(HttpServletResponse.SC_ACCEPTED, downloadId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancel(int expectedStatusCode, String downloadId) throws Exception
|
||||||
|
{
|
||||||
|
delete(API_DOWNLOADS, downloadId, expectedStatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Download getDownloadFromResponse(HttpResponse response) throws Exception
|
||||||
|
{
|
||||||
|
if (asList(SC_ACCEPTED, SC_OK).contains(response.getStatusCode()))
|
||||||
|
{
|
||||||
|
return RestApiUtil.parseRestApiEntry((JSONObject) response.getJsonResponse(), Download.class);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user