Another merge. I was bored.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@2923 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Britt Park
2006-05-19 00:38:14 +00:00
parent 1b4c08d1d4
commit 9d6b8bdf26
3 changed files with 193 additions and 57 deletions

View File

@@ -347,6 +347,7 @@
<property name="fixesFromSchema"><value>0</value></property> <property name="fixesFromSchema"><value>0</value></property>
<property name="fixesToSchema"><value>12</value></property> <property name="fixesToSchema"><value>12</value></property>
<property name="targetSchema"><value>13</value></property> <property name="targetSchema"><value>13</value></property>
<property name="scriptsACP"><value>alfresco/bootstrap/example_javascripts.acp</value></property>
<!-- helper beans for execution --> <!-- helper beans for execution -->
<property name="importerBootstrap"> <property name="importerBootstrap">
<ref bean="spacesBootstrap" /> <ref bean="spacesBootstrap" />
@@ -354,6 +355,9 @@
<property name="messageSource"> <property name="messageSource">
<ref bean="bootstrapSpacesMessageSource" /> <ref bean="bootstrapSpacesMessageSource" />
</property> </property>
<property name="importerService">
<ref bean="importerComponent" />
</property>
</bean> </bean>
</beans> </beans>

View File

@@ -16,6 +16,7 @@
*/ */
package org.alfresco.repo.admin.patch.impl; package org.alfresco.repo.admin.patch.impl;
import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -25,13 +26,17 @@ import java.util.Properties;
import org.alfresco.i18n.I18NUtil; import org.alfresco.i18n.I18NUtil;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.admin.patch.AbstractPatch; import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.importer.ACPImportPackageHandler;
import org.alfresco.repo.importer.ImporterBootstrap; import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.service.cmr.admin.PatchException; import org.alfresco.service.cmr.admin.PatchException;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
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;
import org.alfresco.service.cmr.view.ImporterService;
import org.alfresco.service.cmr.view.Location;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.springframework.context.MessageSource; import org.springframework.context.MessageSource;
import org.springframework.core.io.ClassPathResource;
/** /**
* Ensures that the <b>scripts</b> folder is present. * Ensures that the <b>scripts</b> folder is present.
@@ -59,32 +64,44 @@ public class ScriptsFolderPatch extends AbstractPatch
private static final String PROPERTY_ICON = "space-icon-default"; private static final String PROPERTY_ICON = "space-icon-default";
private ImporterBootstrap importerBootstrap; private ImporterBootstrap importerBootstrap;
private ImporterService importerService;
private MessageSource messageSource; private MessageSource messageSource;
protected NodeRef dictionaryNodeRef; protected NodeRef dictionaryNodeRef;
protected Properties configuration; protected Properties configuration;
protected NodeRef scriptsFolderNodeRef; protected NodeRef scriptsFolderNodeRef;
private String scriptsACP;
public void setImporterBootstrap(ImporterBootstrap importerBootstrap) public void setImporterBootstrap(ImporterBootstrap importerBootstrap)
{ {
this.importerBootstrap = importerBootstrap; this.importerBootstrap = importerBootstrap;
} }
public void setImporterService(ImporterService importerService)
{
this.importerService = importerService;
}
public void setMessageSource(MessageSource messageSource) public void setMessageSource(MessageSource messageSource)
{ {
this.messageSource = messageSource; this.messageSource = messageSource;
} }
public void setScriptsACP(String scriptsACP)
{
this.scriptsACP = scriptsACP;
}
/** /**
* Ensure that required common properties have been set * Ensure that required common properties have been set
*/ */
protected void checkCommonProperties() throws Exception protected void checkCommonProperties() throws Exception
{ {
if (importerBootstrap == null) checkPropertyNotNull(importerBootstrap, "importerBootstrap");
{ checkPropertyNotNull(importerService, "importerService");
throw new PatchException("'importerBootstrap' property has not been set"); checkPropertyNotNull(messageSource, "messageSource");
} if (namespaceService == null)
else if (namespaceService == null)
{ {
throw new PatchException("'namespaceService' property has not been set"); throw new PatchException("'namespaceService' property has not been set");
} }
@@ -96,6 +113,7 @@ public class ScriptsFolderPatch extends AbstractPatch
{ {
throw new PatchException("'nodeService' property has not been set"); throw new PatchException("'nodeService' property has not been set");
} }
checkPropertyNotNull(scriptsACP, "scriptsACP");
} }
/** /**
@@ -193,6 +211,19 @@ public class ScriptsFolderPatch extends AbstractPatch
{ {
// create it // create it
createFolder(); createFolder();
// import the content
try
{
authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
importContent();
}
finally
{
authenticationComponent.clearCurrentSecurityContext();
}
msg = I18NUtil.getMessage(MSG_CREATED, scriptsFolderNodeRef); msg = I18NUtil.getMessage(MSG_CREATED, scriptsFolderNodeRef);
} }
else else
@@ -251,4 +282,13 @@ public class ScriptsFolderPatch extends AbstractPatch
// done // done
} }
private void importContent() throws IOException
{
// import the content
ClassPathResource acpResource = new ClassPathResource(this.scriptsACP);
ACPImportPackageHandler acpHandler = new ACPImportPackageHandler(acpResource.getFile(), null);
Location importLocation = new Location(this.scriptsFolderNodeRef);
importerService.importView(acpHandler, importLocation, null, null);
}
} }

View File

@@ -17,13 +17,15 @@
package org.alfresco.repo.model.filefolder; package org.alfresco.repo.model.filefolder;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.transform.AbstractContentTransformerTest; import org.alfresco.repo.content.transform.AbstractContentTransformerTest;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.transaction.TransactionUtil; import org.alfresco.repo.transaction.TransactionUtil;
import org.alfresco.repo.transaction.TransactionUtil.TransactionWork; import org.alfresco.repo.transaction.TransactionUtil.TransactionWork;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
@@ -38,6 +40,8 @@ import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService; import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.ApplicationContextHelper; import org.alfresco.util.ApplicationContextHelper;
import org.alfresco.util.GUID; import org.alfresco.util.GUID;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
/** /**
@@ -53,9 +57,12 @@ import org.springframework.context.ApplicationContext;
*/ */
public class FileFolderPerformanceTester extends TestCase public class FileFolderPerformanceTester extends TestCase
{ {
private static Log logger = LogFactory.getLog(FileFolderPerformanceTester.class);
private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext(); private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
private TransactionService transactionService; private TransactionService transactionService;
private AuthenticationComponent authenticationComponent;
private NodeService nodeService; private NodeService nodeService;
private FileFolderService fileFolderService; private FileFolderService fileFolderService;
private StoreRef storeRef; private StoreRef storeRef;
@@ -67,9 +74,13 @@ public class FileFolderPerformanceTester extends TestCase
{ {
ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY); ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);
transactionService = serviceRegistry.getTransactionService(); transactionService = serviceRegistry.getTransactionService();
authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
nodeService = serviceRegistry.getNodeService(); nodeService = serviceRegistry.getNodeService();
fileFolderService = serviceRegistry.getFileFolderService(); fileFolderService = serviceRegistry.getFileFolderService();
// authenticate
authenticationComponent.setSystemUserAsCurrentUser();
// create a folder root to work in // create a folder root to work in
storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, getName() + "_" + System.currentTimeMillis()); storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, getName() + "_" + System.currentTimeMillis());
NodeRef rootNodeRef = nodeService.getRootNode(storeRef); NodeRef rootNodeRef = nodeService.getRootNode(storeRef);
@@ -92,38 +103,82 @@ public class FileFolderPerformanceTester extends TestCase
* are added one to each folder until each folder has the presribed number of files within it. * are added one to each folder until each folder has the presribed number of files within it.
* This can therefore be used to test the performance when the L2 cache sizes are exceeded. * This can therefore be used to test the performance when the L2 cache sizes are exceeded.
* <p> * <p>
* Each creation (file or folder) uses the <b>REQUIRES_NEW</b> transaction declaration. * Each creation (file or folder) uses the <b>PROPAGATION REQUIRED</b> transaction declaration.
* *
* @param parentNodeRef the level zero parent * @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> * @return Returns the average time (ms) to create the <b>files only</b>
*/ */
private double buildStructure(final NodeRef parentNodeRef, final int folderCount, final int fileCount) private void buildStructure(
final NodeRef parentNodeRef,
final int threadCount,
final boolean randomOrder,
final int folderCount,
final int fileCount,
final double[] dumpPoints)
{ {
List<NodeRef> folders = new ArrayList<NodeRef>(folderCount); TransactionWork<NodeRef[]> createFoldersWork = new TransactionWork<NodeRef[]>()
{
public NodeRef[] doWork() throws Exception
{
NodeRef[] folders = new NodeRef[folderCount];
for (int i = 0; i < folderCount; i++) for (int i = 0; i < folderCount; i++)
{
TransactionWork<FileInfo> createFolderWork = new TransactionWork<FileInfo>()
{
public FileInfo doWork() throws Exception
{ {
FileInfo folderInfo = fileFolderService.create( FileInfo folderInfo = fileFolderService.create(
parentNodeRef, parentNodeRef,
GUID.generate(), GUID.generate(),
ContentModel.TYPE_FOLDER); ContentModel.TYPE_FOLDER);
// done // keep the reference
return folderInfo; folders[i] = folderInfo.getNodeRef();
}
return folders;
} }
}; };
FileInfo folderInfo = TransactionUtil.executeInUserTransaction(transactionService, createFolderWork); final NodeRef[] folders = TransactionUtil.executeInUserTransaction(
// keep the reference transactionService,
folders.add(folderInfo.getNodeRef()); createFoldersWork);
} // the worker that will load the files into the folders
// now progress around the folders until they have been populated Runnable runnable = new Runnable()
long start = System.currentTimeMillis(); {
private long start;
public void run()
{
// authenticate
authenticationComponent.setSystemUserAsCurrentUser();
// progress around the folders until they have been populated
start = System.currentTimeMillis();
int nextDumpNumber = 0;
for (int i = 0; i < fileCount; i++) for (int i = 0; i < fileCount; i++)
{ {
for (final NodeRef folderRef : folders) // must we dump results
double completedCount = (double) i;
double nextDumpCount = (dumpPoints == null || dumpPoints.length == 0 || nextDumpNumber >= dumpPoints.length)
? -1.0
: (double) fileCount * dumpPoints[nextDumpNumber];
if ((nextDumpCount - 0.5) < completedCount && completedCount < (nextDumpCount + 0.5))
{ {
dumpResults(i);
nextDumpNumber++;
}
// shuffle folders if required
List<NodeRef> foldersList = Arrays.asList(folders);
if (randomOrder)
{
// shuffle folder list
Collections.shuffle(foldersList);
}
for (int j = 0; j < folders.length; j++)
{
if (logger.isDebugEnabled())
{
String msg = String.format(
"Thread %s loading file %4d into folder %4d",
Thread.currentThread().getName(),
i, j);
logger.debug(msg);
}
final NodeRef folderRef = folders[j];
TransactionWork<FileInfo> createFileWork = new TransactionWork<FileInfo>() TransactionWork<FileInfo> createFileWork = new TransactionWork<FileInfo>()
{ {
public FileInfo doWork() throws Exception public FileInfo doWork() throws Exception
@@ -143,34 +198,71 @@ public class FileFolderPerformanceTester extends TestCase
TransactionUtil.executeInUserTransaction(transactionService, createFileWork); TransactionUtil.executeInUserTransaction(transactionService, createFileWork);
} }
} }
dumpResults(fileCount);
}
private void dumpResults(int currentFileCount)
{
long end = System.currentTimeMillis(); long end = System.currentTimeMillis();
long time = (end - start); long time = (end - start);
double average = (double) time / (double) (folderCount * fileCount); double average = (double) time / (double) (folderCount * currentFileCount);
// done double percentComplete = (double) currentFileCount / (double) fileCount * 100.0;
return average;
}
private void timeBuildStructure(NodeRef parentNodeRef, int folderCount, int fileCount)
{
System.out.println("Starting load of " + fileCount + " files in each of " + folderCount + " folders");
double average = buildStructure(parentNodeRef, folderCount, fileCount);
System.out.println( System.out.println(
"[" + getName() + "] \n" + "[" + Thread.currentThread().getName() + "] \n" +
" Created " + fileCount + " files in each of " + folderCount + " folders: \n" + " Created " + currentFileCount + " files in each of " + folderCount + " folders: \n" +
" Average: " + String.format("%10.2f", average) + "ms per file \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"); " Average: " + String.format("%10.2f", 1000.0/average) + " files per second");
} }
};
// kick off the required number of threads
System.out.println(
"Starting " + threadCount +
" threads loading " + fileCount +
" files in each of " + folderCount +
" folders (" +
(randomOrder ? "shuffled" : "in order") + ").");
ThreadGroup threadGroup = new ThreadGroup(getName());
Thread[] threads = new Thread[threadCount];
for (int i = 0; i < threadCount; i++)
{
threads[i] = new Thread(threadGroup, runnable, String.format("FileLoader-%02d", i));
threads[i].start();
}
// join each thread so that we wait for them all to finish
for (int i = 0; i < threads.length; i++)
{
try
{
threads[i].join();
}
catch (InterruptedException e)
{
// not too serious - the worker threads are non-daemon
}
}
}
public void test1Folder10Children() throws Exception public void test1Folder10Children() throws Exception
{ {
timeBuildStructure(rootFolderRef, 1, 10); buildStructure(rootFolderRef, 2, false, 1, 10, null);
} }
public void test10Folders100ChildrenMultiTxn() throws Exception public void test10Folders100ChildrenMultiTxn() throws Exception
{ {
timeBuildStructure(rootFolderRef, 10, 100); buildStructure(rootFolderRef, 2, false, 10, 100, new double[] {0.50});
} }
// //
// public void test10Folders100ChildrenMultiTxnMultiThread() throws Exception
// {
// buildStructure(4, rootFolderRef, 10, 100);
// }
//
// public void test1000Folders1000ChildrenMultiTxnMultiThread() throws Exception
// {
// buildStructure(rootFolderRef, 4, true, 1000, 1000);
// }
//
// public void test100Folders1Child() throws Exception // public void test100Folders1Child() throws Exception
// { // {
// timeBuildStructure(rootFolderRef, 100, 1); // timeBuildStructure(rootFolderRef, 100, 1);