mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
ACS-306: ACS Repository: V1 Rest API for content direct access urls (#1046)
- added alfresco.content.directAccessUrl.expiryTime.seconds property to allow the configuration of the direct access url expiry time - changed getDirectAccessUrl method signature to allow the successful execution of the acl interceptor - moved get content data to it's own method so it can be easily reused - updated test
This commit is contained in:
@@ -370,39 +370,8 @@ public class ContentServiceImpl extends ContentTransformServiceAdaptor implement
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private ContentReader getReader(NodeRef nodeRef, QName propertyQName, boolean fireContentReadPolicy)
|
||||
{
|
||||
ContentData contentData = null;
|
||||
Serializable propValue = nodeService.getProperty(nodeRef, propertyQName);
|
||||
if (propValue instanceof Collection)
|
||||
{
|
||||
Collection<Serializable> colPropValue = (Collection<Serializable>)propValue;
|
||||
if (colPropValue.size() > 0)
|
||||
{
|
||||
propValue = colPropValue.iterator().next();
|
||||
}
|
||||
}
|
||||
|
||||
if (propValue instanceof ContentData)
|
||||
{
|
||||
contentData = (ContentData)propValue;
|
||||
}
|
||||
|
||||
if (contentData == null)
|
||||
{
|
||||
PropertyDefinition contentPropDef = dictionaryService.getProperty(propertyQName);
|
||||
|
||||
// if no value or a value other content, and a property definition has been provided, ensure that it's CONTENT or ANY
|
||||
if (contentPropDef != null &&
|
||||
(!(contentPropDef.getDataType().getName().equals(DataTypeDefinition.CONTENT) ||
|
||||
contentPropDef.getDataType().getName().equals(DataTypeDefinition.ANY))))
|
||||
{
|
||||
throw new InvalidTypeException("The node property must be of type content: \n" +
|
||||
" node: " + nodeRef + "\n" +
|
||||
" property name: " + propertyQName + "\n" +
|
||||
" property type: " + ((contentPropDef == null) ? "unknown" : contentPropDef.getDataType()),
|
||||
propertyQName);
|
||||
}
|
||||
}
|
||||
{
|
||||
ContentData contentData = getContentData(nodeRef, propertyQName);
|
||||
|
||||
// check that the URL is available
|
||||
if (contentData == null || contentData.getContentUrl() == null)
|
||||
@@ -439,6 +408,43 @@ public class ContentServiceImpl extends ContentTransformServiceAdaptor implement
|
||||
return reader;
|
||||
}
|
||||
|
||||
private ContentData getContentData(NodeRef nodeRef, QName propertyQName)
|
||||
{
|
||||
ContentData contentData = null;
|
||||
Serializable propValue = nodeService.getProperty(nodeRef, propertyQName);
|
||||
if (propValue instanceof Collection)
|
||||
{
|
||||
Collection<Serializable> colPropValue = (Collection<Serializable>)propValue;
|
||||
if (colPropValue.size() > 0)
|
||||
{
|
||||
propValue = colPropValue.iterator().next();
|
||||
}
|
||||
}
|
||||
|
||||
if (propValue instanceof ContentData)
|
||||
{
|
||||
contentData = (ContentData)propValue;
|
||||
}
|
||||
|
||||
if (contentData == null)
|
||||
{
|
||||
PropertyDefinition contentPropDef = dictionaryService.getProperty(propertyQName);
|
||||
|
||||
// if no value or a value other content, and a property definition has been provided, ensure that it's CONTENT or ANY
|
||||
if (contentPropDef != null &&
|
||||
(!(contentPropDef.getDataType().getName().equals(DataTypeDefinition.CONTENT) ||
|
||||
contentPropDef.getDataType().getName().equals(DataTypeDefinition.ANY))))
|
||||
{
|
||||
throw new InvalidTypeException("The node property must be of type content: \n" +
|
||||
" node: " + nodeRef + "\n" +
|
||||
" property name: " + propertyQName + "\n" +
|
||||
" property type: " + ((contentPropDef == null) ? "unknown" : contentPropDef.getDataType()),
|
||||
propertyQName);
|
||||
}
|
||||
}
|
||||
return contentData;
|
||||
}
|
||||
|
||||
public ContentWriter getWriter(NodeRef nodeRef, QName propertyQName, boolean update)
|
||||
{
|
||||
if (nodeRef == null)
|
||||
@@ -503,11 +509,20 @@ public class ContentServiceImpl extends ContentTransformServiceAdaptor implement
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDirectAccessUrl(String contentUrl, int expiryTime)
|
||||
public String getDirectAccessUrl(NodeRef nodeRef, int expiryTime)
|
||||
{
|
||||
ContentData contentData = getContentData(nodeRef, ContentModel.PROP_CONTENT);
|
||||
|
||||
// check that the URL is available
|
||||
if (contentData == null || contentData.getContentUrl() == null)
|
||||
{
|
||||
// there is no URL - the interface specifies that this is not an error condition
|
||||
return null;
|
||||
}
|
||||
|
||||
if (store.isDirectAccessSupported())
|
||||
{
|
||||
return store.getDirectAccessUrl(contentUrl, expiryTime);
|
||||
return store.getDirectAccessUrl(contentData.getContentUrl(), expiryTime);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
@@ -154,12 +154,18 @@ public interface ContentService extends ContentTransformService
|
||||
public ContentWriter getTempWriter();
|
||||
|
||||
/**
|
||||
* Gets a presigned URL to directly access a binary content. It is up to the content store
|
||||
* if it can fulfil this request with an expiry time or not.
|
||||
* Gets a presigned URL to directly access a binary content. It is up to the
|
||||
* content store if it can fulfil this request with an expiry time (in
|
||||
* milliseconds) or not.
|
||||
*
|
||||
* @param contentUrl A content store URL
|
||||
* @param expiryTime Expiration time in milliseconds
|
||||
* @return A direct access URL for a binary content or empty string if not supported
|
||||
* @param nodeRef
|
||||
* a reference to a node having a content property
|
||||
* @param expiryTime
|
||||
* the expiration time in milliseconds of the direct access url. This
|
||||
* is the length of time in milliseconds that the link is valid for.
|
||||
* @return A direct access URL for a binary content or returns null if there is
|
||||
* no binary content for the node or empty string if not supported
|
||||
*/
|
||||
public String getDirectAccessUrl(String contentUrl, int expiryTime);
|
||||
@Auditable(parameters = {"nodeRef", "expiryTime"})
|
||||
public String getDirectAccessUrl(NodeRef nodeRef, int expiryTime);
|
||||
}
|
||||
|
@@ -1327,4 +1327,8 @@ system.delete_not_exists.batchsize=100000
|
||||
system.delete_not_exists.delete_batchsize=1000
|
||||
system.delete_not_exists.read_only=false
|
||||
system.delete_not_exists.timeout_seconds=-1
|
||||
system.prop_table_cleaner.algorithm=V2
|
||||
system.prop_table_cleaner.algorithm=V2
|
||||
|
||||
# Configure the expiration time of the direct access url. This is the length of time in seconds that the link is valid for.
|
||||
# Note: It is up to the actual ContentStore implementation if it can fulfil this request or not.
|
||||
alfresco.content.directAccessUrl.expiryTime.seconds=28800
|
@@ -189,7 +189,8 @@ public class ContentServiceImplTest extends BaseVersionStoreTest
|
||||
@Test
|
||||
public void testWhenGetDirectAccessUrlIsNotSupported()
|
||||
{
|
||||
assertEquals("", contentService.getDirectAccessUrl("s3v2://1234421", 10));
|
||||
NodeRef versionableNode = createNewVersionableNode();
|
||||
assertEquals("", contentService.getDirectAccessUrl(versionableNode, 10));
|
||||
assertFalse(contentStore.isDirectAccessSupported());
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user