Updated to use alfresco-data-model:6.1-SNAPSHOT that includes the removal of ContentStore.getUrls methods

- Fixed derived code to remove the implementations


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@131256 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2016-10-06 19:46:02 +00:00
parent 4125597e28
commit 245770e049
17 changed files with 306 additions and 1068 deletions

View File

@@ -25,8 +25,6 @@
*/ */
package org.alfresco.repo.content; package org.alfresco.repo.content;
import java.util.Date;
import org.alfresco.api.AlfrescoPublicApi; import org.alfresco.api.AlfrescoPublicApi;
import org.alfresco.repo.content.ContentLimitProvider.NoLimitProvider; import org.alfresco.repo.content.ContentLimitProvider.NoLimitProvider;
import org.alfresco.service.cmr.repository.ContentIOException; import org.alfresco.service.cmr.repository.ContentIOException;
@@ -164,29 +162,6 @@ public abstract class AbstractContentStore implements ContentStore
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
/**
* @see #getUrls(Date, Date, ContentUrlHandler)
*/
@SuppressWarnings("deprecation")
@Override
public final void getUrls(ContentUrlHandler handler) throws ContentIOException
{
getUrls(null, null, handler);
}
/**
* Override to provide an implementation. If no implementation is supplied, then the store will not support
* cleaning of orphaned content binaries.
*
* @throws UnsupportedOperationException always
*/
@SuppressWarnings("deprecation")
@Override
public void getUrls(Date createdAfter, Date createdBefore, ContentUrlHandler handler) throws ContentIOException
{
throw new UnsupportedOperationException();
}
/** /**
* Implement to supply a store-specific writer for the given existing content * Implement to supply a store-specific writer for the given existing content
* and optional target content URL. * and optional target content URL.

View File

@@ -25,7 +25,6 @@
*/ */
package org.alfresco.repo.content; package org.alfresco.repo.content;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock; import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
@@ -393,37 +392,6 @@ public abstract class AbstractRoutingContentStore implements ContentStore
return getWriter(new ContentContext(existingContentReader, newContentUrl)); return getWriter(new ContentContext(existingContentReader, newContentUrl));
} }
/**
* @see #getUrls(Date, Date, ContentUrlHandler)
*/
@SuppressWarnings("deprecation")
public void getUrls(ContentUrlHandler handler) throws ContentIOException
{
getUrls(null, null, handler);
}
/**
* Passes the call to each of the stores wrapped by this store
*
* @see ContentStore#getUrls(Date, Date, ContentUrlHandler)
*/
@SuppressWarnings("deprecation")
public void getUrls(Date createdAfter, Date createdBefore, ContentUrlHandler handler) throws ContentIOException
{
List<ContentStore> stores = getAllStores();
for (ContentStore store : stores)
{
try
{
store.getUrls(createdAfter, createdBefore, handler);
}
catch (UnsupportedOperationException e)
{
// Support of this is not mandatory
}
}
}
/** /**
* This operation has to be performed on all the stores in order to maintain the * This operation has to be performed on all the stores in order to maintain the
* {@link ContentStore#exists(String)} contract. * {@link ContentStore#exists(String)} contract.

View File

@@ -66,12 +66,10 @@ import org.alfresco.service.cmr.repository.MimetypeServiceAware;
import org.alfresco.service.cmr.repository.NoTransformerException; import org.alfresco.service.cmr.repository.NoTransformerException;
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.cmr.repository.StoreRef;
import org.alfresco.service.cmr.repository.TransformationOptions; import org.alfresco.service.cmr.repository.TransformationOptions;
import org.alfresco.service.cmr.usage.ContentQuotaException; import org.alfresco.service.cmr.usage.ContentQuotaException;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.EqualsHelper; import org.alfresco.util.EqualsHelper;
import org.alfresco.util.Pair;
import org.alfresco.util.TempFileProvider; import org.alfresco.util.TempFileProvider;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;

View File

@@ -25,7 +25,6 @@
*/ */
package org.alfresco.repo.content.caching; package org.alfresco.repo.content.caching;
import java.util.Date;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock; import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
@@ -335,21 +334,6 @@ public class CachingContentStore implements ContentStore, ApplicationEventPublis
} }
} }
@SuppressWarnings("deprecation")
@Override
public void getUrls(ContentUrlHandler handler) throws ContentIOException
{
backingStore.getUrls(handler);
}
@SuppressWarnings("deprecation")
@Override
public void getUrls(Date createdAfter, Date createdBefore, ContentUrlHandler handler)
throws ContentIOException
{
backingStore.getUrls(createdAfter, createdBefore, handler);
}
@Override @Override
public boolean delete(String contentUrl) public boolean delete(String contentUrl)
{ {

View File

@@ -186,13 +186,11 @@ public class ContentStoreCleanerScalabilityRunner extends Repository
private class NullContentStore extends AbstractContentStore private class NullContentStore extends AbstractContentStore
{ {
private ThreadLocal<File> hammeredFile; private ThreadLocal<File> hammeredFile;
private int count;
private int deletedCount; private int deletedCount;
private NullContentStore(int count) private NullContentStore(int count)
{ {
hammeredFile = new ThreadLocal<File>(); hammeredFile = new ThreadLocal<File>();
this.count = count;
} }
public boolean isWriteSupported() public boolean isWriteSupported()
@@ -216,17 +214,6 @@ public class ContentStoreCleanerScalabilityRunner extends Repository
return new FileContentWriter(file); return new FileContentWriter(file);
} }
@Override
public void getUrls(Date createdAfter, Date createdBefore, ContentUrlHandler handler) throws ContentIOException
{
// Make up it up
for (int i = 0; i < count; i++)
{
String contentUrl = FileContentStore.createNewFileStoreUrl() + "-imaginary";
handler.handle(contentUrl);
}
}
public ContentReader getReader(String contentUrl) public ContentReader getReader(String contentUrl)
{ {
File file = hammeredFile.get(); File file = hammeredFile.get();

View File

@@ -30,7 +30,6 @@ import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.Map; import java.util.Map;
@@ -67,7 +66,7 @@ import org.springframework.context.event.ContextRefreshedEvent;
* The protocols handled are: * The protocols handled are:
* <ul> * <ul>
* <li><b>{@link #STORE_PROTOCOL store}</b>: These URLs can be generated by this implementation and are file references within the root directory.</li> * <li><b>{@link #STORE_PROTOCOL store}</b>: These URLs can be generated by this implementation and are file references within the root directory.</li>
* <li><b>{@link #SPOOF_PROTOCOL spoof}</b>: These URLs are never generated by the implementation but represent spoofed binary text stream data: TODO</li> * <li><b>{@link #SPOOF_PROTOCOL spoof}</b>: These URLs are never generated by the implementation but represent spoofed binary text stream data.</li>
* </ul> * </ul>
* *
* @author Derek Hulley * @author Derek Hulley
@@ -532,74 +531,6 @@ public class FileContentStore
} }
} }
/**
* Gets the urls.
*
* @param createdAfter
* the created after date
* @param createdBefore
* the created before dat6e
* @param handler
* the handler
*/
@SuppressWarnings("deprecation")
public void getUrls(Date createdAfter, Date createdBefore, ContentUrlHandler handler)
{
// recursively get all files within the root
getUrls(rootDirectory, handler, createdAfter, createdBefore);
// done
if (logger.isDebugEnabled())
{
logger.debug("Listed all content URLS: \n" +
" store: " + this);
}
}
/**
* Returns a list of all files within the given directory and all subdirectories.
* @param directory the current directory to get the files from
* @param handler the callback to use for each URL
* @param createdAfter only get URLs for content create after this date
* @param createdBefore only get URLs for content created before this date
*/
@SuppressWarnings("deprecation")
private void getUrls(File directory, ContentUrlHandler handler, Date createdAfter, Date createdBefore)
{
File[] files = directory.listFiles();
if (files == null)
{
// the directory has disappeared
throw new ContentIOException("Failed list files in folder: " + directory);
}
for (File file : files)
{
if (file.isDirectory())
{
// we have a subdirectory - recurse
getUrls(file, handler, createdAfter, createdBefore);
}
else
{
// check the created date of the file
long lastModified = file.lastModified();
if (createdAfter != null && lastModified < createdAfter.getTime())
{
// file is too old
continue;
}
else if (createdBefore != null && lastModified > createdBefore.getTime())
{
// file is too young
continue;
}
// found a file - create the URL
String contentUrl = makeContentUrl(file);
// Callback
handler.handle(contentUrl);
}
}
}
/** /**
* Attempts to delete the content. The actual deletion is optional on the interface * Attempts to delete the content. The actual deletion is optional on the interface
* so it just returns the success or failure of the underlying delete. * so it just returns the success or failure of the underlying delete.

View File

@@ -37,6 +37,8 @@ import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper; import org.alfresco.util.ApplicationContextHelper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
/** /**
@@ -47,9 +49,14 @@ import org.springframework.context.ApplicationContext;
* *
* @since 2.1 * @since 2.1
* @author Derek Hulley * @author Derek Hulley
*
* @deprecated Removed in 5.2
*/ */
@Deprecated
public class HttpAlfrescoStore extends AbstractContentStore public class HttpAlfrescoStore extends AbstractContentStore
{ {
private static final Log logger = LogFactory.getLog(HttpAlfrescoStore.class);
private TransactionService transactionService; private TransactionService transactionService;
private AuthenticationService authenticationService; private AuthenticationService authenticationService;
private String baseHttpUrl; private String baseHttpUrl;
@@ -59,6 +66,7 @@ public class HttpAlfrescoStore extends AbstractContentStore
*/ */
public HttpAlfrescoStore() public HttpAlfrescoStore()
{ {
logger.warn("HttpAlfrescoStore has been deprecated since Alfresco 5.2.");
} }
/** /**

View File

@@ -25,7 +25,6 @@
*/ */
package org.alfresco.repo.content.replication; package org.alfresco.repo.content.replication;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReadWriteLock;
@@ -69,7 +68,6 @@ public class AggregatingContentStore extends AbstractContentStore
private List<ContentStore> secondaryStores; private List<ContentStore> secondaryStores;
private Lock readLock; private Lock readLock;
private Lock writeLock;
/** /**
* Default constructor * Default constructor
@@ -78,7 +76,6 @@ public class AggregatingContentStore extends AbstractContentStore
{ {
ReadWriteLock storeLock = new ReentrantReadWriteLock(); ReadWriteLock storeLock = new ReentrantReadWriteLock();
readLock = storeLock.readLock(); readLock = storeLock.readLock();
writeLock = storeLock.writeLock();
} }
/** /**
@@ -151,7 +148,6 @@ public class AggregatingContentStore extends AbstractContentStore
} }
// the content is not in the primary reader so we have to go looking for it // the content is not in the primary reader so we have to go looking for it
ContentReader secondaryContentReader = null;
for (ContentStore store : secondaryStores) for (ContentStore store : secondaryStores)
{ {
ContentReader reader = store.getReader(contentUrl); ContentReader reader = store.getReader(contentUrl);
@@ -195,28 +191,4 @@ public class AggregatingContentStore extends AbstractContentStore
} }
return deleted; return deleted;
} }
/**
* Iterates over results as given by the primary store and all secondary stores. It is up to the handler to eliminate
* duplicates that will occur between the primary and secondary stores.
*/
@SuppressWarnings("deprecation")
public void getUrls(Date createdAfter, Date createdBefore, ContentUrlHandler handler) throws ContentIOException
{
// add in URLs from primary store
primaryStore.getUrls(createdAfter, createdBefore, handler);
// add in URLs from secondary stores (they are visible for reads)
for (ContentStore secondaryStore : secondaryStores)
{
secondaryStore.getUrls(createdAfter, createdBefore, handler);
}
// done
if (logger.isDebugEnabled())
{
logger.debug("Iterated over content URLs: \n" +
" created after: " + createdAfter + "\n" +
" created before: " + createdBefore);
}
}
} }

View File

@@ -41,8 +41,6 @@ import org.alfresco.repo.domain.tenant.TenantAdminDAO;
import org.alfresco.repo.domain.tenant.TenantEntity; import org.alfresco.repo.domain.tenant.TenantEntity;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork; import org.alfresco.repo.tenant.TenantUtil.TenantRunAsWork;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
@@ -56,8 +54,6 @@ import org.springframework.context.ApplicationContextAware;
*/ */
public abstract class AbstractTenantRoutingContentStore extends AbstractRoutingContentStore implements ApplicationContextAware, TenantRoutingContentStore public abstract class AbstractTenantRoutingContentStore extends AbstractRoutingContentStore implements ApplicationContextAware, TenantRoutingContentStore
{ {
private static Log logger = LogFactory.getLog(AbstractTenantRoutingContentStore.class);
private String defaultRootDirectory; private String defaultRootDirectory;
private TenantAdminDAO tenantAdminDAO; private TenantAdminDAO tenantAdminDAO;
protected TenantService tenantService; protected TenantService tenantService;

View File

@@ -28,12 +28,9 @@ package org.alfresco.repo.content;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.util.HashSet;
import java.util.Set;
import javax.transaction.UserTransaction; import javax.transaction.UserTransaction;
import org.alfresco.repo.content.ContentStore.ContentUrlHandler;
import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper; import org.alfresco.util.ApplicationContextHelper;
@@ -132,49 +129,6 @@ public abstract class AbstractReadOnlyContentStoreTest
return getStore().getReader(contentUrl); return getStore().getReader(contentUrl);
} }
/**
* Fetch a valid URL from the store. The default implementation will attempt to get
* all the available URLs from the store and pick the first one. Writable store tests
* can create some content to be sure of its existence.
*
* @return
* Return any valid URL for the store, or <tt>null</tt> if the store is empty.
*/
@SuppressWarnings("deprecation")
protected String getExistingContentUrl()
{
ContentStore store = getStore();
try
{
final Set<String> contentUrls = new HashSet<String>(5);
ContentUrlHandler handler = new ContentUrlHandler()
{
public void handle(String contentUrl)
{
if (contentUrls.size() < 50)
{
contentUrls.add(contentUrl);
}
}
};
store.getUrls(handler);
if (contentUrls.size() > 0)
{
return (String) contentUrls.toArray()[0];
}
else
{
// We can't do anything with this
return null;
}
}
catch (UnsupportedOperationException e)
{
// The store doesn't support this
return null;
}
}
@Test @Test
public void testSetUp() throws Exception public void testSetUp() throws Exception
{ {
@@ -211,6 +165,11 @@ public abstract class AbstractReadOnlyContentStoreTest
} }
} }
/**
* Tests to implement this method in order to provide some content to play with
*/
protected abstract String getExistingContentUrl();
/** /**
* Checks that the error handling for <i>inappropriate</i> content URLs * Checks that the error handling for <i>inappropriate</i> content URLs
*/ */

View File

@@ -25,12 +25,6 @@
*/ */
package org.alfresco.repo.content; package org.alfresco.repo.content;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
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.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
@@ -41,10 +35,8 @@ import java.io.OutputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.util.Date;
import java.util.Locale; import java.util.Locale;
import org.alfresco.repo.content.ContentStore.ContentUrlHandler;
import org.alfresco.service.cmr.repository.ContentIOException; import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentStreamListener; import org.alfresco.service.cmr.repository.ContentStreamListener;
@@ -54,6 +46,12 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/** /**
* Abstract base class that provides a set of tests for implementations * Abstract base class that provides a set of tests for implementations
* of {@link ContentStore}. * of {@link ContentStore}.
@@ -64,7 +62,6 @@ import org.junit.Test;
* *
* @author Derek Hulley * @author Derek Hulley
*/ */
@SuppressWarnings("deprecation")
public abstract class AbstractWritableContentStoreTest extends AbstractReadOnlyContentStoreTest public abstract class AbstractWritableContentStoreTest extends AbstractReadOnlyContentStoreTest
{ {
protected static Log logger = LogFactory.getLog(AbstractWritableContentStoreTest.class); protected static Log logger = LogFactory.getLog(AbstractWritableContentStoreTest.class);
@@ -380,26 +377,6 @@ public abstract class AbstractWritableContentStoreTest extends AbstractReadOnlyC
assertTrue("After-content reader should be closed after reading", readerAfterWrite.isClosed()); assertTrue("After-content reader should be closed after reading", readerAfterWrite.isClosed());
} }
/**
* Helper method to check if a store contains a particular URL using the getUrl method
*/
private boolean searchForUrl(ContentStore store, final String contentUrl, Date from, Date to)
{
final boolean[] found = new boolean[] {false};
ContentUrlHandler handler = new ContentUrlHandler()
{
public void handle(String checkContentUrl)
{
if (contentUrl.equals(checkContentUrl))
{
found[0] = true;
}
}
};
getStore().getUrls(from, to, handler);
return found[0];
}
@Test @Test
public void testDeleteSimple() throws Exception public void testDeleteSimple() throws Exception
{ {
@@ -654,46 +631,6 @@ public abstract class AbstractWritableContentStoreTest extends AbstractReadOnlyC
assertEquals("Write out of and read into files failed", content, check); assertEquals("Write out of and read into files failed", content, check);
} }
/**
* Tests retrieval of all content URLs
* <p>
* Only applies when {@link #getStore()} returns a value.
*/
@Test
public void testListUrls() throws Exception
{
ContentStore store = getStore();
// Ensure that this test can be done
try
{
searchForUrl(store, "abc", null, null);
}
catch (UnsupportedOperationException e)
{
logger.warn("Store test testListUrls not possible on " + store.getClass().getName());
return;
}
// Proceed with the test
ContentWriter writer = getWriter();
String contentUrl = writer.getContentUrl();
boolean inStore = searchForUrl(store, contentUrl, null, null);
assertTrue("Writer URL not listed by store", inStore);
Date yesterday = new Date(System.currentTimeMillis() - 3600L * 1000L * 24L);
// write some data
writer.putContent("The quick brown fox...");
// check again
inStore = searchForUrl(store, contentUrl, null, null);
assertTrue("Writer URL not listed by store", inStore);
// check that the query for content created before this time yesterday doesn't return the URL
inStore = searchForUrl(store, contentUrl, null, yesterday);
assertFalse("URL was younger than required, but still shows up", inStore);
}
/** /**
* Tests random access writing * Tests random access writing
* <p> * <p>

View File

@@ -34,8 +34,6 @@ import org.alfresco.repo.content.filestore.FileContentStoreTest;
import org.alfresco.repo.content.filestore.NoRandomAccessFileContentStoreTest; import org.alfresco.repo.content.filestore.NoRandomAccessFileContentStoreTest;
import org.alfresco.repo.content.filestore.ReadOnlyFileContentStoreTest; import org.alfresco.repo.content.filestore.ReadOnlyFileContentStoreTest;
import org.alfresco.repo.content.filestore.SpoofedTextContentReaderTest; import org.alfresco.repo.content.filestore.SpoofedTextContentReaderTest;
import org.alfresco.repo.content.replication.ContentStoreReplicatorTest;
import org.alfresco.repo.content.replication.ReplicatingContentStoreTest;
/** /**
* Suite for content-related tests. * Suite for content-related tests.
@@ -59,8 +57,6 @@ public class ContentFullContextTestSuite extends TestSuite
suite.addTest(new JUnit4TestAdapter(FileContentStoreTest.class)); suite.addTest(new JUnit4TestAdapter(FileContentStoreTest.class));
suite.addTest(new JUnit4TestAdapter(NoRandomAccessFileContentStoreTest.class)); suite.addTest(new JUnit4TestAdapter(NoRandomAccessFileContentStoreTest.class));
suite.addTest(new JUnit4TestAdapter(ReadOnlyFileContentStoreTest.class)); suite.addTest(new JUnit4TestAdapter(ReadOnlyFileContentStoreTest.class));
suite.addTestSuite(ContentStoreReplicatorTest.class);
suite.addTest(new JUnit4TestAdapter(ReplicatingContentStoreTest.class));
suite.addTestSuite(ContentDataTest.class); suite.addTestSuite(ContentDataTest.class);
//suite.addTestSuite(MimetypeMapTest.class); //suite.addTestSuite(MimetypeMapTest.class);
suite.addTestSuite(RoutingContentServiceTest.class); suite.addTestSuite(RoutingContentServiceTest.class);

View File

@@ -25,22 +25,14 @@
*/ */
package org.alfresco.repo.content; package org.alfresco.repo.content;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Date;
import java.util.List; import java.util.List;
import org.alfresco.repo.cache.DefaultSimpleCache; import org.alfresco.repo.cache.DefaultSimpleCache;
import org.alfresco.repo.cache.SimpleCache; import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.content.filestore.FileContentStore; import org.alfresco.repo.content.filestore.FileContentStore;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.test_category.OwnJVMTestsCategory; import org.alfresco.test_category.OwnJVMTestsCategory;
@@ -50,6 +42,12 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.experimental.categories.Category; import org.junit.experimental.categories.Category;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/** /**
* Ensures that the routing of URLs based on context is working. A combination * Ensures that the routing of URLs based on context is working. A combination
* of fully featured and incompletely featured stores is used to ensure that * of fully featured and incompletely featured stores is used to ensure that
@@ -228,13 +226,6 @@ public class RoutingContentStoreTest extends AbstractWritableContentStoreTest
{ {
return fileStore.getReader(contentUrl); return fileStore.getReader(contentUrl);
} }
@SuppressWarnings("deprecation")
@Override
public void getUrls(Date createdAfter, Date createdBefore, ContentUrlHandler handler) throws ContentIOException
{
fileStore.getUrls(createdAfter, createdBefore, handler);
}
} }
/** /**

View File

@@ -28,7 +28,9 @@ package org.alfresco.repo.content.filestore;
import java.io.File; import java.io.File;
import org.alfresco.repo.content.AbstractReadOnlyContentStoreTest; import org.alfresco.repo.content.AbstractReadOnlyContentStoreTest;
import org.alfresco.repo.content.ContentContext;
import org.alfresco.repo.content.ContentStore; import org.alfresco.repo.content.ContentStore;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.test_category.OwnJVMTestsCategory; import org.alfresco.test_category.OwnJVMTestsCategory;
import org.alfresco.util.TempFileProvider; import org.alfresco.util.TempFileProvider;
import org.junit.Before; import org.junit.Before;
@@ -46,6 +48,7 @@ import org.junit.experimental.categories.Category;
public class ReadOnlyFileContentStoreTest extends AbstractReadOnlyContentStoreTest public class ReadOnlyFileContentStoreTest extends AbstractReadOnlyContentStoreTest
{ {
private FileContentStore store; private FileContentStore store;
private String contentUrl;
@Before @Before
public void before() throws Exception public void before() throws Exception
@@ -56,6 +59,10 @@ public class ReadOnlyFileContentStoreTest extends AbstractReadOnlyContentStoreTe
tempDir.getAbsolutePath() + tempDir.getAbsolutePath() +
File.separatorChar + File.separatorChar +
getName()); getName());
// Put some content into it
ContentWriter writer = store.getWriter(new ContentContext(null, null));
writer.putContent("Content for getExistingContentUrl");
this.contentUrl = writer.getContentUrl();
// disallow random access // disallow random access
store.setReadOnly(true); store.setReadOnly(true);
} }
@@ -65,4 +72,10 @@ public class ReadOnlyFileContentStoreTest extends AbstractReadOnlyContentStoreTe
{ {
return store; return store;
} }
@Override
protected String getExistingContentUrl()
{
return contentUrl;
}
} }

View File

@@ -25,25 +25,14 @@
*/ */
package org.alfresco.repo.content.replication; package org.alfresco.repo.content.replication;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.alfresco.repo.content.AbstractWritableContentStoreTest; import org.alfresco.repo.content.AbstractWritableContentStoreTest;
import org.alfresco.repo.content.ContentContext; import org.alfresco.repo.content.ContentContext;
import org.alfresco.repo.content.ContentStore; import org.alfresco.repo.content.ContentStore;
import org.alfresco.repo.content.ContentStore.ContentUrlHandler;
import org.alfresco.repo.content.filestore.FileContentStore; import org.alfresco.repo.content.filestore.FileContentStore;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.test_category.OwnJVMTestsCategory; import org.alfresco.test_category.OwnJVMTestsCategory;
@@ -52,6 +41,9 @@ import org.alfresco.util.TempFileProvider;
import org.junit.Before; import org.junit.Before;
import org.junit.experimental.categories.Category; import org.junit.experimental.categories.Category;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/** /**
* Tests read and write functionality for the aggregating store. * Tests read and write functionality for the aggregating store.
* <p> * <p>
@@ -140,20 +132,8 @@ public class AggregatingContentStoreTest extends AbstractWritableContentStoreTes
*/ */
private void checkForUrl(String contentUrl, boolean mustExist) private void checkForUrl(String contentUrl, boolean mustExist)
{ {
// check that the URL is present for each of the stores ContentReader reader = getReader(contentUrl);
for (ContentStore store : secondaryStores) assertEquals("Reader state differs from expected: " + reader, mustExist, reader.exists());
{
final Set<String> urls = new HashSet<String>(1027);
ContentUrlHandler handler = new ContentUrlHandler()
{
public void handle(String contentUrl)
{
urls.add(contentUrl);
}
};
store.getUrls(handler);
assertTrue("URL of new content not present in store", urls.contains(contentUrl) == mustExist);
}
} }
public void testDelete() throws Exception public void testDelete() throws Exception

View File

@@ -1,203 +0,0 @@
/*
* #%L
* Alfresco Repository
* %%
* 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.repo.content.replication;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
import junit.framework.TestCase;
import org.alfresco.repo.content.ContentContext;
import org.alfresco.repo.content.ContentStore;
import org.alfresco.repo.content.ContentStore.ContentUrlHandler;
import org.alfresco.repo.content.filestore.FileContentStore;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.util.GUID;
import org.alfresco.util.TempFileProvider;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.support.StaticApplicationContext;
/**
* Tests the content store replicator.
*
* @see org.alfresco.repo.content.replication.ContentStoreReplicator
*
* @author Derek Hulley
*/
@SuppressWarnings({"unused", "deprecation"})
public class ContentStoreReplicatorTest extends TestCase
{
private static final String SOME_CONTENT = "The No. 1 Ladies' Detective Agency";
private ContentStoreReplicator replicator;
private ContentStore sourceStore;
private ContentStore targetStore;
@Override
public void setUp() throws Exception
{
super.setUp();
// Create a dummy context for message broadcasting
StaticApplicationContext ctx = new StaticApplicationContext();
ctx.refresh();
File tempDir = TempFileProvider.getTempDir();
// create the source file store
String storeDir = tempDir.getAbsolutePath() + File.separatorChar + getName() + File.separatorChar + GUID.generate();
sourceStore = new FileContentStore(ctx, storeDir);
// create the target file store
storeDir = tempDir.getAbsolutePath() + File.separatorChar + getName() + File.separatorChar + GUID.generate();
targetStore = new FileContentStore(ctx, storeDir);
// create the replicator
replicator = new ContentStoreReplicator();
replicator.setSourceStore(sourceStore);
replicator.setTargetStore(targetStore);
}
/**
* Creates a source with some files and replicates in a single pass, checking the results.
*/
public void testSinglePassReplication() throws Exception
{
ContentWriter writer = sourceStore.getWriter(ContentStore.NEW_CONTENT_CONTEXT);
writer.putContent("123");
// replicate
replicator.start();
// wait a second
synchronized(this)
{
this.wait(5000L);
}
assertTrue("Target store doesn't have content added to source",
targetStore.exists(writer.getContentUrl()));
// this was a single pass, so now more replication should be done
writer = sourceStore.getWriter(ContentStore.NEW_CONTENT_CONTEXT);
writer.putContent("456");
// wait a second
synchronized(this)
{
this.wait(1000L);
}
assertFalse("Replication should have been single-pass",
targetStore.exists(writer.getContentUrl()));
}
/**
* Handler that merely records the URL
*
* @author Derek Hulley
* @since 2.0
*/
private class UrlRecorder implements ContentUrlHandler
{
public Set<String> urls = new HashSet<String>(1027);
public void handle(String contentUrl)
{
urls.add(contentUrl);
}
}
/**
* Adds content to the source while the replicator is going as fast as possible.
* Just to make it more interesting, the content is sometimes put in the target
* store as well.
* <p>
* Afterwards, some content is removed from the the target.
* <p>
* Then, finally, a check is performed to ensure that the source and target are
* in synch.
*/
public void testContinuousReplication() throws Exception
{
replicator.start();
String duplicateUrl = null;
// start the replicator - it won't wait between iterations
for (int i = 0; i < 10; i++)
{
// put some content into both the target and source
ContentWriter duplicateSourceWriter = sourceStore.getWriter(ContentStore.NEW_CONTENT_CONTEXT);
duplicateUrl = duplicateSourceWriter.getContentUrl();
try
{
ContentContext targetContentCtx = new ContentContext(null, duplicateUrl);
ContentWriter duplicateTargetWriter = targetStore.getWriter(targetContentCtx);
duplicateTargetWriter.putContent("Duplicate Target Content: " + i);
duplicateSourceWriter.putContent(duplicateTargetWriter.getReader());
}
catch (ContentIOException e)
{
// This can happen because the replicator may have beaten us to it
}
for (int j = 0; j < 100; j++)
{
// write content
ContentWriter writer = sourceStore.getWriter(ContentStore.NEW_CONTENT_CONTEXT);
writer.putContent("Repeated put: " + j);
}
}
// remove the last duplicated URL from the target
targetStore.delete(duplicateUrl);
// allow time for the replicator to catch up
synchronized(this)
{
this.wait(1000L);
}
// check that we have an exact match of URLs
UrlRecorder sourceUrls = new UrlRecorder();
UrlRecorder targetUrls = new UrlRecorder();
sourceStore.getUrls(sourceUrls);
targetStore.getUrls(targetUrls);
assertTrue("Source must be equal to target", sourceUrls.urls.containsAll(targetUrls.urls));
//targetUrls.urls.contains(sourceUrls.urls);
}
/**
* Call the replicator repeatedly to check that it prevents concurrent use
*/
public void testRepeatedReplication() throws Exception
{
for (int i = 0; i < 10; i++)
{
replicator.start();
}
}
}

View File

@@ -1,254 +0,0 @@
/*
* #%L
* Alfresco Repository
* %%
* 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.repo.content.replication;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.alfresco.repo.content.AbstractWritableContentStoreTest;
import org.alfresco.repo.content.ContentContext;
import org.alfresco.repo.content.ContentStore;
import org.alfresco.repo.content.ContentStore.ContentUrlHandler;
import org.alfresco.repo.content.filestore.FileContentStore;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.test_category.OwnJVMTestsCategory;
import org.alfresco.util.GUID;
import org.alfresco.util.TempFileProvider;
import org.junit.Before;
import org.junit.experimental.categories.Category;
/**
* Tests read and write functionality for the replicating store.
* <p>
* By default, replication is off for both the inbound and outbound
* replication. Specific tests change this.
*
* @see org.alfresco.repo.content.replication.ReplicatingContentStore
*
* @author Derek Hulley
*/
@Category(OwnJVMTestsCategory.class)
public class ReplicatingContentStoreTest extends AbstractWritableContentStoreTest
{
private static final String SOME_CONTENT = "The No. 1 Ladies' Detective Agency";
private ReplicatingContentStore replicatingStore;
private ContentStore primaryStore;
private List<ContentStore> secondaryStores;
@Before
public void before() throws Exception
{
File tempDir = TempFileProvider.getTempDir();
// create a primary file store
String storeDir = tempDir.getAbsolutePath() + File.separatorChar + GUID.generate();
primaryStore = new FileContentStore(ctx, storeDir);
// create some secondary file stores
secondaryStores = new ArrayList<ContentStore>(3);
for (int i = 0; i < 4; i++)
{
storeDir = tempDir.getAbsolutePath() + File.separatorChar + GUID.generate();
FileContentStore store = new FileContentStore(ctx, storeDir);
secondaryStores.add(store);
// Only the first 3 are writable
if (i >= 3)
{
store.setReadOnly(true);
}
}
// Create the replicating store
replicatingStore = new ReplicatingContentStore();
replicatingStore.setPrimaryStore(primaryStore);
replicatingStore.setSecondaryStores(secondaryStores);
replicatingStore.setOutbound(false);
replicatingStore.setInbound(false);
}
@Override
public ContentStore getStore()
{
return replicatingStore;
}
/**
* Performs checks necessary to ensure the proper replication of content for the given
* URL
*/
private void checkForReplication(boolean inbound, boolean outbound, String contentUrl, String content)
{
if (inbound)
{
ContentReader reader = primaryStore.getReader(contentUrl);
assertTrue("Content was not replicated into the primary store", reader.exists());
assertEquals("The replicated content was incorrect", content, reader.getContentString());
}
if (outbound)
{
for (ContentStore store : secondaryStores)
{
// This is only required for writable stores
if (!store.isWriteSupported())
{
continue;
}
ContentReader reader = store.getReader(contentUrl);
assertTrue("Content was not replicated out to the secondary stores within a second", reader.exists());
assertEquals("The replicated content was incorrect", content, reader.getContentString());
}
}
}
/**
* Checks that the url is present in each of the stores
*
* @param contentUrl String
* @param mustExist true if the content must exist, false if it must <b>not</b> exist
*/
private void checkForUrl(String contentUrl, boolean mustExist)
{
// check that the URL is present for each of the stores
for (ContentStore store : secondaryStores)
{
final Set<String> urls = new HashSet<String>(1027);
ContentUrlHandler handler = new ContentUrlHandler()
{
public void handle(String contentUrl)
{
urls.add(contentUrl);
}
};
store.getUrls(handler);
assertTrue("URL of new content not present in store", urls.contains(contentUrl) == mustExist);
}
}
public void testNoReplication() throws Exception
{
ContentWriter writer = getWriter();
writer.putContent(SOME_CONTENT);
checkForReplication(false, false, writer.getContentUrl(), SOME_CONTENT);
}
public void testOutboundReplication() throws Exception
{
replicatingStore.setOutbound(true);
// write some content
ContentWriter writer = getWriter();
writer.putContent(SOME_CONTENT);
String contentUrl = writer.getContentUrl();
checkForReplication(false, true, contentUrl, SOME_CONTENT);
// check for outbound deletes
replicatingStore.delete(contentUrl);
checkForUrl(contentUrl, false);
}
public void testAsyncOutboundReplication() throws Exception
{
ThreadPoolExecutor tpe = new ThreadPoolExecutor(1, 1, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
replicatingStore.setOutbound(true);
replicatingStore.setOutboundThreadPoolExecutor(tpe);
// write some content
ContentWriter writer = getWriter();
writer.putContent(SOME_CONTENT);
String contentUrl = writer.getContentUrl();
// wait for a second
synchronized(this)
{
this.wait(1000L);
}
checkForReplication(false, true, contentUrl, SOME_CONTENT);
// check for outbound deletes
replicatingStore.delete(contentUrl);
checkForUrl(contentUrl, false);
}
public void testInboundReplication() throws Exception
{
replicatingStore.setInbound(false);
// pick a secondary store and write some content to it
ContentStore secondaryStore = secondaryStores.get(2);
ContentWriter writer = secondaryStore.getWriter(ContentContext.NULL_CONTEXT);
writer.putContent(SOME_CONTENT);
String contentUrl = writer.getContentUrl();
// get a reader from the replicating store
ContentReader reader = replicatingStore.getReader(contentUrl);
assertTrue("Reader must have been found in secondary store", reader.exists());
// set inbound replication on and repeat
replicatingStore.setInbound(true);
reader = replicatingStore.getReader(contentUrl);
// this time, it must have been replicated to the primary store
checkForReplication(true, false, contentUrl, SOME_CONTENT);
}
public void testTargetContentUrlExists()
{
replicatingStore.setOutbound(true);
replicatingStore.setInbound(false);
// pick a secondary store and write some content to it
ContentStore secondaryStore = secondaryStores.get(2);
ContentWriter secondaryWriter = secondaryStore.getWriter(ContentContext.NULL_CONTEXT);
secondaryWriter.putContent("Content for secondary");
String secondaryContentUrl = secondaryWriter.getContentUrl();
// Now write to the primary store
ContentWriter replicatingWriter = replicatingStore.getWriter(new ContentContext(null, secondaryContentUrl));
String replicatingContent = "Content for primary";
try
{
replicatingWriter.putContent(replicatingContent);
fail("Replication should fail when the secondary store already has the content");
}
catch (ContentIOException e)
{
// Expected
}
}
}