mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
ACS-2216: Fix incorrect ContentService Java Interface - should accept content propQName (#813)
Squashed some of the commit messages: * ACS-2216: Resolving failing tests * ACS-2216: Reformatting code * ACS-2216: Adding David's suggestion * ACS-2216: Set some methods to default as per David's comments * ACS-2216: Added test for when propertyQName has no content * ACS-2216: Replaced try catch with assertThrows * ACS-2216: Added propertyQName to Auditable list Co-authored-by: David Edwards <david.edwards@hyland.com>
This commit is contained in:
@@ -3420,7 +3420,7 @@ public class NodesImpl implements Nodes
|
|||||||
@Override
|
@Override
|
||||||
public DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, boolean attachment, Long validFor)
|
public DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, boolean attachment, Long validFor)
|
||||||
{
|
{
|
||||||
DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(nodeRef, attachment, validFor);
|
DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(nodeRef, ContentModel.PROP_CONTENT, attachment, validFor);
|
||||||
if (directAccessUrl == null)
|
if (directAccessUrl == null)
|
||||||
{
|
{
|
||||||
throw new DisabledServiceException("Direct access url isn't available.");
|
throw new DisabledServiceException("Direct access url isn't available.");
|
||||||
|
@@ -591,14 +591,14 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
|
|||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isContentDirectUrlEnabled(NodeRef nodeRef)
|
public boolean isContentDirectUrlEnabled(NodeRef nodeRef, QName propertyQName)
|
||||||
{
|
{
|
||||||
boolean contentDirectUrlEnabled = false;
|
boolean contentDirectUrlEnabled = false;
|
||||||
|
|
||||||
// TODO: update this
|
// TODO: update this
|
||||||
if (systemWideDirectUrlConfig.isEnabled())
|
if (systemWideDirectUrlConfig.isEnabled())
|
||||||
{
|
{
|
||||||
ContentData contentData = getContentData(nodeRef, ContentModel.PROP_CONTENT);
|
ContentData contentData = getContentData(nodeRef, propertyQName);
|
||||||
|
|
||||||
// check that the URL is available
|
// check that the URL is available
|
||||||
if (contentData == null || contentData.getContentUrl() == null)
|
if (contentData == null || contentData.getContentUrl() == null)
|
||||||
@@ -615,14 +615,15 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa
|
|||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, boolean attachment, Long validFor)
|
@Override
|
||||||
|
public DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, QName propertyQName, boolean attachment, Long validFor)
|
||||||
{
|
{
|
||||||
if (!systemWideDirectUrlConfig.isEnabled())
|
if (!systemWideDirectUrlConfig.isEnabled())
|
||||||
{
|
{
|
||||||
throw new DirectAccessUrlDisabledException("Direct access url isn't available.");
|
throw new DirectAccessUrlDisabledException("Direct access url isn't available.");
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentData contentData = getContentData(nodeRef, ContentModel.PROP_CONTENT);
|
ContentData contentData = getContentData(nodeRef, propertyQName);
|
||||||
// check that the content & URL is available
|
// check that the content & URL is available
|
||||||
if (contentData == null || contentData.getContentUrl() == null)
|
if (contentData == null || contentData.getContentUrl() == null)
|
||||||
{
|
{
|
||||||
|
@@ -27,6 +27,7 @@ package org.alfresco.service.cmr.repository;
|
|||||||
|
|
||||||
|
|
||||||
import org.alfresco.api.AlfrescoPublicApi;
|
import org.alfresco.api.AlfrescoPublicApi;
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.service.Auditable;
|
import org.alfresco.service.Auditable;
|
||||||
import org.alfresco.service.Experimental;
|
import org.alfresco.service.Experimental;
|
||||||
import org.alfresco.service.cmr.dictionary.InvalidTypeException;
|
import org.alfresco.service.cmr.dictionary.InvalidTypeException;
|
||||||
@@ -170,7 +171,20 @@ public interface ContentService
|
|||||||
*
|
*
|
||||||
* @return {@code true} if direct access URLs retrieving is supported for the node, {@code false} otherwise
|
* @return {@code true} if direct access URLs retrieving is supported for the node, {@code false} otherwise
|
||||||
*/
|
*/
|
||||||
boolean isContentDirectUrlEnabled(NodeRef nodeRef);
|
@Deprecated
|
||||||
|
default boolean isContentDirectUrlEnabled(NodeRef nodeRef)
|
||||||
|
{
|
||||||
|
return isContentDirectUrlEnabled(nodeRef, ContentModel.PROP_CONTENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the system and store supports the retrieving of a direct access {@code URL} for the given node.
|
||||||
|
*
|
||||||
|
* @param nodeRef a reference to a node having a content property
|
||||||
|
* @param propertyQName the name of the property, which must be of type <b>content</b>
|
||||||
|
* @return {@code true} if direct access URLs retrieving is supported for the node, {@code false} otherwise
|
||||||
|
*/
|
||||||
|
boolean isContentDirectUrlEnabled(NodeRef nodeRef, QName propertyQName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a presigned URL to directly access the content. It is up to the actual store
|
* Gets a presigned URL to directly access the content. It is up to the actual store
|
||||||
@@ -181,11 +195,27 @@ public interface ContentService
|
|||||||
* @return A direct access {@code URL} object for the content.
|
* @return A direct access {@code URL} object for the content.
|
||||||
* @throws UnsupportedOperationException if the store is unable to provide the information.
|
* @throws UnsupportedOperationException if the store is unable to provide the information.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
default DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, boolean attachment)
|
default DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, boolean attachment)
|
||||||
{
|
{
|
||||||
return requestContentDirectUrl(nodeRef, attachment, null);
|
return requestContentDirectUrl(nodeRef, attachment, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a presigned URL to directly access the content. It is up to the actual store
|
||||||
|
* implementation if it can fulfil this request with an expiry time or not.
|
||||||
|
*
|
||||||
|
* @param nodeRef Node ref for which to obtain the direct access {@code URL}.
|
||||||
|
* @param propertyQName the name of the property, which must be of type <b>content</b>
|
||||||
|
* @param attachment {@code true} if an attachment URL is requested, {@code false} for an embedded {@code URL}.
|
||||||
|
* @return A direct access {@code URL} object for the content.
|
||||||
|
* @throws UnsupportedOperationException if the store is unable to provide the information.
|
||||||
|
*/
|
||||||
|
default DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, QName propertyQName, boolean attachment)
|
||||||
|
{
|
||||||
|
return requestContentDirectUrl(nodeRef, propertyQName, attachment, null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a presigned URL to directly access the content. It is up to the actual store
|
* Gets a presigned URL to directly access the content. It is up to the actual store
|
||||||
* implementation if it can fulfil this request with an expiry time or not.
|
* implementation if it can fulfil this request with an expiry time or not.
|
||||||
@@ -197,7 +227,25 @@ public interface ContentService
|
|||||||
* @throws UnsupportedOperationException if the store is unable to provide the information.
|
* @throws UnsupportedOperationException if the store is unable to provide the information.
|
||||||
*/
|
*/
|
||||||
@Auditable(parameters = {"nodeRef", "validFor"})
|
@Auditable(parameters = {"nodeRef", "validFor"})
|
||||||
DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, boolean attachment, Long validFor);
|
@Deprecated
|
||||||
|
default public DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, boolean attachment, Long validFor)
|
||||||
|
{
|
||||||
|
return requestContentDirectUrl(nodeRef, ContentModel.PROP_CONTENT, attachment, validFor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a presigned URL to directly access the content. It is up to the actual store
|
||||||
|
* implementation if it can fulfil this request with an expiry time or not.
|
||||||
|
*
|
||||||
|
* @param nodeRef Node ref for which to obtain the direct access {@code URL}.
|
||||||
|
* @param propertyQName the name of the property, which must be of type <b>content</b>
|
||||||
|
* @param attachment {@code true} if an attachment URL is requested, {@code false} for an embedded {@code URL}.
|
||||||
|
* @param validFor The time at which the direct access {@code URL} will expire.
|
||||||
|
* @return A direct access {@code URL} object for the content.
|
||||||
|
* @throws UnsupportedOperationException if the store is unable to provide the information.
|
||||||
|
*/
|
||||||
|
@Auditable(parameters = {"nodeRef", "propertyQName", "validFor"})
|
||||||
|
DirectAccessUrl requestContentDirectUrl(NodeRef nodeRef, QName propertyQName, boolean attachment, Long validFor);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a key-value (String-String) collection of storage headers/properties with their respective values for a specific node reference.
|
* Gets a key-value (String-String) collection of storage headers/properties with their respective values for a specific node reference.
|
||||||
|
@@ -48,6 +48,7 @@ import org.alfresco.service.cmr.repository.ContentData;
|
|||||||
import org.alfresco.service.cmr.repository.DirectAccessUrl;
|
import org.alfresco.service.cmr.repository.DirectAccessUrl;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
@@ -78,6 +79,8 @@ public class ContentServiceImplUnitTest
|
|||||||
private static final String X_AMZ_HEADER_2 = "x-amz-header-2";
|
private static final String X_AMZ_HEADER_2 = "x-amz-header-2";
|
||||||
private static final String VALUE_2 = "value2";
|
private static final String VALUE_2 = "value2";
|
||||||
|
|
||||||
|
private static final QName PROP_CONTENT_QNAME = ContentModel.PROP_CONTENT;
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
private ContentServiceImpl contentService;
|
private ContentServiceImpl contentService;
|
||||||
|
|
||||||
@@ -131,15 +134,10 @@ public class ContentServiceImplUnitTest
|
|||||||
public void testRequestContentDirectUrl_SystemWideIsDisabled()
|
public void testRequestContentDirectUrl_SystemWideIsDisabled()
|
||||||
{
|
{
|
||||||
setupSystemWideDirectAccessConfig(DISABLED);
|
setupSystemWideDirectAccessConfig(DISABLED);
|
||||||
try
|
assertThrows(DirectAccessUrlDisabledException.class, () -> {
|
||||||
{
|
contentService.requestContentDirectUrl(NODE_REF, PROP_CONTENT_QNAME, true, 20L);
|
||||||
contentService.requestContentDirectUrl(NODE_REF, true, 20L);
|
});
|
||||||
fail("Expected DirectAccessUrlDisabledException");
|
verify(mockContentStore, never()).isContentDirectUrlEnabled();
|
||||||
}
|
|
||||||
catch (DirectAccessUrlDisabledException ex)
|
|
||||||
{
|
|
||||||
verify(mockContentStore, never()).isContentDirectUrlEnabled();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -148,7 +146,7 @@ public class ContentServiceImplUnitTest
|
|||||||
setupSystemWideDirectAccessConfig(ENABLED);
|
setupSystemWideDirectAccessConfig(ENABLED);
|
||||||
when(mockContentStore.isContentDirectUrlEnabled()).thenReturn(DISABLED);
|
when(mockContentStore.isContentDirectUrlEnabled()).thenReturn(DISABLED);
|
||||||
|
|
||||||
DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(NODE_REF, true, 20L);
|
DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(NODE_REF, PROP_CONTENT_QNAME,true, 20L);
|
||||||
assertNull(directAccessUrl);
|
assertNull(directAccessUrl);
|
||||||
verify(mockContentStore, never()).requestContentDirectUrl(anyString(), eq(true), anyString(), anyString(), anyLong());
|
verify(mockContentStore, never()).requestContentDirectUrl(anyString(), eq(true), anyString(), anyString(), anyLong());
|
||||||
}
|
}
|
||||||
@@ -159,7 +157,7 @@ public class ContentServiceImplUnitTest
|
|||||||
setupSystemWideDirectAccessConfig(ENABLED);
|
setupSystemWideDirectAccessConfig(ENABLED);
|
||||||
when(mockContentStore.isContentDirectUrlEnabled()).thenReturn(ENABLED);
|
when(mockContentStore.isContentDirectUrlEnabled()).thenReturn(ENABLED);
|
||||||
|
|
||||||
DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(NODE_REF, true, 20L);
|
DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(NODE_REF, PROP_CONTENT_QNAME, true, 20L);
|
||||||
assertNull(directAccessUrl);
|
assertNull(directAccessUrl);
|
||||||
verify(mockContentStore, times(1)).requestContentDirectUrl(anyString(), eq(true), anyString(), anyString(), anyLong());
|
verify(mockContentStore, times(1)).requestContentDirectUrl(anyString(), eq(true), anyString(), anyString(), anyLong());
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.version;
|
package org.alfresco.repo.version;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertThrows;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
import static org.mockito.MockitoAnnotations.openMocks;
|
import static org.mockito.MockitoAnnotations.openMocks;
|
||||||
|
|
||||||
@@ -63,6 +64,7 @@ public class ContentServiceImplTest extends BaseVersionStoreTest
|
|||||||
* Test content data
|
* Test content data
|
||||||
*/
|
*/
|
||||||
private final static String UPDATED_CONTENT = "This content has been updated with a new value.";
|
private final static String UPDATED_CONTENT = "This content has been updated with a new value.";
|
||||||
|
private static final QName QNAME = ContentModel.PROP_CONTENT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The version content store
|
* The version content store
|
||||||
@@ -157,34 +159,30 @@ public class ContentServiceImplTest extends BaseVersionStoreTest
|
|||||||
// Set the presigned URL to expire after one minute.
|
// Set the presigned URL to expire after one minute.
|
||||||
Long validFor = 60L;
|
Long validFor = 60L;
|
||||||
|
|
||||||
try
|
assertThrows("nodeRef has no content", IllegalArgumentException.class, () -> {
|
||||||
{
|
|
||||||
// Create a node without content
|
// Create a node without content
|
||||||
NodeRef nodeRef = this.dbNodeService
|
NodeRef nodeRef = this.dbNodeService
|
||||||
.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{test}MyNoContentNode"), TEST_TYPE_QNAME, this.nodeProperties).getChildRef();
|
.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{test}MyNoContentNode"), TEST_TYPE_QNAME, this.nodeProperties).getChildRef();
|
||||||
|
|
||||||
assertNull(contentService.requestContentDirectUrl(nodeRef, true, validFor));
|
assertNull(contentService.requestContentDirectUrl(nodeRef, QNAME, true, validFor));
|
||||||
fail("nodeRef has no content");
|
});
|
||||||
}
|
|
||||||
catch (IllegalArgumentException e)
|
|
||||||
{
|
|
||||||
// Expected exception
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
assertThrows("nodeRef is null", IllegalArgumentException.class, () -> {
|
||||||
{
|
assertNull(contentService.requestContentDirectUrl(null, null, true, null));
|
||||||
assertNull(contentService.requestContentDirectUrl(null, true, null));
|
});
|
||||||
fail("nodeRef is null");
|
|
||||||
}
|
assertThrows("propertyQName has no content", NullPointerException.class, () -> {
|
||||||
catch (IllegalArgumentException e)
|
// Create a node without content
|
||||||
{
|
NodeRef nodeRef = this.dbNodeService
|
||||||
// Expected exception
|
.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{test}MyNoContentNode"), TEST_TYPE_QNAME, this.nodeProperties).getChildRef();
|
||||||
}
|
|
||||||
|
contentService.requestContentDirectUrl(nodeRef, null, true, validFor);
|
||||||
|
});
|
||||||
|
|
||||||
// Create a node with content
|
// Create a node with content
|
||||||
NodeRef nodeRef = createNewVersionableNode();
|
NodeRef nodeRef = createNewVersionableNode();
|
||||||
|
|
||||||
assertNull(contentService.requestContentDirectUrl(nodeRef, true, null));
|
assertNull(contentService.requestContentDirectUrl(nodeRef, QNAME, true, null));
|
||||||
assertNull(contentService.requestContentDirectUrl(nodeRef, true, validFor));
|
assertNull(contentService.requestContentDirectUrl(nodeRef, QNAME, true, validFor));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user