diff --git a/data-model/src/main/java/org/alfresco/repo/content/ContentStore.java b/data-model/src/main/java/org/alfresco/repo/content/ContentStore.java index 56a43858f7..43a62881e8 100644 --- a/data-model/src/main/java/org/alfresco/repo/content/ContentStore.java +++ b/data-model/src/main/java/org/alfresco/repo/content/ContentStore.java @@ -269,9 +269,25 @@ public interface ContentStore * @return A direct access {@code URL} object for the content * @throws UnsupportedOperationException if the store is unable to provide the information */ + @Deprecated default DirectAccessUrl requestContentDirectUrl(String contentUrl, boolean attachment, String fileName) { - return requestContentDirectUrl(contentUrl, attachment, fileName, null); + return requestContentDirectUrl(contentUrl, attachment, fileName, null, 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 contentUrl A content store {@code URL} + * @param attachment {@code true} if an attachment URL is requested, {@code false} for an embedded {@code URL}. + * @param fileName File name of the content + * @return A direct access {@code URL} object for the content + * @throws UnsupportedOperationException if the store is unable to provide the information + */ + default DirectAccessUrl requestContentDirectUrl(String contentUrl, boolean attachment, String fileName, String mimetype) + { + return requestContentDirectUrl(contentUrl, attachment, fileName, mimetype, null); } /** @@ -285,7 +301,25 @@ public interface ContentStore * @return A direct access {@code URL} object for the content. * @throws UnsupportedOperationException if the store is unable to provide the information */ + @Deprecated default DirectAccessUrl requestContentDirectUrl(String contentUrl, boolean attachment, String fileName, Long validFor) + { + return requestContentDirectUrl(contentUrl, attachment, fileName, null, 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 contentUrl A content store {@code URL} + * @param attachment {@code true} if an attachment URL is requested, {@code false} for an embedded {@code URL}. + * @param fileName File name of the content + * @param mimetype Mimetype of the content + * @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 + */ + default DirectAccessUrl requestContentDirectUrl(String contentUrl, boolean attachment, String fileName, String mimetype, Long validFor) { throw new UnsupportedOperationException( "Retrieving direct access URLs is not supported by this content store."); diff --git a/repository/src/main/java/org/alfresco/repo/content/ContentServiceImpl.java b/repository/src/main/java/org/alfresco/repo/content/ContentServiceImpl.java index 8337bdd02d..f88f2810e5 100644 --- a/repository/src/main/java/org/alfresco/repo/content/ContentServiceImpl.java +++ b/repository/src/main/java/org/alfresco/repo/content/ContentServiceImpl.java @@ -605,7 +605,7 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa throw new IllegalArgumentException("The supplied nodeRef " + nodeRef + " has no content."); } - contentDirectUrlEnabled = (store.isContentDirectUrlEnabled(getContentUrl(nodeRef))); + contentDirectUrlEnabled = (store.isContentDirectUrlEnabled(contentData.getContentUrl())); } return contentDirectUrlEnabled; @@ -621,8 +621,17 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa throw new DirectAccessUrlDisabledException("Direct access url isn't available."); } - String contentUrl = getContentUrl(nodeRef); + ContentData contentData = getContentData(nodeRef, ContentModel.PROP_CONTENT); + // check that the content & URL is available + if (contentData == null || contentData.getContentUrl() == null) + { + throw new IllegalArgumentException("The supplied nodeRef " + nodeRef + " has no content."); + } + + String contentUrl = contentData.getContentUrl(); + String contentMimetype = contentData.getMimetype(); String fileName = getFileName(nodeRef); + validFor = adjustValidFor(validFor); DirectAccessUrl directAccessUrl = null; @@ -630,7 +639,7 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa { try { - directAccessUrl = store.requestContentDirectUrl(contentUrl, attachment, fileName, validFor); + directAccessUrl = store.requestContentDirectUrl(contentUrl, attachment, fileName, contentMimetype, validFor); } catch (UnsupportedOperationException ex) { @@ -640,19 +649,6 @@ public class ContentServiceImpl implements ContentService, ApplicationContextAwa return directAccessUrl; } - protected String getContentUrl(NodeRef nodeRef) - { - ContentData contentData = getContentData(nodeRef, ContentModel.PROP_CONTENT); - - // check that the URL is available - if (contentData == null || contentData.getContentUrl() == null) - { - throw new IllegalArgumentException("The supplied nodeRef " + nodeRef + " has no content."); - } - - return contentData.getContentUrl(); - } - protected String getFileName(NodeRef nodeRef) { String fileName = null; diff --git a/repository/src/main/java/org/alfresco/repo/content/caching/CachingContentStore.java b/repository/src/main/java/org/alfresco/repo/content/caching/CachingContentStore.java index c2b498391a..8297fb86f8 100644 --- a/repository/src/main/java/org/alfresco/repo/content/caching/CachingContentStore.java +++ b/repository/src/main/java/org/alfresco/repo/content/caching/CachingContentStore.java @@ -509,4 +509,12 @@ public class CachingContentStore implements ContentStore, ApplicationEventPublis { return backingStore.requestContentDirectUrl(contentUrl, attachment, fileName, validFor); } + + /** + * {@inheritDoc} + */ + public DirectAccessUrl requestContentDirectUrl(String contentUrl, boolean attachment, String fileName, String mimeType, Long validFor) + { + return backingStore.requestContentDirectUrl(contentUrl, attachment, fileName, mimeType, validFor); + } } diff --git a/repository/src/main/java/org/alfresco/repo/content/replication/AggregatingContentStore.java b/repository/src/main/java/org/alfresco/repo/content/replication/AggregatingContentStore.java index 342a299f5b..3528c74c1c 100644 --- a/repository/src/main/java/org/alfresco/repo/content/replication/AggregatingContentStore.java +++ b/repository/src/main/java/org/alfresco/repo/content/replication/AggregatingContentStore.java @@ -317,7 +317,7 @@ public class AggregatingContentStore extends AbstractContentStore return isContentDirectUrlEnabled; } - public DirectAccessUrl requestContentDirectUrl(String contentUrl, boolean attachment, String fileName, Long validFor) + public DirectAccessUrl requestContentDirectUrl(String contentUrl, boolean attachment, String fileName, String mimetype, Long validFor) { if (primaryStore == null) { @@ -337,7 +337,7 @@ public class AggregatingContentStore extends AbstractContentStore // Check the primary store try { - directAccessUrl = primaryStore.requestContentDirectUrl(contentUrl, attachment, fileName, validFor); + directAccessUrl = primaryStore.requestContentDirectUrl(contentUrl, attachment, fileName, mimetype, validFor); } catch (UnsupportedOperationException e) { @@ -360,7 +360,7 @@ public class AggregatingContentStore extends AbstractContentStore { try { - directAccessUrl = store.requestContentDirectUrl(contentUrl, attachment, fileName, validFor); + directAccessUrl = store.requestContentDirectUrl(contentUrl, attachment, fileName, mimetype, validFor); } catch (UnsupportedOperationException e) { diff --git a/repository/src/test/java/org/alfresco/repo/content/ContentServiceImplUnitTest.java b/repository/src/test/java/org/alfresco/repo/content/ContentServiceImplUnitTest.java index 63e6530715..aa2f9276eb 100644 --- a/repository/src/test/java/org/alfresco/repo/content/ContentServiceImplUnitTest.java +++ b/repository/src/test/java/org/alfresco/repo/content/ContentServiceImplUnitTest.java @@ -83,6 +83,7 @@ public class ContentServiceImplUnitTest openMocks(this); when(mockNodeService.getProperty(NODE_REF, ContentModel.PROP_CONTENT)).thenReturn(mockContentData); when(mockContentData.getContentUrl()).thenReturn("someContentUrl"); + when(mockContentData.getMimetype()).thenReturn("someMimetype"); when(mockNodeService.getProperty(NODE_REF, ContentModel.PROP_NAME)).thenReturn("someFilename"); } @@ -133,7 +134,7 @@ public class ContentServiceImplUnitTest DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(NODE_REF, true, 20L); assertNull(directAccessUrl); - verify(mockContentStore, never()).requestContentDirectUrl(anyString(), eq(true), anyString(), anyLong()); + verify(mockContentStore, never()).requestContentDirectUrl(anyString(), eq(true), anyString(), anyString(), anyLong()); } @Test @@ -144,7 +145,7 @@ public class ContentServiceImplUnitTest DirectAccessUrl directAccessUrl = contentService.requestContentDirectUrl(NODE_REF, true, 20L); assertNull(directAccessUrl); - verify(mockContentStore, times(1)).requestContentDirectUrl(anyString(), eq(true), anyString(), anyLong()); + verify(mockContentStore, times(1)).requestContentDirectUrl(anyString(), eq(true), anyString(), anyString(), anyLong()); } /* Helper method to set system-wide direct access url configuration settings */ diff --git a/repository/src/test/java/org/alfresco/repo/content/caching/CachingContentStoreTest.java b/repository/src/test/java/org/alfresco/repo/content/caching/CachingContentStoreTest.java index e7cec2bbe0..8f92a4e633 100644 --- a/repository/src/test/java/org/alfresco/repo/content/caching/CachingContentStoreTest.java +++ b/repository/src/test/java/org/alfresco/repo/content/caching/CachingContentStoreTest.java @@ -505,8 +505,8 @@ public class CachingContentStoreTest { try { - when(backingStore.requestContentDirectUrl(anyString(), eq(true), anyString(), anyLong())).thenThrow(new UnsupportedOperationException()); - cachingStore.requestContentDirectUrl("url", true,"someFile", 30L); + when(backingStore.requestContentDirectUrl(anyString(), eq(true), anyString(), anyString(), anyLong())).thenThrow(new UnsupportedOperationException()); + cachingStore.requestContentDirectUrl("url", true,"someFile", "someMimetype", 30L); fail(); } catch (UnsupportedOperationException e) @@ -518,7 +518,7 @@ public class CachingContentStoreTest @Test public void getRequestContentDirectUrl() { - when(backingStore.requestContentDirectUrl(anyString(), eq(true), anyString(), anyLong())).thenReturn(new DirectAccessUrl()); - cachingStore.requestContentDirectUrl("url", true,"someFile", 30L); + when(backingStore.requestContentDirectUrl(anyString(), eq(true), anyString(), anyString(), anyLong())).thenReturn(new DirectAccessUrl()); + cachingStore.requestContentDirectUrl("url", true,"someFile", "someMimeType", 30L); } } diff --git a/repository/src/test/java/org/alfresco/repo/content/replication/AggregatingContentStoreTest.java b/repository/src/test/java/org/alfresco/repo/content/replication/AggregatingContentStoreTest.java index ccf627474c..2d8f2d15bd 100644 --- a/repository/src/test/java/org/alfresco/repo/content/replication/AggregatingContentStoreTest.java +++ b/repository/src/test/java/org/alfresco/repo/content/replication/AggregatingContentStoreTest.java @@ -227,14 +227,14 @@ public class AggregatingContentStoreTest extends AbstractWritableContentStoreTes UnsupportedContentUrlException unsupportedContentUrlExc = new UnsupportedContentUrlException(aggStore, ""); // By default it is unsupported - DirectAccessUrl directAccessUrl = aggStore.requestContentDirectUrl("url", true, "anyfilename", 30L); + DirectAccessUrl directAccessUrl = aggStore.requestContentDirectUrl("url", true, "anyfilename", "anyMimetype", 30L); assertNull(directAccessUrl); // Direct access not supported try { - when(primaryStoreMock.requestContentDirectUrl(eq("urlDANotSupported"), any(), any(), any())).thenThrow(unsupportedExc); - when(secondaryStoreMock.requestContentDirectUrl(eq("urlDANotSupported"), any(), any(), any())).thenThrow(unsupportedExc); + when(primaryStoreMock.requestContentDirectUrl(any(), any(), any(), any(), any())).thenThrow(unsupportedExc); + when(secondaryStoreMock.requestContentDirectUrl(eq("urlDANotSupported"), any(), any(), any(), any())).thenThrow(unsupportedExc); aggStore.requestContentDirectUrl(eq("urlDANotSupported"), true, "anyfilename", 30L); fail(); } @@ -245,9 +245,9 @@ public class AggregatingContentStoreTest extends AbstractWritableContentStoreTes try { - when(primaryStoreMock.requestContentDirectUrl(eq("urlDANotSupported"), any(), any(), any())).thenThrow(unsupportedContentUrlExc); - when(secondaryStoreMock.requestContentDirectUrl(eq("urlDANotSupported"), any(), any(), any())).thenThrow(unsupportedExc); - aggStore.requestContentDirectUrl("urlDANotSupported", true, "anyfilename", 30L); + when(primaryStoreMock.requestContentDirectUrl(eq("urlDANotSupported"), any(), any(), any(), any())).thenThrow(unsupportedContentUrlExc); + when(secondaryStoreMock.requestContentDirectUrl(eq("urlDANotSupported"), any(), any(), any(), any())).thenThrow(unsupportedExc); + aggStore.requestContentDirectUrl("urlDANotSupported", true, "anyfilename", "anyMimetype", 30L); fail(); } catch (UnsupportedOperationException e) @@ -257,9 +257,9 @@ public class AggregatingContentStoreTest extends AbstractWritableContentStoreTes try { - when(primaryStoreMock.requestContentDirectUrl(eq("urlDANotSupported"), any(), any(), any())).thenThrow(unsupportedExc); - when(secondaryStoreMock.requestContentDirectUrl(eq("urlDANotSupported"), any(), any(), any())).thenThrow(unsupportedContentUrlExc); - aggStore.requestContentDirectUrl("urlDANotSupported", true, "anyfilename", 30L); + when(primaryStoreMock.requestContentDirectUrl(eq("urlDANotSupported"), any(), any(), any(), any())).thenThrow(unsupportedExc); + when(secondaryStoreMock.requestContentDirectUrl(eq("urlDANotSupported"), any(), any(), any(), any())).thenThrow(unsupportedContentUrlExc); + aggStore.requestContentDirectUrl("urlDANotSupported", true, "anyfilename", "anyMimetype", 30L); fail(); } catch (UnsupportedOperationException e) @@ -270,9 +270,9 @@ public class AggregatingContentStoreTest extends AbstractWritableContentStoreTes // Content url not supported try { - when(primaryStoreMock.requestContentDirectUrl(eq("urlNotSupported"), any(), any(), any())).thenThrow(unsupportedContentUrlExc); - when(secondaryStoreMock.requestContentDirectUrl(eq("urlNotSupported"), any(), any(), any())).thenThrow(unsupportedContentUrlExc); - aggStore.requestContentDirectUrl("urlNotSupported", true, "anyfilename", 30L); + when(primaryStoreMock.requestContentDirectUrl(eq("urlNotSupported"), any(), any(), any(), any())).thenThrow(unsupportedContentUrlExc); + when(secondaryStoreMock.requestContentDirectUrl(eq("urlNotSupported"), any(), any(), any(), any())).thenThrow(unsupportedContentUrlExc); + aggStore.requestContentDirectUrl("urlNotSupported", true, "anyfilename", "anyMimetype", 30L); fail(); } catch (UnsupportedContentUrlException e) @@ -280,31 +280,31 @@ public class AggregatingContentStoreTest extends AbstractWritableContentStoreTes // Expected } - when(primaryStoreMock.requestContentDirectUrl(eq("urlPriSupported"), any(), any(), any())).thenReturn(new DirectAccessUrl()); - when(secondaryStoreMock.requestContentDirectUrl(eq("urlPriSupported"), any(), any(), any())).thenThrow(unsupportedExc); - directAccessUrl = aggStore.requestContentDirectUrl("urlPriSupported", true, "anyfilename", 30L); + when(primaryStoreMock.requestContentDirectUrl(eq("urlPriSupported"), any(), any(), any(), any())).thenReturn(new DirectAccessUrl()); + when(secondaryStoreMock.requestContentDirectUrl(eq("urlPriSupported"), any(), any(), any(), any())).thenThrow(unsupportedExc); + directAccessUrl = aggStore.requestContentDirectUrl("urlPriSupported", true, "anyfilename", "anyMimetype", 30L); assertNotNull(directAccessUrl); - when(primaryStoreMock.requestContentDirectUrl(eq("urlPriSupported"), any(), any(), any())).thenReturn(new DirectAccessUrl()); - when(secondaryStoreMock.requestContentDirectUrl(eq("urlPriSupported"), any(), any(), any())).thenThrow(unsupportedContentUrlExc); - directAccessUrl = aggStore.requestContentDirectUrl("urlPriSupported", true, "anyfilename", 30L); + when(primaryStoreMock.requestContentDirectUrl(eq("urlPriSupported"), any(), any(), any(), any())).thenReturn(new DirectAccessUrl()); + when(secondaryStoreMock.requestContentDirectUrl(eq("urlPriSupported"), any(), any(), any(), any())).thenThrow(unsupportedContentUrlExc); + directAccessUrl = aggStore.requestContentDirectUrl("urlPriSupported", true, "anyfilename", "anyMimetype", 30L); assertNotNull(directAccessUrl); - when(primaryStoreMock.requestContentDirectUrl(eq("urlSecSupported"), any(), any(), any())).thenThrow(unsupportedExc); - when(secondaryStoreMock.requestContentDirectUrl(eq("urlSecSupported"), any(), any(), any())).thenReturn(new DirectAccessUrl()); - directAccessUrl = aggStore.requestContentDirectUrl("urlSecSupported", true, "anyfilename", 30L); + when(primaryStoreMock.requestContentDirectUrl(eq("urlSecSupported"), any(), any(), any(), any())).thenThrow(unsupportedExc); + when(secondaryStoreMock.requestContentDirectUrl(eq("urlSecSupported"), any(), any(), any(), any())).thenReturn(new DirectAccessUrl()); + directAccessUrl = aggStore.requestContentDirectUrl("urlSecSupported", true, "anyfilename", "anyMimetype", 30L); assertNotNull(directAccessUrl); - when(primaryStoreMock.requestContentDirectUrl(eq("urlSecSupported"), any(), any(), any())).thenThrow(unsupportedContentUrlExc); - when(secondaryStoreMock.requestContentDirectUrl(eq("urlSecSupported"), any(), any(), any())).thenReturn(new DirectAccessUrl()); - directAccessUrl = aggStore.requestContentDirectUrl("urlSecSupported", true, "anyfilename", 30L); + when(primaryStoreMock.requestContentDirectUrl(eq("urlSecSupported"), any(), any(), any(), any())).thenThrow(unsupportedContentUrlExc); + when(secondaryStoreMock.requestContentDirectUrl(eq("urlSecSupported"), any(), any(), any(), any())).thenReturn(new DirectAccessUrl()); + directAccessUrl = aggStore.requestContentDirectUrl("urlSecSupported", true, "anyfilename", "anyMimetype", 30L); assertNotNull(directAccessUrl); - when(primaryStoreMock.requestContentDirectUrl(eq("urlPriSupported"), any(), any(), any())).thenReturn(new DirectAccessUrl()); - when(secondaryStoreMock.requestContentDirectUrl(eq("urlSecSupported"), any(), any(), any())).thenReturn(new DirectAccessUrl()); - directAccessUrl = aggStore.requestContentDirectUrl("urlPriSupported", true, "anyfilename", 30L); + when(primaryStoreMock.requestContentDirectUrl(eq("urlPriSupported"), any(), any(), any(), any())).thenReturn(new DirectAccessUrl()); + when(secondaryStoreMock.requestContentDirectUrl(eq("urlSecSupported"), any(), any(), any(), any())).thenReturn(new DirectAccessUrl()); + directAccessUrl = aggStore.requestContentDirectUrl("urlPriSupported", true, "anyfilename", "anyMimetype", 30L); assertNotNull(directAccessUrl); - directAccessUrl = aggStore.requestContentDirectUrl("urlSecSupported", true, "anyfilename", 30L); + directAccessUrl = aggStore.requestContentDirectUrl("urlSecSupported", true, "anyfilename", "anyMimetype", 30L); assertNotNull(directAccessUrl); } }