mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-09-17 14:21:39 +00:00
ACS-1604 : Update & tests for AggregatingContentStore (#486)
This commit is contained in:
committed by
Andrea Ligios
parent
0b840643f9
commit
57dbd4d12f
@@ -27,6 +27,7 @@ package org.alfresco.repo.content.replication;
|
|||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import java.util.concurrent.locks.ReadWriteLock;
|
import java.util.concurrent.locks.ReadWriteLock;
|
||||||
@@ -66,7 +67,8 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
*/
|
*/
|
||||||
public class AggregatingContentStore extends AbstractContentStore
|
public class AggregatingContentStore extends AbstractContentStore
|
||||||
{
|
{
|
||||||
private static Log logger = LogFactory.getLog(AggregatingContentStore.class);
|
private static final Log logger = LogFactory.getLog(AggregatingContentStore.class);
|
||||||
|
private static final String REPLICATING_CONTENT_STORE_NOT_INITIALISED = "ReplicatingContentStore not initialised";
|
||||||
|
|
||||||
private ContentStore primaryStore;
|
private ContentStore primaryStore;
|
||||||
private List<ContentStore> secondaryStores;
|
private List<ContentStore> secondaryStores;
|
||||||
@@ -135,7 +137,7 @@ public class AggregatingContentStore extends AbstractContentStore
|
|||||||
{
|
{
|
||||||
if (primaryStore == null)
|
if (primaryStore == null)
|
||||||
{
|
{
|
||||||
throw new AlfrescoRuntimeException("ReplicatingContentStore not initialised");
|
throw new AlfrescoRuntimeException(REPLICATING_CONTENT_STORE_NOT_INITIALISED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get a read lock so that we are sure that no replication is underway
|
// get a read lock so that we are sure that no replication is underway
|
||||||
@@ -170,11 +172,12 @@ public class AggregatingContentStore extends AbstractContentStore
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean exists(String contentUrl)
|
public boolean exists(String contentUrl)
|
||||||
{
|
{
|
||||||
if (primaryStore == null)
|
if (primaryStore == null)
|
||||||
{
|
{
|
||||||
throw new AlfrescoRuntimeException("ReplicatingContentStore not initialised");
|
throw new AlfrescoRuntimeException(REPLICATING_CONTENT_STORE_NOT_INITIALISED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get a read lock so that we are sure that no replication is underway
|
// get a read lock so that we are sure that no replication is underway
|
||||||
@@ -240,6 +243,7 @@ public class AggregatingContentStore extends AbstractContentStore
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public ContentWriter getWriter(ContentContext ctx)
|
public ContentWriter getWriter(ContentContext ctx)
|
||||||
{
|
{
|
||||||
// get the writer
|
// get the writer
|
||||||
@@ -254,6 +258,7 @@ public class AggregatingContentStore extends AbstractContentStore
|
|||||||
*
|
*
|
||||||
* @return Returns the value returned by the delete on the primary store.
|
* @return Returns the value returned by the delete on the primary store.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean delete(String contentUrl) throws ContentIOException
|
public boolean delete(String contentUrl) throws ContentIOException
|
||||||
{
|
{
|
||||||
// delete on the primary store
|
// delete on the primary store
|
||||||
@@ -269,6 +274,7 @@ public class AggregatingContentStore extends AbstractContentStore
|
|||||||
/**
|
/**
|
||||||
* @return Returns <tt>true</tt> if at least one store supports direct access
|
* @return Returns <tt>true</tt> if at least one store supports direct access
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean isDirectAccessSupported()
|
public boolean isDirectAccessSupported()
|
||||||
{
|
{
|
||||||
// Check the primary store
|
// Check the primary store
|
||||||
@@ -293,11 +299,12 @@ public class AggregatingContentStore extends AbstractContentStore
|
|||||||
return isDirectAccessSupported;
|
return isDirectAccessSupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public DirectAccessUrl getDirectAccessUrl(String contentUrl, Date expiresAt)
|
public DirectAccessUrl getDirectAccessUrl(String contentUrl, Date expiresAt)
|
||||||
{
|
{
|
||||||
if (primaryStore == null)
|
if (primaryStore == null)
|
||||||
{
|
{
|
||||||
throw new AlfrescoRuntimeException("ReplicatingContentStore not initialised");
|
throw new AlfrescoRuntimeException(REPLICATING_CONTENT_STORE_NOT_INITIALISED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get a read lock so that we are sure that no replication is underway
|
// get a read lock so that we are sure that no replication is underway
|
||||||
@@ -380,25 +387,9 @@ public class AggregatingContentStore extends AbstractContentStore
|
|||||||
@Override
|
@Override
|
||||||
public boolean isStorageClassesSupported(Set<String> storageClasses)
|
public boolean isStorageClassesSupported(Set<String> storageClasses)
|
||||||
{
|
{
|
||||||
// Check the primary store
|
// We only need to provide info about the primary store,
|
||||||
boolean isStorageClassesSupported = primaryStore.isStorageClassesSupported(storageClasses);
|
// because the aggregating CS only allows to be written in the primary
|
||||||
|
return primaryStore.isStorageClassesSupported(storageClasses);
|
||||||
if (!isStorageClassesSupported)
|
|
||||||
{
|
|
||||||
// Storage class is not supported by the primary store so we have to check the
|
|
||||||
// other stores
|
|
||||||
for (ContentStore store : secondaryStores)
|
|
||||||
{
|
|
||||||
isStorageClassesSupported = store.isDirectAccessSupported();
|
|
||||||
|
|
||||||
if (isStorageClassesSupported)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return isStorageClassesSupported;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -408,4 +399,91 @@ public class AggregatingContentStore extends AbstractContentStore
|
|||||||
// because the aggregating CS only allows to be written in the primary
|
// because the aggregating CS only allows to be written in the primary
|
||||||
return primaryStore.getSupportedStorageClasses();
|
return primaryStore.getSupportedStorageClasses();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateStorageClasses(String contentUrl, Set<String> storageClasses, Map<String, Object> parameters)
|
||||||
|
{
|
||||||
|
primaryStore.updateStorageClasses(contentUrl, storageClasses, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> findStorageClasses(String contentUrl)
|
||||||
|
{
|
||||||
|
if (primaryStore == null)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException(REPLICATING_CONTENT_STORE_NOT_INITIALISED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get a read lock so that we are sure that no replication is underway
|
||||||
|
readLock.lock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Keep track of the unsupported state of the content URL - it might be a rubbish URL
|
||||||
|
boolean contentUrlSupported = true;
|
||||||
|
Set<String> storageClasses = null;
|
||||||
|
|
||||||
|
// Check the primary store
|
||||||
|
try
|
||||||
|
{
|
||||||
|
storageClasses = primaryStore.findStorageClasses(contentUrl);
|
||||||
|
}
|
||||||
|
catch (UnsupportedContentUrlException e)
|
||||||
|
{
|
||||||
|
// The store can't handle the content URL
|
||||||
|
contentUrlSupported = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (storageClasses != null)
|
||||||
|
{
|
||||||
|
return storageClasses;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the content is not in the primary store so we have to go looking for it
|
||||||
|
for (ContentStore store : secondaryStores)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
storageClasses = store.findStorageClasses(contentUrl);
|
||||||
|
}
|
||||||
|
catch (UnsupportedContentUrlException e)
|
||||||
|
{
|
||||||
|
// The store can't handle the content URL
|
||||||
|
contentUrlSupported = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (storageClasses != null)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (storageClasses == null && !contentUrlSupported)
|
||||||
|
{
|
||||||
|
// The content URL was not supported
|
||||||
|
throw new UnsupportedContentUrlException(this, contentUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return storageClasses;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
readLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Set<String>, Set<Set<String>>> getStorageClassesTransitions()
|
||||||
|
{
|
||||||
|
// We only need to provide info about the primary store,
|
||||||
|
// because the aggregating CS only allows to be written in the primary
|
||||||
|
return primaryStore.getStorageClassesTransitions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Set<String>, Set<Set<String>>> findStorageClassesTransitions(String contentUrl)
|
||||||
|
{
|
||||||
|
// We only need to provide info about the primary store,
|
||||||
|
// because the aggregating CS only allows to be written in the primary
|
||||||
|
return primaryStore.findStorageClassesTransitions(contentUrl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.content.replication;
|
package org.alfresco.repo.content.replication;
|
||||||
|
|
||||||
|
import static java.util.Collections.emptyMap;
|
||||||
|
import static java.util.Collections.emptySet;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
@@ -32,15 +34,15 @@ import static org.junit.Assert.assertNull;
|
|||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.never;
|
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.verifyNoInteractions;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@@ -57,12 +59,11 @@ import org.alfresco.util.GUID;
|
|||||||
import org.alfresco.util.TempFileProvider;
|
import org.alfresco.util.TempFileProvider;
|
||||||
import org.alfresco.util.testing.category.NeverRunsTests;
|
import org.alfresco.util.testing.category.NeverRunsTests;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.experimental.categories.Category;
|
import org.junit.experimental.categories.Category;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.MockitoJUnit;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
import org.mockito.junit.MockitoRule;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests read and write functionality for the aggregating store.
|
* Tests read and write functionality for the aggregating store.
|
||||||
@@ -74,6 +75,7 @@ import org.mockito.junit.MockitoRule;
|
|||||||
* @author Mark Rogers
|
* @author Mark Rogers
|
||||||
*/
|
*/
|
||||||
@Category({OwnJVMTestsCategory.class, NeverRunsTests.class})
|
@Category({OwnJVMTestsCategory.class, NeverRunsTests.class})
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class AggregatingContentStoreTest extends AbstractWritableContentStoreTest
|
public class AggregatingContentStoreTest extends AbstractWritableContentStoreTest
|
||||||
{
|
{
|
||||||
private static final String SOME_CONTENT = "The No. 1 Ladies' Detective Agency";
|
private static final String SOME_CONTENT = "The No. 1 Ladies' Detective Agency";
|
||||||
@@ -86,11 +88,8 @@ public class AggregatingContentStoreTest extends AbstractWritableContentStoreTes
|
|||||||
ContentStore primaryStoreMock;
|
ContentStore primaryStoreMock;
|
||||||
@Mock
|
@Mock
|
||||||
ContentStore secondaryStoreMock;
|
ContentStore secondaryStoreMock;
|
||||||
@Mock
|
|
||||||
AggregatingContentStore aggregatingContentStoreMock;
|
|
||||||
|
|
||||||
@Rule
|
AggregatingContentStore aggregatingContentStoreMock;
|
||||||
public MockitoRule rule = MockitoJUnit.rule();
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before() throws Exception
|
public void before() throws Exception
|
||||||
@@ -107,10 +106,15 @@ public class AggregatingContentStoreTest extends AbstractWritableContentStoreTes
|
|||||||
FileContentStore store = new FileContentStore(ctx, storeDir);
|
FileContentStore store = new FileContentStore(ctx, storeDir);
|
||||||
secondaryStores.add(store);
|
secondaryStores.add(store);
|
||||||
}
|
}
|
||||||
// Create the aggregating store
|
// Create the aggregating store for Spring tests
|
||||||
aggregatingStore = new AggregatingContentStore();
|
aggregatingStore = new AggregatingContentStore();
|
||||||
aggregatingStore.setPrimaryStore(primaryStore);
|
aggregatingStore.setPrimaryStore(primaryStore);
|
||||||
aggregatingStore.setSecondaryStores(secondaryStores);
|
aggregatingStore.setSecondaryStores(secondaryStores);
|
||||||
|
|
||||||
|
// Create a mocked aggregating store
|
||||||
|
aggregatingContentStoreMock = new AggregatingContentStore();
|
||||||
|
aggregatingContentStoreMock.setPrimaryStore(primaryStoreMock);
|
||||||
|
aggregatingContentStoreMock.setSecondaryStores(List.of(secondaryStoreMock));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -145,6 +149,7 @@ public class AggregatingContentStoreTest extends AbstractWritableContentStoreTes
|
|||||||
return writer.getContentUrl();
|
return writer.getContentUrl();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testAddContent() throws Exception
|
public void testAddContent() throws Exception
|
||||||
{
|
{
|
||||||
ContentWriter writer = getWriter();
|
ContentWriter writer = getWriter();
|
||||||
@@ -166,6 +171,7 @@ public class AggregatingContentStoreTest extends AbstractWritableContentStoreTes
|
|||||||
assertEquals("Reader state differs from expected: " + reader, mustExist, reader.exists());
|
assertEquals("Reader state differs from expected: " + reader, mustExist, reader.exists());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testDelete() throws Exception
|
public void testDelete() throws Exception
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -182,6 +188,7 @@ public class AggregatingContentStoreTest extends AbstractWritableContentStoreTes
|
|||||||
checkForUrl(contentUrl, false);
|
checkForUrl(contentUrl, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testReadFromSecondaryStore()
|
public void testReadFromSecondaryStore()
|
||||||
{
|
{
|
||||||
// pick a secondary store and write some content to it
|
// pick a secondary store and write some content to it
|
||||||
@@ -194,45 +201,43 @@ public class AggregatingContentStoreTest extends AbstractWritableContentStoreTes
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsDirectAccessSupported()
|
public void testDirectAccessUnsupportedByDefault()
|
||||||
{
|
{
|
||||||
// Create the aggregating store
|
|
||||||
AggregatingContentStore aggStore = new AggregatingContentStore();
|
|
||||||
aggStore.setPrimaryStore(primaryStoreMock);
|
|
||||||
aggStore.setSecondaryStores(List.of(secondaryStoreMock));
|
|
||||||
|
|
||||||
// By default it is unsupported
|
// By default it is unsupported
|
||||||
assertFalse(aggStore.isDirectAccessSupported());
|
assertFalse(aggregatingContentStoreMock.isDirectAccessSupported());
|
||||||
|
verify(primaryStoreMock, times(1)).isDirectAccessSupported();
|
||||||
|
verify(secondaryStoreMock, times(1)).isDirectAccessSupported();
|
||||||
|
}
|
||||||
|
|
||||||
// Supported if at least one store supports direct access
|
@Test
|
||||||
|
public void testIsDirectAccessSupportedByPrimaryStore()
|
||||||
{
|
{
|
||||||
when(primaryStoreMock.isDirectAccessSupported()).thenReturn(false);
|
when(primaryStoreMock.isDirectAccessSupported()).thenReturn(false);
|
||||||
when(secondaryStoreMock.isDirectAccessSupported()).thenReturn(true);
|
when(secondaryStoreMock.isDirectAccessSupported()).thenReturn(true);
|
||||||
assertTrue(aggStore.isDirectAccessSupported());
|
|
||||||
|
|
||||||
when(primaryStoreMock.isDirectAccessSupported()).thenReturn(true);
|
assertTrue(aggregatingContentStoreMock.isDirectAccessSupported());
|
||||||
when(secondaryStoreMock.isDirectAccessSupported()).thenReturn(true);
|
verify(primaryStoreMock, times(1)).isDirectAccessSupported();
|
||||||
assertTrue(aggStore.isDirectAccessSupported());
|
verify(secondaryStoreMock, times(1)).isDirectAccessSupported();
|
||||||
|
|
||||||
when(primaryStoreMock.isDirectAccessSupported()).thenReturn(true);
|
|
||||||
when(secondaryStoreMock.isDirectAccessSupported()).thenReturn(false);
|
|
||||||
assertTrue(aggStore.isDirectAccessSupported());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsDirectAccessSupportedBySecondaryStore()
|
||||||
|
{
|
||||||
|
when(primaryStoreMock.isDirectAccessSupported()).thenReturn(true);
|
||||||
|
|
||||||
|
assertTrue(aggregatingContentStoreMock.isDirectAccessSupported());
|
||||||
|
verify(primaryStoreMock, times(1)).isDirectAccessSupported();
|
||||||
|
verifyNoInteractions(secondaryStoreMock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetDirectAccessUrl()
|
public void testGetDirectAccessUrl()
|
||||||
{
|
{
|
||||||
// Create the aggregating store
|
|
||||||
AggregatingContentStore aggStore = new AggregatingContentStore();
|
|
||||||
aggStore.setPrimaryStore(primaryStoreMock);
|
|
||||||
aggStore.setSecondaryStores(List.of(secondaryStoreMock));
|
|
||||||
|
|
||||||
UnsupportedOperationException unsupportedExc = new UnsupportedOperationException();
|
UnsupportedOperationException unsupportedExc = new UnsupportedOperationException();
|
||||||
UnsupportedContentUrlException unsupportedContentUrlExc = new UnsupportedContentUrlException(aggStore, "");
|
UnsupportedContentUrlException unsupportedContentUrlExc = new UnsupportedContentUrlException(aggregatingContentStoreMock, "");
|
||||||
|
|
||||||
// By default it is unsupported
|
// By default it is unsupported
|
||||||
DirectAccessUrl directAccessUrl = aggStore.getDirectAccessUrl("url", null);
|
DirectAccessUrl directAccessUrl = aggregatingContentStoreMock.getDirectAccessUrl("url", null);
|
||||||
assertNull(directAccessUrl);
|
assertNull(directAccessUrl);
|
||||||
|
|
||||||
// Direct access not supported
|
// Direct access not supported
|
||||||
@@ -240,7 +245,7 @@ public class AggregatingContentStoreTest extends AbstractWritableContentStoreTes
|
|||||||
{
|
{
|
||||||
when(primaryStoreMock.getDirectAccessUrl(eq("urlDANotSupported"), any())).thenThrow(unsupportedExc);
|
when(primaryStoreMock.getDirectAccessUrl(eq("urlDANotSupported"), any())).thenThrow(unsupportedExc);
|
||||||
when(secondaryStoreMock.getDirectAccessUrl(eq("urlDANotSupported"), any())).thenThrow(unsupportedExc);
|
when(secondaryStoreMock.getDirectAccessUrl(eq("urlDANotSupported"), any())).thenThrow(unsupportedExc);
|
||||||
aggStore.getDirectAccessUrl("urlDANotSupported", null);
|
aggregatingContentStoreMock.getDirectAccessUrl("urlDANotSupported", null);
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
catch (UnsupportedOperationException e)
|
catch (UnsupportedOperationException e)
|
||||||
@@ -252,7 +257,7 @@ public class AggregatingContentStoreTest extends AbstractWritableContentStoreTes
|
|||||||
{
|
{
|
||||||
when(primaryStoreMock.getDirectAccessUrl(eq("urlDANotSupported"), any())).thenThrow(unsupportedContentUrlExc);
|
when(primaryStoreMock.getDirectAccessUrl(eq("urlDANotSupported"), any())).thenThrow(unsupportedContentUrlExc);
|
||||||
when(secondaryStoreMock.getDirectAccessUrl(eq("urlDANotSupported"), any())).thenThrow(unsupportedExc);
|
when(secondaryStoreMock.getDirectAccessUrl(eq("urlDANotSupported"), any())).thenThrow(unsupportedExc);
|
||||||
aggStore.getDirectAccessUrl("urlDANotSupported", null);
|
aggregatingContentStoreMock.getDirectAccessUrl("urlDANotSupported", null);
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
catch (UnsupportedOperationException e)
|
catch (UnsupportedOperationException e)
|
||||||
@@ -264,7 +269,7 @@ public class AggregatingContentStoreTest extends AbstractWritableContentStoreTes
|
|||||||
{
|
{
|
||||||
when(primaryStoreMock.getDirectAccessUrl(eq("urlDANotSupported"), any())).thenThrow(unsupportedExc);
|
when(primaryStoreMock.getDirectAccessUrl(eq("urlDANotSupported"), any())).thenThrow(unsupportedExc);
|
||||||
when(secondaryStoreMock.getDirectAccessUrl(eq("urlDANotSupported"), any())).thenThrow(unsupportedContentUrlExc);
|
when(secondaryStoreMock.getDirectAccessUrl(eq("urlDANotSupported"), any())).thenThrow(unsupportedContentUrlExc);
|
||||||
aggStore.getDirectAccessUrl("urlDANotSupported", null);
|
aggregatingContentStoreMock.getDirectAccessUrl("urlDANotSupported", null);
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
catch (UnsupportedOperationException e)
|
catch (UnsupportedOperationException e)
|
||||||
@@ -277,7 +282,7 @@ public class AggregatingContentStoreTest extends AbstractWritableContentStoreTes
|
|||||||
{
|
{
|
||||||
when(primaryStoreMock.getDirectAccessUrl(eq("urlNotSupported"), any())).thenThrow(unsupportedContentUrlExc);
|
when(primaryStoreMock.getDirectAccessUrl(eq("urlNotSupported"), any())).thenThrow(unsupportedContentUrlExc);
|
||||||
when(secondaryStoreMock.getDirectAccessUrl(eq("urlNotSupported"), any())).thenThrow(unsupportedContentUrlExc);
|
when(secondaryStoreMock.getDirectAccessUrl(eq("urlNotSupported"), any())).thenThrow(unsupportedContentUrlExc);
|
||||||
aggStore.getDirectAccessUrl("urlNotSupported", null);
|
aggregatingContentStoreMock.getDirectAccessUrl("urlNotSupported", null);
|
||||||
fail();
|
fail();
|
||||||
}
|
}
|
||||||
catch (UnsupportedContentUrlException e)
|
catch (UnsupportedContentUrlException e)
|
||||||
@@ -286,30 +291,28 @@ public class AggregatingContentStoreTest extends AbstractWritableContentStoreTes
|
|||||||
}
|
}
|
||||||
|
|
||||||
when(primaryStoreMock.getDirectAccessUrl(eq("urlPriSupported"), any())).thenReturn(new DirectAccessUrl());
|
when(primaryStoreMock.getDirectAccessUrl(eq("urlPriSupported"), any())).thenReturn(new DirectAccessUrl());
|
||||||
when(secondaryStoreMock.getDirectAccessUrl(eq("urlPriSupported"), any())).thenThrow(unsupportedExc);
|
directAccessUrl = aggregatingContentStoreMock.getDirectAccessUrl("urlPriSupported", null);
|
||||||
directAccessUrl = aggStore.getDirectAccessUrl("urlPriSupported", null);
|
|
||||||
assertNotNull(directAccessUrl);
|
assertNotNull(directAccessUrl);
|
||||||
|
|
||||||
when(primaryStoreMock.getDirectAccessUrl(eq("urlPriSupported"), any())).thenReturn(new DirectAccessUrl());
|
when(primaryStoreMock.getDirectAccessUrl(eq("urlPriSupported"), any())).thenReturn(new DirectAccessUrl());
|
||||||
when(secondaryStoreMock.getDirectAccessUrl(eq("urlPriSupported"), any())).thenThrow(unsupportedContentUrlExc);
|
directAccessUrl = aggregatingContentStoreMock.getDirectAccessUrl("urlPriSupported", null);
|
||||||
directAccessUrl = aggStore.getDirectAccessUrl("urlPriSupported", null);
|
|
||||||
assertNotNull(directAccessUrl);
|
assertNotNull(directAccessUrl);
|
||||||
|
|
||||||
when(primaryStoreMock.getDirectAccessUrl(eq("urlSecSupported"), any())).thenThrow(unsupportedExc);
|
when(primaryStoreMock.getDirectAccessUrl(eq("urlSecSupported"), any())).thenThrow(unsupportedExc);
|
||||||
when(secondaryStoreMock.getDirectAccessUrl(eq("urlSecSupported"), any())).thenReturn(new DirectAccessUrl());
|
when(secondaryStoreMock.getDirectAccessUrl(eq("urlSecSupported"), any())).thenReturn(new DirectAccessUrl());
|
||||||
directAccessUrl = aggStore.getDirectAccessUrl("urlSecSupported", null);
|
directAccessUrl = aggregatingContentStoreMock.getDirectAccessUrl("urlSecSupported", null);
|
||||||
assertNotNull(directAccessUrl);
|
assertNotNull(directAccessUrl);
|
||||||
|
|
||||||
when(primaryStoreMock.getDirectAccessUrl(eq("urlSecSupported"), any())).thenThrow(unsupportedContentUrlExc);
|
when(primaryStoreMock.getDirectAccessUrl(eq("urlSecSupported"), any())).thenThrow(unsupportedContentUrlExc);
|
||||||
when(secondaryStoreMock.getDirectAccessUrl(eq("urlSecSupported"), any())).thenReturn(new DirectAccessUrl());
|
when(secondaryStoreMock.getDirectAccessUrl(eq("urlSecSupported"), any())).thenReturn(new DirectAccessUrl());
|
||||||
directAccessUrl = aggStore.getDirectAccessUrl("urlSecSupported", null);
|
directAccessUrl = aggregatingContentStoreMock.getDirectAccessUrl("urlSecSupported", null);
|
||||||
assertNotNull(directAccessUrl);
|
assertNotNull(directAccessUrl);
|
||||||
|
|
||||||
when(primaryStoreMock.getDirectAccessUrl(eq("urlPriSupported"), any())).thenReturn(new DirectAccessUrl());
|
when(primaryStoreMock.getDirectAccessUrl(eq("urlPriSupported"), any())).thenReturn(new DirectAccessUrl());
|
||||||
when(secondaryStoreMock.getDirectAccessUrl(eq("urlSecSupported"), any())).thenReturn(new DirectAccessUrl());
|
when(secondaryStoreMock.getDirectAccessUrl(eq("urlSecSupported"), any())).thenReturn(new DirectAccessUrl());
|
||||||
directAccessUrl = aggStore.getDirectAccessUrl("urlPriSupported", null);
|
directAccessUrl = aggregatingContentStoreMock.getDirectAccessUrl("urlPriSupported", null);
|
||||||
assertNotNull(directAccessUrl);
|
assertNotNull(directAccessUrl);
|
||||||
directAccessUrl = aggStore.getDirectAccessUrl("urlSecSupported", null);
|
directAccessUrl = aggregatingContentStoreMock.getDirectAccessUrl("urlSecSupported", null);
|
||||||
assertNotNull(directAccessUrl);
|
assertNotNull(directAccessUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,46 +320,114 @@ public class AggregatingContentStoreTest extends AbstractWritableContentStoreTes
|
|||||||
public void testIsStorageClassesSupported()
|
public void testIsStorageClassesSupported()
|
||||||
{
|
{
|
||||||
Set<String> sc = Set.of("a-certain-storage-class");
|
Set<String> sc = Set.of("a-certain-storage-class");
|
||||||
// Create the aggregating store
|
|
||||||
AggregatingContentStore aggStore = new AggregatingContentStore();
|
|
||||||
aggStore.setPrimaryStore(primaryStoreMock);
|
|
||||||
aggStore.setSecondaryStores(List.of(secondaryStoreMock));
|
|
||||||
|
|
||||||
// SC supported by the primary store
|
|
||||||
when(primaryStoreMock.isStorageClassesSupported(sc)).thenReturn(true);
|
when(primaryStoreMock.isStorageClassesSupported(sc)).thenReturn(true);
|
||||||
assertTrue(aggStore.isStorageClassesSupported(sc));
|
|
||||||
verify(primaryStoreMock, times(1)).isStorageClassesSupported(sc);
|
|
||||||
verify(secondaryStoreMock, never()).isStorageClassesSupported(sc);
|
|
||||||
|
|
||||||
// SC supported by the secondary store
|
assertTrue(aggregatingContentStoreMock.isStorageClassesSupported(sc));
|
||||||
when(primaryStoreMock.isStorageClassesSupported(sc)).thenReturn(false);
|
|
||||||
when(secondaryStoreMock.isStorageClassesSupported(sc)).thenReturn(true);
|
|
||||||
assertTrue(aggStore.isStorageClassesSupported(sc));
|
|
||||||
verify(primaryStoreMock, times(1)).isStorageClassesSupported(sc);
|
verify(primaryStoreMock, times(1)).isStorageClassesSupported(sc);
|
||||||
verify(secondaryStoreMock, times(1)).isStorageClassesSupported(sc);
|
verifyNoInteractions(secondaryStoreMock);
|
||||||
|
}
|
||||||
|
|
||||||
// SC not supported by the stores
|
@Test
|
||||||
|
public void testStorageClassesIsNotSupported()
|
||||||
|
{
|
||||||
|
Set<String> sc = Set.of("a-certain-storage-class");
|
||||||
when(primaryStoreMock.isStorageClassesSupported(sc)).thenReturn(false);
|
when(primaryStoreMock.isStorageClassesSupported(sc)).thenReturn(false);
|
||||||
when(secondaryStoreMock.isStorageClassesSupported(sc)).thenReturn(false);
|
|
||||||
assertFalse(aggStore.isStorageClassesSupported(sc));
|
assertFalse(aggregatingContentStoreMock.isStorageClassesSupported(sc));
|
||||||
verify(primaryStoreMock, times(1)).isStorageClassesSupported(sc);
|
verify(primaryStoreMock, times(1)).isStorageClassesSupported(sc);
|
||||||
verify(secondaryStoreMock, times(1)).isStorageClassesSupported(sc);
|
verifyNoInteractions(secondaryStoreMock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetSupportedStorageClasses()
|
public void testGetSupportedStorageClasses()
|
||||||
{
|
{
|
||||||
Set<String> sc = Collections.emptySet();
|
when(primaryStoreMock.getSupportedStorageClasses()).thenReturn(emptySet());
|
||||||
// Create the aggregating store
|
|
||||||
AggregatingContentStore aggStore = new AggregatingContentStore();
|
|
||||||
aggStore.setPrimaryStore(primaryStoreMock);
|
|
||||||
aggStore.setSecondaryStores(List.of(secondaryStoreMock));
|
|
||||||
|
|
||||||
when(primaryStoreMock.getSupportedStorageClasses()).thenReturn(sc);
|
assertTrue(aggregatingContentStoreMock.getSupportedStorageClasses().isEmpty());
|
||||||
|
|
||||||
final Set<String> supportedStorageClasses = aggStore.getSupportedStorageClasses();
|
|
||||||
assertTrue(supportedStorageClasses.isEmpty());
|
|
||||||
verify(primaryStoreMock, times(1)).getSupportedStorageClasses();
|
verify(primaryStoreMock, times(1)).getSupportedStorageClasses();
|
||||||
verify(secondaryStoreMock, times(0)).getSupportedStorageClasses();
|
verifyNoInteractions(secondaryStoreMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateStorageClassesForGivenContentUrl()
|
||||||
|
{
|
||||||
|
String contentUrl = "contentUrl";
|
||||||
|
final Set<String> storageClasses = Set.of("a-certain-storage-class");
|
||||||
|
|
||||||
|
aggregatingContentStoreMock.updateStorageClasses(contentUrl, storageClasses, null);
|
||||||
|
|
||||||
|
verify(primaryStoreMock, times(1)).updateStorageClasses(contentUrl, storageClasses, null);
|
||||||
|
verifyNoInteractions(secondaryStoreMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindStorageClassesForGivenContentUrlInPrimaryStore()
|
||||||
|
{
|
||||||
|
when(primaryStoreMock.findStorageClasses(anyString())).thenReturn(emptySet());
|
||||||
|
|
||||||
|
assertTrue(aggregatingContentStoreMock.findStorageClasses("a-contentUrl").isEmpty());
|
||||||
|
verify(primaryStoreMock, times(1)).findStorageClasses("a-contentUrl");
|
||||||
|
verifyNoInteractions(secondaryStoreMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindStorageClassesForGivenContentUrlInSecondaryStore()
|
||||||
|
{
|
||||||
|
UnsupportedContentUrlException unsupportedContentUrlExc = new UnsupportedContentUrlException(
|
||||||
|
aggregatingContentStoreMock, "");
|
||||||
|
|
||||||
|
when(primaryStoreMock.findStorageClasses(anyString())).thenThrow(unsupportedContentUrlExc);
|
||||||
|
when(secondaryStoreMock.findStorageClasses(anyString())).thenReturn(emptySet());
|
||||||
|
|
||||||
|
assertTrue(aggregatingContentStoreMock.findStorageClasses("a-contentUrl").isEmpty());
|
||||||
|
verify(primaryStoreMock, times(1)).findStorageClasses("a-contentUrl");
|
||||||
|
verify(secondaryStoreMock, times(1)).findStorageClasses("a-contentUrl");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = UnsupportedContentUrlException.class)
|
||||||
|
public void testFindStorageClassesForInvalidContentUrl()
|
||||||
|
{
|
||||||
|
when(primaryStoreMock.findStorageClasses(anyString()))
|
||||||
|
.thenThrow(new UnsupportedContentUrlException(aggregatingContentStoreMock, ""));
|
||||||
|
when(secondaryStoreMock.findStorageClasses(anyString()))
|
||||||
|
.thenThrow(new UnsupportedContentUrlException(aggregatingContentStoreMock, ""));
|
||||||
|
|
||||||
|
aggregatingContentStoreMock.findStorageClasses("a-contentUrl");
|
||||||
|
|
||||||
|
verify(primaryStoreMock, times(1)).findStorageClasses("a-contentUrl");
|
||||||
|
verify(secondaryStoreMock, times(1)).findStorageClasses("a-contentUrl");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetStorageClassesTransitions()
|
||||||
|
{
|
||||||
|
when(primaryStoreMock.getStorageClassesTransitions()).thenReturn(emptyMap());
|
||||||
|
|
||||||
|
assertTrue(aggregatingContentStoreMock.getStorageClassesTransitions().isEmpty());
|
||||||
|
verify(primaryStoreMock, times(1)).getStorageClassesTransitions();
|
||||||
|
verifyNoInteractions(secondaryStoreMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindStorageClassesTransitionsForGivenContentUrl()
|
||||||
|
{
|
||||||
|
when(primaryStoreMock.findStorageClassesTransitions(anyString())).thenReturn(emptyMap());
|
||||||
|
|
||||||
|
assertTrue(
|
||||||
|
aggregatingContentStoreMock.findStorageClassesTransitions("contentUrl").isEmpty());
|
||||||
|
verify(primaryStoreMock, times(1)).findStorageClassesTransitions("contentUrl");
|
||||||
|
verifyNoInteractions(secondaryStoreMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = UnsupportedContentUrlException.class)
|
||||||
|
public void testFindStorageClassesTransitionsForUnsupportedContentUrl()
|
||||||
|
{
|
||||||
|
when(primaryStoreMock.findStorageClassesTransitions(anyString()))
|
||||||
|
.thenThrow(new UnsupportedContentUrlException(aggregatingContentStoreMock, ""));
|
||||||
|
|
||||||
|
aggregatingContentStoreMock.findStorageClassesTransitions("contentUrl");
|
||||||
|
|
||||||
|
verify(primaryStoreMock, times(1)).findStorageClassesTransitions("contentUrl");
|
||||||
|
verifyNoInteractions(secondaryStoreMock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user