mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-10-08 14:51:49 +00:00
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:
@@ -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.
|
||||||
|
@@ -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.
|
||||||
|
@@ -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;
|
||||||
|
@@ -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)
|
||||||
{
|
{
|
||||||
|
@@ -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();
|
||||||
|
@@ -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.
|
||||||
|
@@ -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.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
@@ -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
|
||||||
*/
|
*/
|
||||||
|
@@ -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>
|
||||||
|
@@ -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);
|
||||||
|
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user