alfresco-community-repo/source/java/org/alfresco/repo/content/RoutingContentStoreTest.java
Matt Ward 511af90d5c Merged BRANCHES/DEV/mward/clustering_p1 to HEAD:
41454: ALF-15881: Disabling clustering in community
   41500: ALF-15883: Move configuration files
   41503: ALF-15884: Move cluster package to enterprise repository project
   41504: ALF-15884: Move cluster package to enterprise repository project
   41519: ALF-15886: References/definition for "hazelcastInstanceFactory" must be in enterprise repo only
   41523: ALF-15886: References/definition for "hazelcastInstanceFactory" must be in enterprise repo only
   41525: ALF-15886: References/definition for "hazelcastInstanceFactory" must be in enterprise repo only
   41527: ALF-15886: References/definition for "hazelcastInstanceFactory" must be in enterprise repo only
   41530: ALF-15886: remove import for class no longer in project.
   41532: ALF-15887: LockStoreFactoryImpl must be separated into community and enterprise versions
   41535: ALF-15883: Move configuration files
   41561: ALF-15886: factory class to create key fileserver config beans.
   41578: ALF-15888: separate transactional and shared cache bean definitions.
   41623: ALF-15888: first pass at DefaultSimpleCache implementation.
   41646: ALF-15888: move ehcache-default.xml
   41651: ALF-15888: update javadoc to reflect changes
   41762: ALF-15888: improve cache test to prove that null values are stored correctly.
   41812: ALF-15888: added new cache provider for use by hibernate: DefaultCacheProvider.
   41830: ALF-15888: make DefaultSimpleCache BeanNameAware to help with debugging etc.
   41831: ALF-15888: missing file from commit - adds enterprise override capability for hibernate-cfg.properties
   41850: ALF-15888: move tickets cache to cache-context.xml
   41857: ALF-15888: make RemoteAlfrescoTicketServiceImpl cache implementation agnostic.
   41866: ALF-15888: extract caches from fileservers and web-client and provide enterprise overrides
   41881: ALF-15888: replace use of EhCacheAdapter with DefaultSimpleCache and SimpleCache interface.
   41884: ALF-15888: added DefaultSimpleCache configuration to CachingContentStore sample XML.
   41885: ALF-15888: move EhCacheAdapter to new package.
   41886: ALF-15888: correct absolute class names in config for EhCacheAdapter.
   41892: ALF-15888: fix CachingContentStore tests.
   41897: ALF-15888: move CacheTest and config to new package.
   41898: ALF-15888: remove redundant directory
   41899: ALF-15889: move EhCacheManagerFactoryBean to new package.
   41902: ALF-15889: moved EhCacheTracerJob to new package.
   41913: ALF-15889: move InternalEhCacheManagerFactoryBean to new package.
   41916: ALF-15889: move AlfrescoCacheManagerPeerProviderFactory to new package.
   41937: ALF-15889: decouple TransactionalCache from EhCache
   41966: ALF-15889: decouple RetryingTransactionHelper from ehcache.
   41989: ALF-15889: added ContextListener test.
   41996: ALF-15889: moved cache test to its own class.
   41998: ALF-15889: move ehcache jars.
   41999: ALF-15889: modify .classpath to reflect jar moves.
   42037: ALF-15889: update poms to reflect lib moves.
   42038: ALF-15889: add eclipse library reference to enterprise projects.
   42093: ALF-15916: moved core properties to enterprise
   42114: ALF-15888: externalized cache sizes to repository.properties.
   42127: ALF-16136: move re-indexing configuration
   42140: ALF-16136: move cluster check property.
   42186: ALF-15889: removing seemingly redundant test config file.
   42187: ALF-15888: tidy up config changes.
   42189: ALF-15888: cleanup config
   42190: ALF-15888: config cleanup
   42191: ALF-15888: config cleanup
   42198: ALF-16136: restored lost property



git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@42210 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
2012-10-01 12:17:53 +00:00

247 lines
8.2 KiB
Java

/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* 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/>.
*/
package org.alfresco.repo.content;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.alfresco.repo.cache.DefaultSimpleCache;
import org.alfresco.repo.cache.SimpleCache;
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.util.Pair;
import org.alfresco.util.TempFileProvider;
/**
* 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
* all routing scenarios are handled.
*
* @see AbstractRoutingContentStore
* @since 2.1
*
* @author Derek Hulley
*/
public class RoutingContentStoreTest extends AbstractWritableContentStoreTest
{
private ContentStore storeA;
private ContentStore storeB;
private ContentStore storeC;
private ContentStore storeD;
private ContentStore routingStore;
@Override
public void setUp() throws Exception
{
super.setUp();
File tempDir = TempFileProvider.getTempDir();
// Create a subdirectory for A
File storeADir = new File(tempDir, "A");
storeA = new FileContentStore(ctx, storeADir);
// Create a subdirectory for B
File storeBDir = new File(tempDir, "B");
storeB = new FileContentStore(ctx, storeBDir);
// Create a subdirectory for C
File storeCDir = new File(tempDir, "C");
storeC = new DumbReadOnlyFileStore(new FileContentStore(ctx, storeCDir));
// No subdirectory for D
storeD = new SupportsNoUrlFormatStore();
// Create the routing store
routingStore = new RandomRoutingContentStore(storeA, storeB, storeC, storeD);
}
@Override
protected ContentStore getStore()
{
return routingStore;
}
public void testSetUp() throws Exception
{
assertNotNull(routingStore);
}
private void checkForContent(String contentUrl, String content)
{
for (ContentStore store : new ContentStore[] {storeA, storeB})
{
// Does the store have it
if (store.exists(contentUrl))
{
// Check it
ContentReader reader = store.getReader(contentUrl);
String checkContent = reader.getContentString();
assertEquals("Content found but is incorrect", content, checkContent);
return;
}
}
fail("Content not found in any of the stores: " + contentUrl);
}
/**
* Checks that requests for missing content URLs are served.
*/
public void testMissingUrl()
{
String missingContentUrl = FileContentStore.createNewFileStoreUrl();
ContentReader reader = routingStore.getReader(missingContentUrl);
assertNotNull("Missing URL should not return null", reader);
assertFalse("Empty reader should say content doesn't exist.", reader.exists());
try
{
reader.getContentString();
fail("Empty reader cannot return content.");
}
catch (Throwable e)
{
// Expected
}
}
public void testGeneralUse()
{
for (int i = 0 ; i < 20; i++)
{
ContentContext contentContext = new ContentContext(null, null);
ContentWriter writer = routingStore.getWriter(contentContext);
String content = "This was generated by " + this.getClass().getName() + "#" + getName() + " number " + i;
writer.putContent(content);
// Check that it exists
String contentUrl = writer.getContentUrl();
checkForContent(contentUrl, content);
// Now go direct to the routing store and check that it is able to find the appropriate URLs
ContentReader reader = routingStore.getReader(contentUrl);
assertNotNull("Null reader returned", reader);
assertTrue("Reader should be onto live content", reader.exists());
}
}
/**
* A test routing store that directs content writes to a randomly-chosen store.
* Matching of content URLs back to the stores is handled by the base class.
*
* @author Derek Hulley
*/
private static class RandomRoutingContentStore extends AbstractRoutingContentStore
{
private List<ContentStore> stores;
public RandomRoutingContentStore(ContentStore ... stores)
{
this.stores = new ArrayList<ContentStore>(5);
for (ContentStore store : stores)
{
this.stores.add(store);
}
SimpleCache<Pair<String,String>, ContentStore> cache = new DefaultSimpleCache<Pair<String,String>, ContentStore>();
super.setStoresCache(cache);
}
@Override
protected List<ContentStore> getAllStores()
{
return stores;
}
@Override
protected ContentStore selectWriteStore(ContentContext ctx)
{
// Shuffle the list of writable stores
List<ContentStore> shuffled = new ArrayList<ContentStore>(stores);
Collections.shuffle(shuffled);
// Pick the first writable store
for (ContentStore store : shuffled)
{
if (store.isWriteSupported())
{
return store;
}
}
// Nothing found
fail("A request came for a writer when there is no writable store to choose from");
return null;
}
}
/**
* The simplest possible store.
*
* @author Derek Hulley
*/
private static class DumbReadOnlyFileStore extends AbstractContentStore
{
FileContentStore fileStore;
public DumbReadOnlyFileStore(FileContentStore fileStore)
{
this.fileStore = fileStore;
}
public boolean isWriteSupported()
{
return false;
}
public ContentReader getReader(String contentUrl)
{
return fileStore.getReader(contentUrl);
}
@Override
public void getUrls(Date createdAfter, Date createdBefore, ContentUrlHandler handler) throws ContentIOException
{
fileStore.getUrls(createdAfter, createdBefore, handler);
}
}
/**
* This store supports nothing. It is designed to catch the routing code out.
*
* @author Derek Hulley
*/
private static class SupportsNoUrlFormatStore extends AbstractContentStore
{
public SupportsNoUrlFormatStore()
{
}
public boolean isWriteSupported()
{
return false;
}
public ContentReader getReader(String contentUrl)
{
throw new UnsupportedContentUrlException(this, contentUrl);
}
@Override
public void getUrls(Date createdAfter, Date createdBefore, ContentUrlHandler handler) throws ContentIOException
{
throw new UnsupportedOperationException("getUrls not supported");
}
}
}