mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Merged HEAD-BUG-FIX (5.1/Cloud) to HEAD (5.1/Cloud)
99376: BENCH-371: BM-0004: Copy Alfresco and set up build plan - Modify FileContentStore to service 'spoof://' URLs - SpoofedTextContentReader to generate consistent text for URL - Fix FileContentStoreTest so that tests actually execute - Add override for @After so that no NPEs are thrown - Add tests for the 'spoof://' protocol - Some additional checks for IllegalArgumentException on SpoofedTextContentReader construction - Force delete of 'spoof' to return false but not fail with an exception This is handled neatly by the EagerContentStoreCleaner, which accepts that the stores may protect data according to their own needs e.g. Centera - Add spoofing option to FileFolderPerformanceTester 290 files/s for 1K files vs 460 files/s for spoofed text files (no binary streaming required) - Start FileFolderLoader component that will be used by the API git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@99502 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -148,6 +148,13 @@
|
||||
<property name="enabled" value="${fileFolderService.checkHidden.enabled}" />
|
||||
</bean>
|
||||
|
||||
<!-- FileFolderLoader and required beans -->
|
||||
<bean name="fileFolderLoader" class="org.alfresco.repo.model.filefolder.FileFolderLoader">
|
||||
<constructor-arg ref="repositoryState" />
|
||||
<constructor-arg ref="transactionService" />
|
||||
<constructor-arg ref="repositoryHelper" />
|
||||
</bean>
|
||||
|
||||
<!-- Multilingual specific service -->
|
||||
<bean name="multilingualContentService" class="org.alfresco.repo.model.ml.MultilingualContentServiceImpl" >
|
||||
<property name="nodeService">
|
||||
|
18
pom.xml
18
pom.xml
@@ -25,12 +25,17 @@
|
||||
<artifactId>alfresco-mbeans</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.alfresco.services</groupId>
|
||||
<artifactId>alfresco-events</artifactId>
|
||||
<version>1.2.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<dependency>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-text-gen</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.alfresco.services</groupId>
|
||||
<artifactId>alfresco-events</artifactId>
|
||||
<version>1.2.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.mail</groupId>
|
||||
<artifactId>javax.mail</artifactId>
|
||||
<version>1.5.2</version>
|
||||
@@ -995,6 +1000,7 @@
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/org/alfresco/AllUnitTestsSuite.java</include>
|
||||
<include>**/org/alfresco/repo/model/filefolder/FileFolderPerformanceTester.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
@@ -21,6 +21,8 @@ package org.alfresco.repo.admin;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
/**
|
||||
* A class that maintains a thread-safe ready indicator on the current bootstrap state of the repository.
|
||||
*
|
||||
* @author Andy
|
||||
*
|
||||
*/
|
||||
@@ -29,6 +31,12 @@ public class RepositoryState
|
||||
private boolean bootstrapping;
|
||||
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
|
||||
/**
|
||||
* Determine if the repository is ready to use.
|
||||
*
|
||||
* @return <tt>true</tt> if the repository bootstrap process is still going,
|
||||
* or <tt>false</tt> if the repository is ready to use
|
||||
*/
|
||||
public boolean isBootstrapping()
|
||||
{
|
||||
this.lock.readLock().lock();
|
||||
|
@@ -239,7 +239,9 @@ public class FileContentReader extends AbstractContentReader
|
||||
|
||||
/**
|
||||
* @return Returns false as this is a reader
|
||||
* @deprecated Since 5.1. This method has no value: a file reader can never write (DH: 2015/02/17)
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean canWrite()
|
||||
{
|
||||
return false; // we only allow reading
|
||||
|
@@ -55,7 +55,12 @@ import org.springframework.context.event.ContextRefreshedEvent;
|
||||
* are generated using information from the {@link ContentContext simple content context}.
|
||||
* <p>
|
||||
* The file names obey, as they must, the URL naming convention
|
||||
* as specified in the {@link org.alfresco.repo.content.ContentStore ContentStore interface}.
|
||||
* as specified in the {@link org.alfresco.repo.content.ContentStore ContentStore interface}.<br/>
|
||||
* The protocols handled are:
|
||||
* <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 #SPOOF_PROTOCOL spoof}</b>: These URLs are never generated by the implementation but represent spoofed binary text stream data: TODO</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
@@ -64,10 +69,11 @@ public class FileContentStore
|
||||
implements ApplicationContextAware, ApplicationListener<ApplicationEvent>
|
||||
{
|
||||
/**
|
||||
* <b>store</b> is the new prefix for file content URLs
|
||||
* <b>store</b> is the default prefix for file content URLs
|
||||
* @see ContentStore#PROTOCOL_DELIMITER
|
||||
*/
|
||||
public static final String STORE_PROTOCOL = "store";
|
||||
public static final String SPOOF_PROTOCOL = "spoof";
|
||||
|
||||
private static final Log logger = LogFactory.getLog(FileContentStore.class);
|
||||
|
||||
@@ -343,10 +349,20 @@ public class FileContentStore
|
||||
Pair<String, String> urlParts = super.getContentUrlParts(contentUrl);
|
||||
String protocol = urlParts.getFirst();
|
||||
String relativePath = urlParts.getSecond();
|
||||
return makeFile(protocol, relativePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the file based on the content URL parts.
|
||||
*
|
||||
* @param protocol must be {@link ContentStore#PROTOCOL_DELIMITER} for this class
|
||||
*/
|
||||
private File makeFile(String protocol, String relativePath)
|
||||
{
|
||||
// Check the protocol
|
||||
if (!protocol.equals(FileContentStore.STORE_PROTOCOL))
|
||||
{
|
||||
throw new UnsupportedContentUrlException(this, contentUrl);
|
||||
throw new UnsupportedContentUrlException(this, protocol + PROTOCOL_DELIMITER + relativePath);
|
||||
}
|
||||
// get the file
|
||||
File file = new File(rootDirectory, relativePath);
|
||||
@@ -367,12 +383,23 @@ public class FileContentStore
|
||||
|
||||
/**
|
||||
* Performs a direct check against the file for its existence.
|
||||
* For {@link #SPOOF_PROTOCOL spoofed} URLs, the URL always exists.
|
||||
*/
|
||||
@Override
|
||||
public boolean exists(String contentUrl)
|
||||
{
|
||||
File file = makeFile(contentUrl);
|
||||
return file.exists();
|
||||
Pair<String, String> urlParts = super.getContentUrlParts(contentUrl);
|
||||
String protocol = urlParts.getFirst();
|
||||
String relativePath = urlParts.getSecond();
|
||||
if (protocol.equals(SPOOF_PROTOCOL))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
File file = makeFile(protocol, relativePath);
|
||||
return file.exists();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -420,9 +447,18 @@ public class FileContentStore
|
||||
*/
|
||||
public ContentReader getReader(String contentUrl)
|
||||
{
|
||||
Pair<String, String> urlParts = super.getContentUrlParts(contentUrl);
|
||||
String protocol = urlParts.getFirst();
|
||||
String relativePath = urlParts.getSecond();
|
||||
// Handle the spoofed URL
|
||||
if (protocol.equals(SPOOF_PROTOCOL))
|
||||
{
|
||||
return new SpoofedTextContentReader(contentUrl);
|
||||
}
|
||||
// else, it's a real file we are after
|
||||
try
|
||||
{
|
||||
File file = makeFile(contentUrl);
|
||||
File file = makeFile(protocol, relativePath);
|
||||
ContentReader reader = null;
|
||||
if (file.exists())
|
||||
{
|
||||
@@ -590,11 +626,21 @@ public class FileContentStore
|
||||
{
|
||||
throw new UnsupportedOperationException("This store is currently read-only: " + this);
|
||||
}
|
||||
// ignore files that don't exist
|
||||
File file = makeFile(contentUrl);
|
||||
// Dig out protocol
|
||||
Pair<String, String> urlParts = super.getContentUrlParts(contentUrl);
|
||||
String protocol = urlParts.getFirst();
|
||||
String relativePath = urlParts.getSecond();
|
||||
if (protocol.equals(SPOOF_PROTOCOL))
|
||||
{
|
||||
// This is not a failure but the content can never actually be deleted
|
||||
return false;
|
||||
}
|
||||
// Handle regular files based on the real files
|
||||
File file = makeFile(protocol, relativePath);
|
||||
boolean deleted = false;
|
||||
if (!file.exists())
|
||||
{
|
||||
// File does not exist
|
||||
deleted = true;
|
||||
}
|
||||
else
|
||||
@@ -618,8 +664,6 @@ public class FileContentStore
|
||||
return deleted;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new content URL. This must be supported by all
|
||||
* stores that are compatible with Alfresco.
|
||||
|
@@ -0,0 +1,311 @@
|
||||
/*
|
||||
* 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.filestore;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import org.alfresco.repo.content.AbstractContentReader;
|
||||
import org.alfresco.repo.content.ContentStore;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.textgen.TextGenerator;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
|
||||
/**
|
||||
* Provides access to text data that is generated when requested.
|
||||
* <p/>
|
||||
* The URL has the format: <b>spoofed://{locale=en_GB,seed=12345,length=1024,strings=["Alfresco", "Cloud"]}
|
||||
* <p/>
|
||||
* The lexicon for the given locale is found by taking the language part of the locale (<b>en</b> in <b>en_GB</b>)
|
||||
* and finding the resource <b>alfresco/textgen/lexicon-stem-en.txt</b>.
|
||||
*
|
||||
* @see TextGenerator
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 5.1
|
||||
*/
|
||||
public class SpoofedTextContentReader extends AbstractContentReader
|
||||
{
|
||||
public static final String LEXICON_STEM_PATH = "alfresco/textgen/lexicon-stem-@@LOCALE@@.txt";
|
||||
public static final String KEY_LOCALE = "locale";
|
||||
public static final String KEY_SEED = "seed";
|
||||
public static final String KEY_SIZE = "size";
|
||||
public static final String KEY_WORDS = "words";
|
||||
|
||||
private static Map<Locale, TextGenerator> textGeneratorsByLocale = new HashMap<Locale, TextGenerator>();
|
||||
private static ReentrantReadWriteLock textGeneratorsLock = new ReentrantReadWriteLock();
|
||||
|
||||
private static final Log logger = LogFactory.getLog(SpoofedTextContentReader.class);
|
||||
|
||||
private final TextGenerator textGenerator;
|
||||
private final long seed;
|
||||
private final long size;
|
||||
private final String[] words;
|
||||
|
||||
/**
|
||||
* Get a text generator for the given locale
|
||||
*
|
||||
* @throws RuntimeException if the locale has no lexicon exists for the locale
|
||||
*/
|
||||
public static TextGenerator getTextGenerator(Locale locale)
|
||||
{
|
||||
textGeneratorsLock.readLock().lock();
|
||||
try
|
||||
{
|
||||
TextGenerator tg = textGeneratorsByLocale.get(locale);
|
||||
if (tg != null)
|
||||
{
|
||||
return tg;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
textGeneratorsLock.readLock().unlock();
|
||||
}
|
||||
// Create one
|
||||
textGeneratorsLock.writeLock().lock();
|
||||
try
|
||||
{
|
||||
// Double check
|
||||
TextGenerator tg = textGeneratorsByLocale.get(locale);
|
||||
if (tg != null)
|
||||
{
|
||||
return tg;
|
||||
}
|
||||
// Create it
|
||||
String lang = locale.getLanguage();
|
||||
String configPath = LEXICON_STEM_PATH.replace("@@LOCALE@@", lang);
|
||||
tg = new TextGenerator(configPath);
|
||||
// Store it
|
||||
textGeneratorsByLocale.put(locale, tg);
|
||||
// Done
|
||||
return tg;
|
||||
}
|
||||
finally
|
||||
{
|
||||
textGeneratorsLock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to create a content URL that represents spoofed text
|
||||
*
|
||||
* @param locale the text local (must be supported by an appropriate lexicon config resource)
|
||||
* @param seed numerical seed to ensure repeatable sequences of random text
|
||||
* @param size the size (bytes) of the text to generate
|
||||
* @param words additional words with decreasing frequency
|
||||
* @return the content URL
|
||||
*
|
||||
* @throws IllegalArgumentException if the resulting URL exceeds 255 characters
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static String createContentUrl(Locale locale, long seed, long size, String ... words)
|
||||
{
|
||||
if (locale == null || size < 0L)
|
||||
{
|
||||
throw new IllegalArgumentException("Locale must be supplied and size must be zero or greater.");
|
||||
}
|
||||
|
||||
// Make sure that there is a text generator available
|
||||
SpoofedTextContentReader.getTextGenerator(locale);
|
||||
|
||||
// Build map
|
||||
String url = null;
|
||||
try
|
||||
{
|
||||
JSONObject jsonObj = new JSONObject();
|
||||
jsonObj.put(KEY_LOCALE, locale.toString());
|
||||
jsonObj.put(KEY_SEED, Long.valueOf(seed).toString());
|
||||
jsonObj.put(KEY_SIZE, Long.valueOf(size).toString());
|
||||
JSONArray jsonWords = new JSONArray();
|
||||
for (String word : words)
|
||||
{
|
||||
if (word == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Words to inject into the document may not be null.");
|
||||
}
|
||||
jsonWords.add(word);
|
||||
}
|
||||
jsonObj.put(KEY_WORDS, jsonWords);
|
||||
|
||||
url = FileContentStore.SPOOF_PROTOCOL + "://" + jsonObj.toString();
|
||||
if (url.length() > 255)
|
||||
{
|
||||
throw new IllegalArgumentException("Content URLs can be up to 255 characters. Have " + url.length() + " characters: " + url);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
// Let these out as they are
|
||||
throw e;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException("Unable to create content URL using " + locale + ", " + seed + ", " + size + ", " + words, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param url a URL describing the type of text to produce (see class comments)
|
||||
*/
|
||||
public SpoofedTextContentReader(String url)
|
||||
{
|
||||
super(url);
|
||||
if (url.length() > 255)
|
||||
{
|
||||
throw new IllegalArgumentException("A content URL is limited to 255 characters: " + url);
|
||||
}
|
||||
// Split out data part
|
||||
int index = url.indexOf(ContentStore.PROTOCOL_DELIMITER);
|
||||
if (index <= 0 || !url.startsWith(FileContentStore.SPOOF_PROTOCOL))
|
||||
{
|
||||
throw new RuntimeException("URL not supported by this reader: " + url);
|
||||
}
|
||||
String urlData = url.substring(index + 3, url.length());
|
||||
// Parse URL
|
||||
try
|
||||
{
|
||||
JSONParser parser = new JSONParser();
|
||||
JSONObject mappedData = (JSONObject) parser.parse(urlData);
|
||||
|
||||
String jsonLocale = mappedData.containsKey(KEY_LOCALE) ? (String) mappedData.get(KEY_LOCALE) : Locale.ENGLISH.toString();
|
||||
String jsonSeed = mappedData.containsKey(KEY_SEED) ? (String) mappedData.get(KEY_SEED) : "0";
|
||||
String jsonSize = mappedData.containsKey(KEY_SIZE) ? (String) mappedData.get(KEY_SIZE) : "1024";
|
||||
JSONArray jsonWords = mappedData.containsKey(KEY_WORDS) ? (JSONArray) mappedData.get(KEY_WORDS) : new JSONArray();
|
||||
// Get the text generator
|
||||
Locale locale = new Locale(jsonLocale);
|
||||
seed = Long.valueOf(jsonSeed);
|
||||
size = Long.valueOf(jsonSize);
|
||||
words = new String[jsonWords.size()];
|
||||
for (int i = 0; i < words.length; i++)
|
||||
{
|
||||
words[i] = (String) jsonWords.get(i);
|
||||
}
|
||||
this.textGenerator = SpoofedTextContentReader.getTextGenerator(locale);
|
||||
// Set the base class storage for external information
|
||||
super.setLocale(locale);
|
||||
super.setEncoding("UTF-8");
|
||||
super.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException("Unable to interpret URL: " + url, e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <tt>true</tt> always
|
||||
*/
|
||||
public boolean exists()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the text generator that will make the spoofed text
|
||||
*/
|
||||
public TextGenerator getTextGenerator()
|
||||
{
|
||||
return textGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the random seed for the spoofed text
|
||||
*/
|
||||
public long getSeed()
|
||||
{
|
||||
return seed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the words to add to the spoofed text
|
||||
*/
|
||||
public String[] getWords()
|
||||
{
|
||||
return words;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return spoofed text size
|
||||
*/
|
||||
public long getSize()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see File#lastModified()
|
||||
*/
|
||||
public long getLastModified()
|
||||
{
|
||||
return 0L;
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL of the write is known from the start and this method contract states
|
||||
* that no consideration needs to be taken w.r.t. the stream state.
|
||||
*/
|
||||
@Override
|
||||
protected ContentReader createReader() throws ContentIOException
|
||||
{
|
||||
SpoofedTextContentReader reader = new SpoofedTextContentReader(getContentUrl());
|
||||
return reader;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReadableByteChannel getDirectReadableChannel() throws ContentIOException
|
||||
{
|
||||
try
|
||||
{
|
||||
// Interpret the URL to generate the text
|
||||
InputStream textStream = textGenerator.getInputStream(seed, size, words);
|
||||
ReadableByteChannel textChannel = Channels.newChannel(textStream);
|
||||
// done
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Opened read channel to random text for URL: " + getContentUrl());
|
||||
}
|
||||
return textChannel;
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
throw new ContentIOException("Failed to read channel: " + this, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void setContentUrl(String contentUrl)
|
||||
{
|
||||
throw new UnsupportedOperationException("The URL is static and cannot be changed.");
|
||||
}
|
||||
}
|
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2015 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.model.filefolder;
|
||||
|
||||
import org.alfresco.repo.admin.RepositoryState;
|
||||
import org.alfresco.repo.model.Repository;
|
||||
import org.alfresco.service.cmr.model.FileNotFoundException;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
|
||||
/**
|
||||
* Class to aid in the generation of file-folder data structures for load test purposes.
|
||||
* <p/>
|
||||
* All paths referenced are in relation to the standard Alfresco "Company Home" folder,
|
||||
* which acts as the root for accessing documents and folders via many APIs.
|
||||
* <p/>
|
||||
* <strong>WARNING: This class may be used but will probably NOT be considered part of the public API i.e.
|
||||
* will probably change in line with Alfresco's internal requirements; nevertheless, backward
|
||||
* compatibility will be maintained where practical.</strong>
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 5.1
|
||||
*/
|
||||
public class FileFolderLoader
|
||||
{
|
||||
private final RepositoryState repoState;
|
||||
private final TransactionService transactionService;
|
||||
private final Repository repositoryHelper;
|
||||
|
||||
/**
|
||||
* @param repoState keep track of repository readiness
|
||||
* @param transactionService ensure proper rollback, where required
|
||||
* @param repositoryHelper access standard repository paths
|
||||
*/
|
||||
public FileFolderLoader(RepositoryState repoState, TransactionService transactionService, Repository repositoryHelper)
|
||||
{
|
||||
this.repoState = repoState;
|
||||
this.transactionService = transactionService;
|
||||
this.repositoryHelper = repositoryHelper;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param folderPath the full path to the folder
|
||||
* @param fileCount the number of files to create
|
||||
* @param minFileSize the smallest file size (all sizes within 1 standard deviation of the mean)
|
||||
* @param maxFileSize the largest file size (all sizes within 1 standard deviation of the mean)
|
||||
* @param uniqueContentCount the total number of unique files that can be generated i.e. each file will be
|
||||
* one of a total number of unique files.
|
||||
* @param forceBinaryStorage <tt>true</tt> to actually write the spoofed text data to the binary store
|
||||
* i.e. the physical underlying storage will have a real file
|
||||
* @return the number of files successfully created
|
||||
* @throws FileNotFoundException if the folder path does not exist
|
||||
* @throws IllegalStateException if the repository is not ready
|
||||
*/
|
||||
public int createFiles(
|
||||
String folderPath,
|
||||
int fileCount,
|
||||
long minFileSize, long maxFileSize,
|
||||
boolean forceBinaryStorage,
|
||||
long uniqueContentCount) throws FileNotFoundException
|
||||
{
|
||||
if (repoState.isBootstrapping())
|
||||
{
|
||||
throw new IllegalStateException("Repository is still bootstrapping.");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
@@ -18,11 +18,6 @@
|
||||
*/
|
||||
package org.alfresco.repo.content;
|
||||
|
||||
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.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
@@ -46,6 +41,11 @@ import org.junit.Test;
|
||||
import org.junit.rules.TestName;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
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
|
||||
* of {@link ContentStore}.
|
||||
|
@@ -26,6 +26,7 @@ import org.alfresco.repo.content.cleanup.ContentStoreCleanerTest;
|
||||
import org.alfresco.repo.content.filestore.FileContentStoreTest;
|
||||
import org.alfresco.repo.content.filestore.NoRandomAccessFileContentStoreTest;
|
||||
import org.alfresco.repo.content.filestore.ReadOnlyFileContentStoreTest;
|
||||
import org.alfresco.repo.content.filestore.SpoofedTextContentReaderTest;
|
||||
import org.alfresco.repo.content.replication.ContentStoreReplicatorTest;
|
||||
import org.alfresco.repo.content.replication.ReplicatingContentStoreTest;
|
||||
|
||||
@@ -47,6 +48,7 @@ public class ContentFullContextTestSuite extends TestSuite
|
||||
// These tests need a full context, at least for now
|
||||
suite.addTestSuite(ContentStoreCleanerTest.class);
|
||||
//suite.addTestSuite(CharsetFinderTest.class);
|
||||
suite.addTest(new JUnit4TestAdapter(SpoofedTextContentReaderTest.class));
|
||||
suite.addTest(new JUnit4TestAdapter(FileContentStoreTest.class));
|
||||
suite.addTest(new JUnit4TestAdapter(NoRandomAccessFileContentStoreTest.class));
|
||||
suite.addTest(new JUnit4TestAdapter(ReadOnlyFileContentStoreTest.class));
|
||||
|
@@ -18,14 +18,9 @@
|
||||
*/
|
||||
package org.alfresco.repo.content.filestore;
|
||||
|
||||
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.nio.ByteBuffer;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.alfresco.repo.content.AbstractWritableContentStoreTest;
|
||||
import org.alfresco.repo.content.ContentContext;
|
||||
@@ -35,12 +30,21 @@ import org.alfresco.repo.content.ContentLimitProvider.SimpleFixedLimitProvider;
|
||||
import org.alfresco.repo.content.ContentLimitViolationException;
|
||||
import org.alfresco.repo.content.ContentStore;
|
||||
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.TempFileProvider;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Tests read and write functionality for the store.
|
||||
*
|
||||
@@ -64,6 +68,13 @@ public class FileContentStoreTest extends AbstractWritableContentStoreTest
|
||||
getName());
|
||||
|
||||
store.setDeleteEmptyDirs(true);
|
||||
// Do not need super class's transactions
|
||||
}
|
||||
|
||||
@After
|
||||
public void after()
|
||||
{
|
||||
// Do not need super class's transactions
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -76,6 +87,7 @@ public class FileContentStoreTest extends AbstractWritableContentStoreTest
|
||||
* Checks that the store disallows concurrent writers to be issued to the same URL.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
@Test
|
||||
public void testConcurrentWriteDetection() throws Exception
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.wrap("Something".getBytes());
|
||||
@@ -98,6 +110,7 @@ public class FileContentStoreTest extends AbstractWritableContentStoreTest
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
public void testRootLocation() throws Exception
|
||||
{
|
||||
ContentStore store = getStore();
|
||||
@@ -111,6 +124,7 @@ public class FileContentStoreTest extends AbstractWritableContentStoreTest
|
||||
* Ensures that the size is something other than <tt>-1</tt> or <tt>Long.MAX_VALUE</tt>
|
||||
*/
|
||||
@Override
|
||||
@Test
|
||||
public void testSpaceFree() throws Exception
|
||||
{
|
||||
ContentStore store = getStore();
|
||||
@@ -123,6 +137,7 @@ public class FileContentStoreTest extends AbstractWritableContentStoreTest
|
||||
* Ensures that the size is something other than <tt>-1</tt> or <tt>Long.MAX_VALUE</tt>
|
||||
*/
|
||||
@Override
|
||||
@Test
|
||||
public void testSpaceTotal() throws Exception
|
||||
{
|
||||
ContentStore store = getStore();
|
||||
@@ -135,6 +150,7 @@ public class FileContentStoreTest extends AbstractWritableContentStoreTest
|
||||
/**
|
||||
* Empty parent directories should be removed when a URL is removed.
|
||||
*/
|
||||
@Test
|
||||
public void testDeleteRemovesEmptyDirs() throws Exception
|
||||
{
|
||||
ContentStore store = getStore();
|
||||
@@ -161,6 +177,7 @@ public class FileContentStoreTest extends AbstractWritableContentStoreTest
|
||||
/**
|
||||
* Only non-empty directories should be deleted.
|
||||
*/
|
||||
@Test
|
||||
public void testDeleteLeavesNonEmptyDirs()
|
||||
{
|
||||
ContentStore store = getStore();
|
||||
@@ -198,6 +215,7 @@ public class FileContentStoreTest extends AbstractWritableContentStoreTest
|
||||
/**
|
||||
* Empty parent directories are not deleted if the store is configured not to.
|
||||
*/
|
||||
@Test
|
||||
public void testNoParentDirsDeleted() throws Exception
|
||||
{
|
||||
store.setDeleteEmptyDirs(false);
|
||||
@@ -221,6 +239,7 @@ public class FileContentStoreTest extends AbstractWritableContentStoreTest
|
||||
* the expected exception.
|
||||
* @since Thor
|
||||
*/
|
||||
@Test
|
||||
public void testWriteFileWithSizeLimit() throws Exception
|
||||
{
|
||||
ContentWriter writer = getWriter();
|
||||
@@ -247,9 +266,10 @@ public class FileContentStoreTest extends AbstractWritableContentStoreTest
|
||||
assertTrue("Stream close not detected", writer.isClosed());
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Test for MNT-12301 case.
|
||||
*/
|
||||
@Test
|
||||
public void testFileAccessOutsideStoreRoot()
|
||||
{
|
||||
String url = FileContentStore.STORE_PROTOCOL + ContentStore.PROTOCOL_DELIMITER + "../somefile.bin";
|
||||
@@ -295,6 +315,31 @@ public class FileContentStoreTest extends AbstractWritableContentStoreTest
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that the store is able to produce readers for spoofed text.
|
||||
*
|
||||
* @since 5.1
|
||||
*/
|
||||
@Test
|
||||
public void testSpoofedContent() throws Exception
|
||||
{
|
||||
String url = SpoofedTextContentReader.createContentUrl(Locale.ENGLISH, 0L, 1024L);
|
||||
ContentContext ctx = new ContentContext(null, url);
|
||||
try
|
||||
{
|
||||
store.getWriter(ctx);
|
||||
fail("FileContentStore should report that all 'spoof' content exists.");
|
||||
}
|
||||
catch (ContentExistsException e)
|
||||
{
|
||||
// Expected
|
||||
}
|
||||
assertFalse("Deletion should be 'false'.", store.delete(url));
|
||||
assertTrue("All spoofed content already exists!", store.exists(url));
|
||||
ContentReader reader = store.getReader(url);
|
||||
assertTrue(reader instanceof SpoofedTextContentReader);
|
||||
assertEquals(1024L, reader.getContentString().getBytes("UTF-8").length);
|
||||
}
|
||||
|
||||
private void assertDirExists(File root, String dir)
|
||||
{
|
||||
|
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* 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.filestore;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Locale;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.alfresco.repo.content.AbstractContentReader;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||
import org.alfresco.service.cmr.repository.ContentReader;
|
||||
import org.alfresco.test_category.OwnJVMTestsCategory;
|
||||
import org.junit.Before;
|
||||
import org.junit.experimental.categories.Category;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
/**
|
||||
* Text spoofing as a {@link ContentReader}
|
||||
*
|
||||
* @see SpoofedTextContentReader
|
||||
*
|
||||
* @author Derek Hulley
|
||||
* @since 5.1
|
||||
*/
|
||||
@Category(OwnJVMTestsCategory.class)
|
||||
public class SpoofedTextContentReaderTest extends TestCase
|
||||
{
|
||||
@Before
|
||||
public void before()
|
||||
{
|
||||
// Nothing
|
||||
}
|
||||
|
||||
public void testStaticUrlHandlingErr()
|
||||
{
|
||||
try
|
||||
{
|
||||
SpoofedTextContentReader.createContentUrl(null, 12345L, 1024L);
|
||||
fail();
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
// Expected
|
||||
}
|
||||
try
|
||||
{
|
||||
SpoofedTextContentReader.createContentUrl(Locale.ENGLISH, 12345L, -1L);
|
||||
fail();
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
// Expected
|
||||
}
|
||||
try
|
||||
{
|
||||
SpoofedTextContentReader.createContentUrl(Locale.ENGLISH, 12345L, 1024L, (String) null);
|
||||
fail();
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
// Expected
|
||||
}
|
||||
try
|
||||
{
|
||||
SpoofedTextContentReader.createContentUrl(Locale.FRENCH, 12345L, 1024L);
|
||||
fail();
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
// Expected
|
||||
}
|
||||
try
|
||||
{
|
||||
SpoofedTextContentReader.createContentUrl(
|
||||
Locale.ENGLISH, 12345L, 1024L,
|
||||
"1234567890ABCDEFGHIJ", "1234567890ABCDEFGHIJ", "1234567890ABCDEFGHIJ", "1234567890ABCDEFGHIJ", "1234567890ABCDEFGHIJ",
|
||||
"1234567890ABCDEFGHIJ", "1234567890ABCDEFGHIJ", "1234567890ABCDEFGHIJ", "1234567890ABCDEFGHIJ", "1234567890ABCDEFGHIJ",
|
||||
"1234567890ABCDEFGHIJ", "1234567890ABCDEFGHIJ", "1234567890ABCDEFGHIJ", "1234567890ABCDEFGHIJ", "1234567890ABCDEFGHIJ");
|
||||
fail();
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testStaticUrlForm_01()
|
||||
{
|
||||
// To URL
|
||||
String url = SpoofedTextContentReader.createContentUrl(Locale.ENGLISH, 12345L, 1024L, "harry");
|
||||
assertTrue(url.startsWith("spoof://{"));
|
||||
assertTrue(url.contains("\"locale\":\"en\""));
|
||||
assertTrue(url.contains("\"seed\":\"12345\""));
|
||||
assertTrue(url.contains("\"size\":\"1024\""));
|
||||
assertTrue(url.contains("\"words\":[\"harry\"]"));
|
||||
assertTrue(url.endsWith("}"));
|
||||
// From Reader
|
||||
SpoofedTextContentReader reader = new SpoofedTextContentReader(url);
|
||||
assertNotNull(reader.getTextGenerator());
|
||||
assertEquals(Locale.ENGLISH, reader.getLocale());
|
||||
assertEquals(MimetypeMap.MIMETYPE_TEXT_PLAIN, reader.getMimetype());
|
||||
assertEquals("UTF-8", reader.getEncoding());
|
||||
assertEquals(12345L, reader.getSeed());
|
||||
assertEquals(1024L, reader.getSize());
|
||||
assertNotNull(reader.getWords());
|
||||
assertEquals(1, reader.getWords().length);
|
||||
assertEquals("harry", reader.getWords()[0]);
|
||||
}
|
||||
|
||||
public void testStaticUrlForm_02()
|
||||
{
|
||||
// To URL
|
||||
String url = SpoofedTextContentReader.createContentUrl(Locale.ENGLISH, 12345L, 1024L);
|
||||
assertTrue(url.startsWith("spoof://{"));
|
||||
assertTrue(url.contains("\"locale\":\"en\""));
|
||||
assertTrue(url.contains("\"seed\":\"12345\""));
|
||||
assertTrue(url.contains("\"size\":\"1024\""));
|
||||
assertTrue(url.contains("\"words\":[]"));
|
||||
assertTrue(url.endsWith("}"));
|
||||
// From Reader
|
||||
SpoofedTextContentReader reader = new SpoofedTextContentReader(url);
|
||||
assertNotNull(reader.getTextGenerator());
|
||||
assertEquals(Locale.ENGLISH, reader.getLocale());
|
||||
assertEquals(MimetypeMap.MIMETYPE_TEXT_PLAIN, reader.getMimetype());
|
||||
assertEquals("UTF-8", reader.getEncoding());
|
||||
assertEquals(12345L, reader.getSeed());
|
||||
assertEquals(1024L, reader.getSize());
|
||||
assertNotNull(reader.getWords());
|
||||
assertEquals(0, reader.getWords().length);
|
||||
}
|
||||
|
||||
public void testGetContentString_01()
|
||||
{
|
||||
// To URL
|
||||
String url = SpoofedTextContentReader.createContentUrl(Locale.ENGLISH, 12345L, 56L, "harry");
|
||||
// To Reader
|
||||
ContentReader reader = new SpoofedTextContentReader(url);
|
||||
String readerText = reader.getContentString();
|
||||
assertEquals("harry have voice the from countered growth invited ", readerText);
|
||||
// Cannot repeat
|
||||
try
|
||||
{
|
||||
reader.getContentString();
|
||||
fail("Should not be able to reread content.");
|
||||
}
|
||||
catch (ContentIOException e)
|
||||
{
|
||||
// Expected
|
||||
}
|
||||
// Get a new Reader
|
||||
reader = reader.getReader();
|
||||
// Get exactly the same text
|
||||
assertEquals(readerText, reader.getContentString());
|
||||
}
|
||||
|
||||
public void testGetContentBinary_01() throws Exception
|
||||
{
|
||||
// To URL
|
||||
String url = SpoofedTextContentReader.createContentUrl(Locale.ENGLISH, 12345L, 56L, "harry");
|
||||
// To Reader
|
||||
ContentReader reader = new SpoofedTextContentReader(url);
|
||||
InputStream is = reader.getContentInputStream();
|
||||
try
|
||||
{
|
||||
byte[] bytes = FileCopyUtils.copyToByteArray(is);
|
||||
assertEquals(56L, bytes.length);
|
||||
}
|
||||
finally
|
||||
{
|
||||
is.close();
|
||||
}
|
||||
// Compare readers
|
||||
ContentReader copyOne = reader.getReader();
|
||||
ContentReader copyTwo = reader.getReader();
|
||||
// Get exactly the same binaries
|
||||
assertTrue(AbstractContentReader.compareContentReaders(copyOne, copyTwo));
|
||||
}
|
||||
}
|
@@ -52,6 +52,7 @@ import org.junit.runners.Suite.SuiteClasses;
|
||||
// These need to come afterwards, as they insert extra
|
||||
// interceptors which would otherwise confuse things
|
||||
FileFolderServiceImplTest.class,
|
||||
// TODO
|
||||
FileFolderDuplicateChildTest.class,
|
||||
FileFolderServicePropagationTest.class
|
||||
})
|
||||
|
@@ -24,12 +24,14 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.content.filestore.SpoofedTextContentReader;
|
||||
import org.alfresco.repo.content.transform.AbstractContentTransformerTest;
|
||||
import org.alfresco.repo.dictionary.DictionaryDAO;
|
||||
import org.alfresco.repo.dictionary.M2Model;
|
||||
@@ -41,6 +43,7 @@ import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransacti
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
@@ -164,9 +167,10 @@ public class FileFolderPerformanceTester extends TestCase
|
||||
* <p>
|
||||
* Each creation (file or folder) uses the <b>PROPAGATION REQUIRED</b> transaction declaration.
|
||||
*
|
||||
* @param parentNodeRef the level zero parent
|
||||
* @param randomOrder true if each thread must put the children into the folders in a random order
|
||||
* @return Returns the average time (ms) to create the <b>files only</b>
|
||||
* @param parentNodeRef the level zero parent
|
||||
* @param randomOrder true if each thread must put the children into the folders in a random order
|
||||
* @param realFile <tt>true</tt> if a real binary must be streamed into the node
|
||||
* @return Returns the average time (ms) to create the <b>files only</b>
|
||||
*/
|
||||
private void buildStructure(
|
||||
final NodeRef parentNodeRef,
|
||||
@@ -175,6 +179,7 @@ public class FileFolderPerformanceTester extends TestCase
|
||||
final int folderCount,
|
||||
final int batchCount,
|
||||
final int filesPerBatch,
|
||||
final boolean realFile,
|
||||
final double[] dumpPoints)
|
||||
{
|
||||
RetryingTransactionCallback<NodeRef[]> createFoldersCallback = new RetryingTransactionCallback<NodeRef[]>()
|
||||
@@ -240,11 +245,25 @@ public class FileFolderPerformanceTester extends TestCase
|
||||
GUID.generate(),
|
||||
ContentModel.TYPE_CONTENT);
|
||||
NodeRef nodeRef = fileInfo.getNodeRef();
|
||||
// write the content
|
||||
ContentWriter writer = fileFolderService.getWriter(nodeRef);
|
||||
writer.setEncoding("UTF-8");
|
||||
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||
writer.putContent(dataFile);
|
||||
if (realFile)
|
||||
{
|
||||
// write the content
|
||||
ContentWriter writer = fileFolderService.getWriter(nodeRef);
|
||||
writer.setEncoding("UTF-8");
|
||||
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
||||
writer.putContent(dataFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Spoof some content
|
||||
String contentUrl = SpoofedTextContentReader.createContentUrl(
|
||||
Locale.ENGLISH,
|
||||
(long) Math.random() * 1000L,
|
||||
(long) Math.random() * 1024L);
|
||||
SpoofedTextContentReader reader = new SpoofedTextContentReader(contentUrl);
|
||||
ContentData contentData = reader.getContentData();
|
||||
nodeService.setProperty(nodeRef, ContentModel.PROP_CONTENT, contentData);
|
||||
}
|
||||
}
|
||||
// done
|
||||
return null;
|
||||
@@ -264,10 +283,11 @@ public class FileFolderPerformanceTester extends TestCase
|
||||
|
||||
if (percentComplete > 0)
|
||||
{
|
||||
logger.debug("\n" +
|
||||
System.out.println("\n" +
|
||||
"[" + Thread.currentThread().getName() + "] \n" +
|
||||
" Created " + (currentBatchCount*filesPerBatch) + " files in each of " + folderCount +
|
||||
" folders (" + (randomOrder ? "shuffled" : "in order") + "): \n" +
|
||||
" folders (" + (randomOrder ? "shuffled" : "in order") + ")" +
|
||||
" with " + (realFile ? "real files" : "spoofed content") + " :\n" +
|
||||
" Progress: " + String.format("%9.2f", percentComplete) + " percent complete \n" +
|
||||
" Average: " + String.format("%10.2f", average) + " ms per file \n" +
|
||||
" Average: " + String.format("%10.2f", 1000.0/average) + " files per second");
|
||||
@@ -276,7 +296,7 @@ public class FileFolderPerformanceTester extends TestCase
|
||||
};
|
||||
|
||||
// kick off the required number of threads
|
||||
logger.debug("\n" +
|
||||
System.out.println("\n" +
|
||||
"Starting " + threadCount +
|
||||
" threads loading " + (batchCount * filesPerBatch) +
|
||||
" files in each of " + folderCount +
|
||||
@@ -463,8 +483,8 @@ public class FileFolderPerformanceTester extends TestCase
|
||||
readStructure(rootFolderRef, 1, 1, new double[] {0.25, 0.50, 0.75});
|
||||
}
|
||||
*/
|
||||
// Load: 800 ordered files per folder (into 3 folders) using 4 threads
|
||||
public void test_4_ordered_3_2_100() throws Exception
|
||||
/** Load: 800 ordered files per folder (into 3 folders) using 4 threads using spoofed text */
|
||||
public void test_4_ordered_3_2_100_spoofed() throws Exception
|
||||
{
|
||||
buildStructure(
|
||||
rootFolderRef,
|
||||
@@ -473,6 +493,7 @@ public class FileFolderPerformanceTester extends TestCase
|
||||
3,
|
||||
2,
|
||||
100,
|
||||
false,
|
||||
new double[] {0.05, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90});
|
||||
|
||||
System.out.println("rootFolderRef: "+rootFolderRef);
|
||||
@@ -480,8 +501,8 @@ public class FileFolderPerformanceTester extends TestCase
|
||||
readStructure(rootFolderRef, 4, 5, new double[] {0.25, 0.50, 0.75});
|
||||
}
|
||||
|
||||
// Load: 800 shuffled files per folder (into 3 folders) using 4 threads
|
||||
public void test_4_shuffled_3_2_100() throws Exception
|
||||
/** Load: 800 shuffled files per folder (into 3 folders) using 4 threads using spoofed text */
|
||||
public void test_4_shuffled_3_2_100_spoofed() throws Exception
|
||||
{
|
||||
buildStructure(
|
||||
rootFolderRef,
|
||||
@@ -490,6 +511,7 @@ public class FileFolderPerformanceTester extends TestCase
|
||||
3,
|
||||
2,
|
||||
100,
|
||||
false,
|
||||
new double[] {0.05, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90});
|
||||
|
||||
System.out.println("rootFolderRef: "+rootFolderRef);
|
||||
@@ -497,22 +519,23 @@ public class FileFolderPerformanceTester extends TestCase
|
||||
readStructure(rootFolderRef, 4, 5, new double[] {0.25, 0.50, 0.75});
|
||||
}
|
||||
|
||||
/*
|
||||
// Load: 50000 ordered files per folder (into 1 folder) using 1 thread
|
||||
public void test_1_ordered_1_5000_10() throws Exception
|
||||
/** Load: 800 shuffled files per folder (into 3 folders) using 4 threads using real text */
|
||||
public void test_4_shuffled_3_2_100_real() throws Exception
|
||||
{
|
||||
buildStructure(
|
||||
rootFolderRef,
|
||||
1,
|
||||
false,
|
||||
1,
|
||||
5000,
|
||||
10,
|
||||
new double[] {0.01, 0.02, 0.03, 0.04, 0.05, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90});
|
||||
4,
|
||||
true,
|
||||
3,
|
||||
2,
|
||||
100,
|
||||
true,
|
||||
new double[] {0.05, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90});
|
||||
|
||||
readStructure(rootFolderRef, 1, 1, new double[] {0.25, 0.50, 0.75});
|
||||
System.out.println("rootFolderRef: "+rootFolderRef);
|
||||
|
||||
readStructure(rootFolderRef, 4, 5, new double[] {0.25, 0.50, 0.75});
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a bunch of files and folders in a folder and then run multi-threaded directory
|
||||
|
@@ -1,2 +1,3 @@
|
||||
## Test to see that Log4J additions are picked up
|
||||
log4j.logger.org.alfresco.repo.admin.Log4JHierarchyInitTest=DEBUG
|
||||
log4j.logger.org.alfresco.repo.model.filefolder.FileFolderPerformanceTester=DEBUG
|
Reference in New Issue
Block a user