Fixed benchmark folder creation algorithm.

Added ability to upload multiple files at a time.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6858 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2007-09-24 09:44:38 +00:00
parent 76afd86b11
commit b4ec9a4992
5 changed files with 142 additions and 20 deletions

View File

@@ -51,6 +51,12 @@
<property name="nodeDaoService"> <property name="nodeDaoService">
<ref bean="nodeDaoService"/> <ref bean="nodeDaoService"/>
</property> </property>
<property name="fileFolderService">
<ref bean="FileFolderService"/>
</property>
<property name="mimetypeService">
<ref bean="MimetypeService"/>
</property>
</bean> </bean>
<bean id="loaderRemoteServerRMI" class="org.springframework.remoting.rmi.RmiServiceExporter"> <bean id="loaderRemoteServerRMI" class="org.springframework.remoting.rmi.RmiServiceExporter">

View File

@@ -265,7 +265,7 @@ public class FileFolderRemoteLoader
String valuesStr = properties.getProperty(propertyName); String valuesStr = properties.getProperty(propertyName);
FileFolderRemoteLoader.checkProperty(propertyName, valuesStr); FileFolderRemoteLoader.checkProperty(propertyName, valuesStr);
// Parse it into the well-known values // Parse it into the well-known values
String[] strValues = new String[] {"1", "0", "0", "1", "false"}; String[] strValues = new String[] {"1", "0", "0", "1", "false", "1"};
int index = 0; int index = 0;
StringTokenizer tokenizer = new StringTokenizer(valuesStr, ","); StringTokenizer tokenizer = new StringTokenizer(valuesStr, ",");
while (tokenizer.hasMoreTokens()) while (tokenizer.hasMoreTokens())
@@ -286,6 +286,7 @@ public class FileFolderRemoteLoader
long testTotal = 0L; long testTotal = 0L;
long testDepth = 1L; long testDepth = 1L;
boolean testVerbose = false; boolean testVerbose = false;
long filesPerUpload = 1;
try try
{ {
testCount = Long.parseLong(strValues[0]); testCount = Long.parseLong(strValues[0]);
@@ -293,12 +294,13 @@ public class FileFolderRemoteLoader
testTotal = Long.parseLong(strValues[2]); testTotal = Long.parseLong(strValues[2]);
testDepth = Long.parseLong(strValues[3]); testDepth = Long.parseLong(strValues[3]);
testVerbose = Boolean.parseBoolean(strValues[4]); testVerbose = Boolean.parseBoolean(strValues[4]);
filesPerUpload = Long.parseLong(strValues[5]);
} }
catch (Throwable e) catch (Throwable e)
{ {
throw new LoaderClientException( throw new LoaderClientException(
"Unable to parse the loader configuration for '" + name + "'. " + LoaderSession.getLineEnding() + "Unable to parse the loader configuration for '" + name + "'. " + LoaderSession.getLineEnding() +
"The correct format is [threadCount], [period(ms)], [total], [folder depth], [verbose]"); "The correct format is [threadCount], [period(ms)], [total], [folder depth], [verbose]<, [filesPerUpload]>");
} }
// Construct // Construct
@@ -307,7 +309,7 @@ public class FileFolderRemoteLoader
AbstractLoaderThread thread = null; AbstractLoaderThread thread = null;
if (type.equals("upload")) if (type.equals("upload"))
{ {
thread = new LoaderUploadThread(session, name, testPeriod, testTotal, testDepth, testVerbose); thread = new LoaderUploadThread(session, name, testPeriod, testTotal, testDepth, testVerbose, filesPerUpload);
} }
else if (type.equals("totals")) else if (type.equals("totals"))
{ {

View File

@@ -27,6 +27,7 @@ package org.alfresco.repo.model.filefolder.loader;
import java.io.File; import java.io.File;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import net.sf.ehcache.Cache; import net.sf.ehcache.Cache;
@@ -60,15 +61,19 @@ public class LoaderUploadThread extends AbstractLoaderThread
pathCache.setCache(cache); pathCache.setCache(cache);
} }
private int filesPerUpload;
public LoaderUploadThread( public LoaderUploadThread(
LoaderSession session, LoaderSession session,
String loaderName, String loaderName,
long testPeriod, long testPeriod,
long testTotal, long testTotal,
long testLoadDepth, long testLoadDepth,
boolean verbose) boolean verbose,
long filesPerUpload)
{ {
super(session, loaderName, testPeriod, testTotal, testLoadDepth, verbose); super(session, loaderName, testPeriod, testTotal, testLoadDepth, verbose);
this.filesPerUpload = (int) filesPerUpload;
} }
/** /**
@@ -101,7 +106,7 @@ public class LoaderUploadThread extends AbstractLoaderThread
FileInfo folderInfo = serverProxy.fileFolderRemote.makeFolders( FileInfo folderInfo = serverProxy.fileFolderRemote.makeFolders(
serverProxy.ticket, serverProxy.ticket,
currentParentNodeRef, currentParentNodeRef,
currentPath, Collections.singletonList(pathElement),
ContentModel.TYPE_FOLDER); ContentModel.TYPE_FOLDER);
currentParentNodeRef = folderInfo.getNodeRef(); currentParentNodeRef = folderInfo.getNodeRef();
// Cache the new node // Cache the new node
@@ -119,29 +124,41 @@ public class LoaderUploadThread extends AbstractLoaderThread
// Make sure the folder exists // Make sure the folder exists
NodeRef folderNodeRef = makeFolders(serverProxy.ticket, serverProxy, workingRootNodeRef, folderPath); NodeRef folderNodeRef = makeFolders(serverProxy.ticket, serverProxy, workingRootNodeRef, folderPath);
// Build a set of files to upload
byte[][] bytes = new byte[filesPerUpload][];
String[] filenames = new String[filesPerUpload];
for (int i = 0; i < filesPerUpload; i++)
{
// Get a random file // Get a random file
File file = getFile(); File file = getFile();
byte[] bytes = FileCopyUtils.copyToByteArray(file); bytes[i] = FileCopyUtils.copyToByteArray(file);
// Get the extension // Get the extension
String filename = GUID.generate(); filenames[i] = GUID.generate();
int index = file.getName().lastIndexOf('.'); int index = file.getName().lastIndexOf('.');
if (index > 0) if (index > 0)
{ {
String ext = file.getName().substring(index + 1, file.getName().length()); String ext = file.getName().substring(index + 1, file.getName().length());
filename += ("." + ext); filenames[i] += ("." + ext);
}
} }
// Upload it // Upload it
FileInfo fileInfo = serverProxy.fileFolderRemote.create( FileInfo[] fileInfos = serverProxy.loaderRemote.uploadContent(
serverProxy.ticket, serverProxy.ticket,
folderNodeRef, folderNodeRef,
filename, filenames,
ContentModel.TYPE_CONTENT); bytes);
NodeRef fileNodeRef = fileInfo.getNodeRef();
serverProxy.fileFolderRemote.putContent(serverProxy.ticket, fileNodeRef, bytes, filename);
// Done // Done
String msg = String.format("Uploaded %s to folder: %s", filename, folderPath.toString()); String msg = String.format("Uploaded %d files to folder: %s", fileInfos.length, folderPath.toString());
return msg; return msg;
} }
@Override
public String getSummary()
{
String summary = super.getSummary();
summary += (String.format("%d files per iteration", filesPerUpload));
return summary;
}
} }

View File

@@ -24,17 +24,24 @@
*/ */
package org.alfresco.repo.remote; package org.alfresco.repo.remote;
import java.io.ByteArrayInputStream;
import java.nio.charset.Charset;
import java.util.List; import java.util.List;
import net.sf.acegisecurity.Authentication; import net.sf.acegisecurity.Authentication;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.encoding.ContentCharsetFinder;
import org.alfresco.repo.node.db.NodeDaoService; import org.alfresco.repo.node.db.NodeDaoService;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.remote.LoaderRemote; import org.alfresco.service.cmr.remote.LoaderRemote;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.MimetypeService;
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.StoreRef;
@@ -67,6 +74,8 @@ public class LoaderRemoteServer implements LoaderRemote
private AuthenticationService authenticationService; private AuthenticationService authenticationService;
private NodeService nodeService; private NodeService nodeService;
private NodeDaoService nodeDaoService; private NodeDaoService nodeDaoService;
private FileFolderService fileFolderService;
private MimetypeService mimetypeService;
/** /**
* @param transactionService provides transactional support and retrying * @param transactionService provides transactional support and retrying
@@ -100,6 +109,22 @@ public class LoaderRemoteServer implements LoaderRemote
this.nodeDaoService = nodeDaoService; this.nodeDaoService = nodeDaoService;
} }
/**
* @param fileFolderService the file-specific service
*/
public void setFileFolderService(FileFolderService fileFolderService)
{
this.fileFolderService = fileFolderService;
}
/**
* @param mimetypeService used to determine encoding, etc
*/
public void setMimetypeService(MimetypeService mimetypeService)
{
this.mimetypeService = mimetypeService;
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@@ -236,4 +261,64 @@ public class LoaderRemoteServer implements LoaderRemote
AuthenticationUtil.setCurrentAuthentication(authentication); AuthenticationUtil.setCurrentAuthentication(authentication);
} }
} }
public FileInfo[] uploadContent(
String ticket,
final NodeRef folderNodeRef,
final String[] filenames,
final byte[][] bytes)
{
if (filenames.length < bytes.length)
{
throw new IllegalArgumentException("The number of files must match the number of binary byte arrays given.");
}
Authentication authentication = AuthenticationUtil.getCurrentAuthentication();
try
{
authenticationService.validate(ticket);
// Make the call
RetryingTransactionCallback<FileInfo[]> callback = new RetryingTransactionCallback<FileInfo[]>()
{
public FileInfo[] execute() throws Throwable
{
FileInfo[] results = new FileInfo[filenames.length];
// Create each file
for (int i = 0; i < filenames.length; i++)
{
// Create the file
FileInfo newFileInfo = fileFolderService.create(
folderNodeRef,
filenames[i],
ContentModel.TYPE_CONTENT);
results[i] = newFileInfo;
NodeRef newFileNodeRef = newFileInfo.getNodeRef();
// Guess the mimetype
String mimetype = mimetypeService.guessMimetype(filenames[i]);
// Get a writer
ContentWriter writer = fileFolderService.getWriter(newFileNodeRef);
// Make a stream
ByteArrayInputStream is = new ByteArrayInputStream(bytes[i]);
// Guess the encoding
ContentCharsetFinder charsetFinder = mimetypeService.getContentCharsetFinder();
Charset charset = charsetFinder.getCharset(is, mimetype);
// Set metadata
writer.setEncoding(charset.name());
writer.setMimetype(mimetype);
// Write the stream
writer.putContent(is);
}
// Done
return results;
}
};
return retryingTransactionHelper.doInTransaction(callback, false, true);
}
finally
{
AuthenticationUtil.setCurrentAuthentication(authentication);
}
}
} }

View File

@@ -24,6 +24,7 @@
*/ */
package org.alfresco.service.cmr.remote; package org.alfresco.service.cmr.remote;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.StoreRef;
@@ -72,4 +73,15 @@ public interface LoaderRemote
* @return Returns the total number of nodes for the given ADM store * @return Returns the total number of nodes for the given ADM store
*/ */
public int getNodeCount(String ticket, StoreRef storeRef); public int getNodeCount(String ticket, StoreRef storeRef);
/**
* Upload multiple files to a folder.
*
* @param ticket the authentication ticket
* @param folderNodeRef the folder to upload to
* @param filenames the names of the files to upload
* @param bytes the contents of the files
* @return Returns the details of each file created
*/
public FileInfo[] uploadContent(String ticket, NodeRef folderNodeRef, String[] filenames, byte[][] bytes);
} }