Enhancements to FSR.

1) Performance imporvements (client and server are now multi-threaded + other performance work)
2) Pluggable transport protocols (ENH-145)
3) Changes to initialisation (ALFCOM-135)
4) Changes to the action service to enable multiple async event queues.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@11022 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Mark Rogers
2008-09-25 15:10:58 +00:00
parent 2a4b7c9eef
commit e98ab1750a
31 changed files with 1890 additions and 500 deletions

View File

@@ -3,8 +3,62 @@
<beans>
<!-- Action Service -->
<!-- Action Service Configuration -->
<!-- Thread Pools -->
<!-- the default pool is used to run most of the async actions -->
<bean id="defaultAsyncThreadPool" class="org.alfresco.util.ThreadPoolExecutorFactoryBean">
<property name="poolName">
<value>defaultAsyncAction</value>
</property>
<property name="corePoolSize">
<value>2</value>
</property>
<property name="maximumPoolSize">
<value>10</value>
</property>
</bean>
<!-- the deployment pool is used to throttle long running deployments which may otherwise block normal
operations -->
<bean id="deploymentAsyncThreadPool" class="org.alfresco.util.ThreadPoolExecutorFactoryBean">
<property name="poolName">
<value>deploymentAsyncAction</value>
</property>
<property name="corePoolSize">
<value>2</value>
</property>
<property name="maximumPoolSize">
<value>3</value>
</property>
</bean>
<bean id="defaultAsynchronousActionExecutionQueue" class="org.alfresco.repo.action.AsynchronousActionExecutionQueueImpl">
<property name="threadPoolExecutor">
<ref bean="defaultAsyncThreadPool"/>
</property>
<property name="transactionService">
<ref bean="transactionService"/>
</property>
<property name="authenticationComponent">
<ref bean="AuthenticationComponent"/>
</property>
</bean>
<bean id="deploymentAsynchronousActionExecutionQueue" class="org.alfresco.repo.action.AsynchronousActionExecutionQueueImpl">
<property name="threadPoolExecutor">
<ref bean="deploymentAsyncThreadPool"/>
</property>
<property name="transactionService">
<ref bean="transactionService"/>
</property>
<property name="authenticationComponent">
<ref bean="AuthenticationComponent"/>
</property>
</bean>
<!-- Action Service -->
<bean id="actionService" class="org.alfresco.repo.action.ActionServiceImpl">
<property name="nodeService">
<ref bean="NodeService" />
@@ -18,8 +72,17 @@
<property name="dictionaryService">
<ref bean="DictionaryService" />
</property>
<property name="asynchronousActionExecutionQueue">
<ref bean="asynchronousActionExecutionQueue"/>
<property name="asynchronousActionExecutionQueues">
<map>
<!-- This is the default async queue -->
<entry key="">
<ref bean="defaultAsynchronousActionExecutionQueue"/>
</entry>
<entry key="deployment">
<ref bean="deploymentAsynchronousActionExecutionQueue"/>
</entry>
</map>
</property>
</bean>
@@ -506,6 +569,11 @@
</bean>
<bean id="avm-deploy-website" class="org.alfresco.repo.avm.actions.AVMDeployWebsiteAction" parent="action-executer">
<!-- Run avm-deploy-website action on the deployment queue -->
<property name="queueName">
<value>deployment</value>
</property>
<property name="deploymentService">
<ref bean="DeploymentService"/>
</property>

View File

@@ -36,6 +36,7 @@
<import resource="classpath:alfresco/avm-services-context.xml" />
<import resource="classpath:alfresco/audit-services-context.xml" />
<import resource="classpath:alfresco/attributes-service-context.xml"/>
<import resource="classpath:alfresco/deployment-service-context.xml"/>
<import resource="classpath:alfresco/linkvalidation-service-context.xml"/>
<import resource="classpath:alfresco/remote-services-context.xml"/>
<import resource="classpath*:alfresco/office-addin-context.xml"/>

View File

@@ -481,6 +481,9 @@
</bean>
<bean id="indexThreadPoolExecutor" class="org.alfresco.util.ThreadPoolExecutorFactoryBean">
<property name="poolName">
<value>indexThread</value>
</property>
<property name="corePoolSize">
<value>10</value>
</property>
@@ -1085,18 +1088,7 @@
</property>
</bean>
<!-- -->
<!-- Thread Pool -->
<!-- -->
<bean id="threadPoolExecutor" class="org.alfresco.util.ThreadPoolExecutorFactoryBean">
<property name="corePoolSize">
<value>2</value>
</property>
<property name="maximumPoolSize">
<value>10</value>
</property>
</bean>
<!-- Query Register Component -->

View File

@@ -0,0 +1,135 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<!-- Deployment Service Configuration -->
<!-- Payload transformers -->
<bean id="deploymentTestTransformer" class="org.alfresco.deployment.test.TestDeploymentTransportTransformer">
</bean>
<bean id="deploymentEncryptor" class="org.alfresco.deployment.transformers.SampleEncryptionTransformer">
<property name="password">
<value>Alfresco</value>
</property>
<property name="cipherName">
<value>PBEWithMD5AndDES</value>
</property>
</bean>
<bean id="deploymentCompressor" class="org.alfresco.deployment.transformers.CompressionTransformer">
</bean>
<!-- Transport adapters to communicate with remote File System Receivers -->
<!-- Communicate with an FSR over RMI - Default method for Alfresco-->
<bean id="rmiFSRAdapter" class="org.alfresco.repo.deploy.DeploymentReceiverTransportAdapterRMI">
</bean>
<!-- communicate with an FSR over RMI with the content encrypted -->
<bean id="encryptedRMIFSRAdapter" class="org.alfresco.repo.deploy.DeploymentReceiverTransportAdapterRMI">
<property name="transformers">
<list>
<ref bean="deploymentEncryptor"></ref>
</list>
</property>
</bean>
<!-- communicate with an FSR over RMI with the content compressed then encrypted -->
<bean id="compressEncryptedRMIFSRAdapter" class="org.alfresco.repo.deploy.DeploymentReceiverTransportAdapterRMI">
<property name="transformers">
<list>
<ref bean="deploymentEncryptor"></ref>
<ref bean="deploymentCompressor"></ref>
</list>
</property>
</bean>
<!-- how to communicate with an FSR over Spring HTTP -->
<bean id="springHttpFSRAdapter" class="org.alfresco.repo.deploy.DeploymentReceiverTransportAdapterSpringHTTP">
<property name="urlPattern">
<value>http://{1}:{2}/alfrescoFSR/deployment</value>
</property>
</bean>
<!-- Deployment Service -->
<bean id="deploymentService" class="org.alfresco.repo.deploy.DeploymentServiceImpl">
<property name="avmService">
<ref bean="indexingAVMService"/>
</property>
<!-- how many files to send in parallel -->
<property name="numberOfSendingThreads">
<value>5</value>
</property>
<!-- Which adapters are provided to communicate with remote File System Receivers -->
<property name="deploymentReceiverTransportAdapters">
<map>
<entry key="default">
<ref bean="rmiFSRAdapter"></ref>
</entry>
<!-- Uncomment to enable spring HTTP
<entry key="spring HTTP">
<ref bean="springHttpFSRAdapter"></ref>
</entry>
-->
<!-- Uncomment to enable encrypted RMI
<entry key="encrypted RMI">
<ref bean="encryptedRMIFSRAdapter"></ref>
</entry>
-->
<!-- Uncomment to enable compressed and encrypted RMI
<entry key="rmi compressed and encrypted">
<ref bean="compressEncryptedRMIFSRAdapter"></ref>
</entry>
-->
</map>
</property>
</bean>
<bean id="deploymentServiceReadTxnAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice">
<ref bean="retryingReadTxnAdvice"/>
</property>
<property name="mappedNames">
<list>
<value>getRemoteActionService</value>
</list>
</property>
</bean>
<bean id="deploymentServiceWriteTxnAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice">
<ref bean="retryingWriteTxnAdvice"/>
</property>
<property name="mappedNames">
<list>
<value>deployDifferenceFS</value>
<value>deployDifference</value>
</list>
</property>
</bean>
<bean id="DeploymentService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<list>
<value>org.alfresco.service.cmr.avm.deploy.DeploymentService</value>
</list>
</property>
<property name="targetName">
<value>deploymentService</value>
</property>
<property name="interceptorNames">
<list>
<value>deploymentServiceWriteTxnAdvisor</value>
<value>deploymentServiceReadTxnAdvisor</value>
<value>checkTxnAdvisor</value>
</list>
</property>
</bean>
</beans>

View File

@@ -7,6 +7,9 @@
The thread pool to use for index rebuilding and recovery
-->
<bean id="indexTrackerThreadPoolExecutor" class="org.alfresco.util.ThreadPoolExecutorFactoryBean">
<property name="poolName">
<value>indexTrackerThread</value>
</property>
<property name="corePoolSize">
<value>${index.recovery.maximumPoolSize}</value>
</property>

View File

@@ -306,6 +306,10 @@
<title>Display Name</title>
<type>d:text</type>
</property>
<property name="wca: deployserveradaptername">
<title>Deployment Server Adapter Name</title>
<type>d:text</type>
</property>
<property name="wca:deployserverusername">
<title>Username</title>
<type>d:text</type>

View File

@@ -1117,57 +1117,6 @@
</property>
</bean>
<!-- Deployment Service. -->
<bean id="deploymentService" class="org.alfresco.repo.deploy.DeploymentServiceImpl">
<property name="avmService">
<ref bean="indexingAVMService"/>
</property>
</bean>
<bean id="deploymentServiceReadTxnAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice">
<ref bean="retryingReadTxnAdvice"/>
</property>
<property name="mappedNames">
<list>
<value>getRemoteActionService</value>
</list>
</property>
</bean>
<bean id="deploymentServiceWriteTxnAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice">
<ref bean="retryingWriteTxnAdvice"/>
</property>
<property name="mappedNames">
<list>
<value>deployDifferenceFS</value>
<value>deployDifference</value>
</list>
</property>
</bean>
<bean id="DeploymentService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<list>
<value>org.alfresco.service.cmr.avm.deploy.DeploymentService</value>
</list>
</property>
<property name="targetName">
<value>deploymentService</value>
</property>
<property name="interceptorNames">
<list>
<value>deploymentServiceWriteTxnAdvisor</value>
<value>deploymentServiceReadTxnAdvisor</value>
<value>checkTxnAdvisor</value>
</list>
</property>
</bean>
<!-- AVM Locking Service. -->
<bean id="avmLockingServiceReadTxnAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">

View File

@@ -84,6 +84,7 @@ public interface WCMAppModel
static final QName PROP_DEPLOYSERVERUSERNAME = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployserverusername");
static final QName PROP_DEPLOYSERVERPASSWORD = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployserverpassword");
static final QName PROP_DEPLOYSERVERGROUP = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployservergroup");
static final QName PROP_DEPLOYSERVERADPTERNAME = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployserveradaptername");
static final QName PROP_DEPLOYSERVERURL = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployserverurl");
static final QName PROP_DEPLOYSERVERTARGET = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deployservertarget");
static final QName PROP_DEPLOYSOURCEPATH = QName.createQName(NamespaceService.WCMAPP_MODEL_1_0_URI, "deploysourcepath");

View File

@@ -114,9 +114,10 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
private AuthenticationComponent authenticationComponent;
/**
* The asynchronous action execution queue
* The asynchronous action execution queues
* map of name, queue
*/
private AsynchronousActionExecutionQueue asynchronousActionExecutionQueue;
private Map<String, AsynchronousActionExecutionQueue> asynchronousActionExecutionQueues;
/**
* Action transaction listener
@@ -184,24 +185,14 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
}
/**
* Set the asynchronous action execution queue
* Set the asynchronous action execution queues
*
* @param asynchronousActionExecutionQueue the asynchronous action execution queue
* @param asynchronousActionExecutionQueue the asynchronous action execution queues
*/
public void setAsynchronousActionExecutionQueue(
AsynchronousActionExecutionQueue asynchronousActionExecutionQueue)
public void setAsynchronousActionExecutionQueues(
Map<String, AsynchronousActionExecutionQueue> asynchronousActionExecutionQueues)
{
this.asynchronousActionExecutionQueue = asynchronousActionExecutionQueue;
}
/**
* Get the asychronous action execution queue
*
* @return the asynchronous action execution queue
*/
public AsynchronousActionExecutionQueue getAsynchronousActionExecutionQueue()
{
return asynchronousActionExecutionQueue;
this.asynchronousActionExecutionQueues = asynchronousActionExecutionQueues;
}
/**
@@ -405,6 +396,71 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
}
}
/**
* called by transaction service.
*/
public void postCommit()
{
for (PendingAction pendingAction : getPostTransactionPendingActions())
{
queueAction(pendingAction);
}
}
/**
*
*/
private void queueAction(PendingAction action)
{
// Get the right queue
AsynchronousActionExecutionQueue queue = getQueue(action.action);
// Queue the action for execution
queue.executeAction(
this,
action.getAction(),
action.getActionedUponNodeRef(),
action.getCheckConditions(),
action.getActionChain());
}
/**
*
* @param compensatingAction
* @param actionedUponNodeRef
*/
private void queueAction(Action compensatingAction, NodeRef actionedUponNodeRef)
{
// Get the right queue
AsynchronousActionExecutionQueue queue = getQueue(compensatingAction);
// Queue the action for execution
queue.executeAction(this, compensatingAction, actionedUponNodeRef, false, null);
}
private AsynchronousActionExecutionQueue getQueue(Action action)
{
ActionExecuter executer = (ActionExecuter)this.applicationContext.getBean(action.getActionDefinitionName());
AsynchronousActionExecutionQueue queue = null;
String queueName = executer.getQueueName();
if(queueName == null)
{
queue = asynchronousActionExecutionQueues.get("");
}
else
{
queue = asynchronousActionExecutionQueues.get(queueName);
}
if(queue == null)
{
// can't get queue
throw new ActionServiceException("Unable to get AsynchronousActionExecutionQueue name: "+ queueName);
}
return queue;
}
/**
* @see org.alfresco.repo.action.RuntimeActionService#executeActionImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef, boolean, org.alfresco.service.cmr.repository.NodeRef)
*/
@@ -501,9 +557,7 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
{
// Set the current user
((ActionImpl)compensatingAction).setRunAsUser(currentUserName);
// Queue the compensating action ready for execution
this.asynchronousActionExecutionQueue.executeAction(this, compensatingAction, actionedUponNodeRef, false, null);
queueAction(compensatingAction, actionedUponNodeRef);
}
}
@@ -1195,7 +1249,7 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
* @see org.alfresco.repo.action.RuntimeActionService#getPostTransactionPendingActions()
*/
@SuppressWarnings("unchecked")
public List<PendingAction> getPostTransactionPendingActions()
private List<PendingAction> getPostTransactionPendingActions()
{
return (List<PendingAction>)AlfrescoTransactionSupport.getResource(POST_TRANSACTION_PENDING_ACTIONS);
}
@@ -1203,7 +1257,7 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
/**
* Pending action details class
*/
public class PendingAction
private class PendingAction
{
/**
* The action

View File

@@ -24,7 +24,6 @@
*/
package org.alfresco.repo.action;
import org.alfresco.repo.action.ActionServiceImpl.PendingAction;
import org.alfresco.repo.transaction.TransactionListener;
import org.alfresco.util.GUID;
@@ -81,15 +80,7 @@ public class ActionTransactionListener implements TransactionListener
*/
public void afterCommit()
{
for (PendingAction pendingAction : this.actionService.getPostTransactionPendingActions())
{
this.actionService.getAsynchronousActionExecutionQueue().executeAction(
actionService,
pendingAction.getAction(),
pendingAction.getActionedUponNodeRef(),
pendingAction.getCheckConditions(),
pendingAction.getActionChain());
}
this.actionService.postCommit();
}
/**

View File

@@ -24,10 +24,8 @@
*/
package org.alfresco.repo.action;
import java.util.List;
import java.util.Set;
import org.alfresco.repo.action.ActionServiceImpl.PendingAction;
import org.alfresco.repo.action.evaluator.ActionConditionEvaluator;
import org.alfresco.repo.action.executer.ActionExecuter;
import org.alfresco.service.cmr.action.Action;
@@ -39,12 +37,17 @@ import org.alfresco.service.namespace.QName;
*/
public interface RuntimeActionService
{
/**
*
*/
void postCommit();
/**
* Get the asynchronous action queue.
*
* @return the asynchronous action queue
*/
AsynchronousActionExecutionQueue getAsynchronousActionExecutionQueue();
//AsynchronousActionExecutionQueue getAsynchronousActionExecutionQueue();
/**
* Register an action condition evaluator
@@ -93,10 +96,10 @@ public interface RuntimeActionService
*/
public void directActionExecution(Action action, NodeRef actionedUponNodeRef);
/**
* Gets a list of the actions that are pending post transaction
*
* @return list of pending actions
*/
public List<PendingAction> getPostTransactionPendingActions();
// /**
// * Gets a list of the actions that are pending post transaction
// *
// * @return list of pending actions
// */
// public List<PendingAction> getPostTransactionPendingActions();
}

View File

@@ -54,4 +54,10 @@ public interface ActionExecuter
public void execute(
Action action,
NodeRef actionedUponNodeRef);
/**
* Get the queueName that will execute this action
*/
String getQueueName();
}

View File

@@ -54,6 +54,13 @@ public abstract class ActionExecuterAbstractBase extends ParameterizedItemAbstra
/** List of types and aspects for which this action is applicable */
protected List<QName> applicableTypes = new ArrayList<QName>();
/**
*
*/
private String queueName = "";
/**
* Init method
*/
@@ -128,5 +135,17 @@ public abstract class ActionExecuterAbstractBase extends ParameterizedItemAbstra
*/
protected abstract void executeImpl(Action action, NodeRef actionedUponNodeRef);
/**
* Set the queueName which will execute this action
* if blank or null then the action will be executed on the "default" queue
* @param the name of the execution queue which should execute this action.
*/
public void setQueueName(String queueName)
{
this.queueName = queueName;
}
public String getQueueName() {
return queueName;
}
}

View File

@@ -45,6 +45,7 @@ import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.avm.deploy.DeploymentCallback;
import org.alfresco.service.cmr.avm.deploy.DeploymentEvent;
import org.alfresco.service.cmr.avm.deploy.DeploymentReport;
import org.alfresco.service.cmr.avm.deploy.DeploymentReportCallback;
import org.alfresco.service.cmr.avm.deploy.DeploymentService;
import org.alfresco.service.cmr.avmsync.AVMSyncException;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
@@ -73,12 +74,15 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase
public static final String PARAM_ATTEMPT = "attempt";
public static final String PARAM_CALLBACK = "callback";
public static final String ASYNC_QUEUE_NAME = "deployment";
private int delay = -1;
private int defaultAlfRmiPort = 50500;
private int defaultReceiverRmiPort = 44100;
private String defaultRemoteUsername = "admin";
private String defaultRemotePassword = "admin";
private String defaultTargetName = "default";
private String defaultAdapterName = "default";
private List<DeploymentCallback> configuredCallbacks;
private DeploymentService deployService;
private ContentService contentService;
@@ -275,6 +279,7 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase
String sourcePath = (String)serverProps.get(WCMAppModel.PROP_DEPLOYSOURCEPATH);
String excludes = (String)serverProps.get(WCMAppModel.PROP_DEPLOYEXCLUDES);
String targetName = (String)serverProps.get(WCMAppModel.PROP_DEPLOYSERVERTARGET);
String adapterName = (String)serverProps.get(WCMAppModel.PROP_DEPLOYSERVERADPTERNAME);
String targetPath = path;
if (fileServerDeployment == false)
@@ -289,6 +294,12 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase
targetPath = storePath[0] + "live:" + storePath[1];
}
}
else
{
if (adapterName == null) {
adapterName = defaultAdapterName;
}
}
// get defaults for data not provided in server node
if (port == null)
@@ -371,7 +382,10 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase
// make the deploy call passing in the DeploymentCallback, if present
Throwable deployError = null;
DeploymentReport report = null;
DeploymentReport report = new DeploymentReport();
callbacks.add(new DeploymentReportCallback(report));
try
{
// overwrite the password before logging
@@ -384,8 +398,19 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase
logger.debug("Performing file server deployment to " + host + ":" + port +
" using deploymentserver: " + serverProps);
report = this.deployService.deployDifferenceFS(version, path, host, port,
remoteUsername, remotePassword, targetName, regexMatcher, true, false, false, callbacks);
this.deployService.deployDifferenceFS(version,
path,
adapterName,
host,
port,
remoteUsername,
remotePassword,
targetName,
regexMatcher,
true,
false,
false,
callbacks);
}
else
{
@@ -393,14 +418,14 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase
logger.debug("Performing Alfresco deployment to " + host + ":" + port +
" using deploymentserver: " + serverProps);
report = this.deployService.deployDifference(version, path, host, port,
this.deployService.deployDifference(version, path, host, port,
remoteUsername, remotePassword, targetPath, regexMatcher, true, false, false, callbacks);
}
}
catch (Throwable err)
{
deployError = err;
logger.error(deployError);
logger.error("Deployment Error", deployError);
}
if (report != null)
@@ -458,7 +483,7 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase
reportProps.put(WCMAppModel.PROP_DEPLOYSERVERURLUSED,
serverProps.get(WCMAppModel.PROP_DEPLOYSERVERURL));
reportProps.put(WCMAppModel.PROP_DEPLOYSUCCESSFUL, (report != null));
reportProps.put(WCMAppModel.PROP_DEPLOYSUCCESSFUL, (report != null) && (error == null));
if (report == null && error != null)
{
// add error message as fail reason if appropriate (the reported
@@ -515,4 +540,6 @@ public class AVMDeployWebsiteAction extends ActionExecuterAbstractBase
return reportRef;
}
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.deploy;
import java.util.List;
import org.alfresco.deployment.DeploymentTransportOutputFilter;
/**
* Abstract Transport Adapter.
*
*/
public abstract class AbstractDeploymentReceiverTransportAdapter {
List<DeploymentTransportOutputFilter> transformers;
/**
* Get the content transformers for this transport - if the transport does not support
* content transformation then simply return null;
* @return the content transformers or null if there are no transformers.
*/
public List<DeploymentTransportOutputFilter>getTransformers() {
return transformers;
}
/**
* Set the content transformers for this transport - if the transport does not support
* content transformation then simply set null or do not call this method.
*/
public void setTransformers( List<DeploymentTransportOutputFilter> transformers) {
this.transformers = transformers;
}
}

View File

@@ -0,0 +1,125 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.deploy;
import java.io.IOException;
import java.io.OutputStream;
import org.alfresco.deployment.DeploymentReceiverTransport;
/**
* OutputStream used by client side to talk to
* the deployment receiver.
* @author britt
*/
public class DeploymentClientOutputStream extends OutputStream
{
private DeploymentReceiverTransport fTransport;
private String fTicket;
private String fOutputToken;
/**
* Make one up.
* @param transport
* @param ticket
* @param outputToken
*/
public DeploymentClientOutputStream(DeploymentReceiverTransport transport,
String ticket,
String outputToken)
{
fTransport = transport;
fTicket = ticket;
fOutputToken = outputToken;
}
/* (non-Javadoc)
* @see java.io.OutputStream#write(int)
*/
@Override
public void write(int b) throws IOException
{
byte[] buff = new byte[1];
buff[0] = (byte)b;
write(buff);
}
/* (non-Javadoc)
* @see java.io.OutputStream#close()
*/
@Override
public void close() throws IOException
{
// NO OP
}
/* (non-Javadoc)
* @see java.io.OutputStream#flush()
*/
@Override
public void flush() throws IOException
{
// NO OP
}
/* (non-Javadoc)
* @see java.io.OutputStream#write(byte[], int, int)
*/
@Override
public void write(byte[] b, int off, int len) throws IOException
{
fTransport.write(fTicket, fOutputToken, b, off, len);
}
/* (non-Javadoc)
* @see java.io.OutputStream#write(byte[])
*/
@Override
public void write(byte[] b) throws IOException
{
write(b, 0, b.length);
}
/**
* Get the deployment ticket.
* @return
*/
public String getTicket()
{
return fTicket;
}
/**
* Get the output token.
* @return
*/
public String getOutputToken()
{
return fOutputToken;
}
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.deploy;
/**
* Class to hold Deployment destination information.
* Used as a lock to serialize deployments to the same
* destination.
* @author britt
*/
public class DeploymentDestination
{
private String fHost;
private int fPort;
DeploymentDestination(String host, int port)
{
fHost = host;
fPort = port;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (!(obj instanceof DeploymentDestination))
{
return false;
}
DeploymentDestination other = (DeploymentDestination)obj;
return fHost.equals(other.fHost) && fPort == other.fPort;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode()
{
return fHost.hashCode() + fPort;
}
public String toString()
{
return fHost;
}
}

View File

@@ -0,0 +1,138 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.deploy;
import java.io.OutputStream;
import java.util.List;
import org.alfresco.deployment.DeploymentReceiverService;
import org.alfresco.deployment.DeploymentReceiverTransport;
import org.alfresco.deployment.FileDescriptor;
/**
* Client side implementation of DeploymentReceiverService which decorates a
* DeploymentReceiverTransport instance.
*
* This class adds code to the send and finishSend methods.
*
* @author britt
*/
public class DeploymentReceiverServiceClient implements
DeploymentReceiverService
{
/**
* The underlying transport.
*/
private DeploymentReceiverTransport fTransport;
public DeploymentReceiverServiceClient()
{
}
public void setDeploymentReceiverTransport(DeploymentReceiverTransport transport)
{
fTransport = transport;
}
/* (non-Javadoc)
* @see org.alfresco.deployment.DeploymentReceiverService#abort(java.lang.String)
*/
public void abort(String ticket)
{
fTransport.abort(ticket);
}
/* (non-Javadoc)
* @see org.alfresco.deployment.DeploymentReceiverService#begin(java.lang.String, java.lang.String, java.lang.String)
*/
public String begin(String target, String user, String password)
{
return fTransport.begin(target, user, password);
}
/* (non-Javadoc)
* @see org.alfresco.deployment.DeploymentReceiverService#commit(java.lang.String)
*/
public void commit(String ticket)
{
fTransport.commit(ticket);
}
/* (non-Javadoc)
* @see org.alfresco.deployment.DeploymentReceiverService#delete(java.lang.String, java.lang.String)
*/
public void delete(String ticket, String path)
{
fTransport.delete(ticket, path);
}
/* (non-Javadoc)
* @see org.alfresco.deployment.DeploymentReceiverService#finishSend(java.lang.String, java.io.OutputStream)
*/
public void finishSend(String ticket, OutputStream out)
{
DeploymentClientOutputStream dcOut = (DeploymentClientOutputStream)out;
fTransport.finishSend(dcOut.getTicket(), dcOut.getOutputToken());
}
/* (non-Javadoc)
* @see org.alfresco.deployment.DeploymentReceiverService#getListing(java.lang.String, java.lang.String)
*/
public List<FileDescriptor> getListing(String ticket, String path)
{
return fTransport.getListing(ticket, path);
}
/* (non-Javadoc)
* @see org.alfresco.deployment.DeploymentReceiverService#mkdir(java.lang.String, java.lang.String, java.lang.String)
*/
public void mkdir(String ticket, String path, String guid)
{
fTransport.mkdir(ticket, path, guid);
}
/* (non-Javadoc)
* @see org.alfresco.deployment.DeploymentReceiverService#send(java.lang.String, java.lang.String, java.lang.String)
*/
public OutputStream send(String ticket, String path, String guid)
{
String outputToken = fTransport.getSendToken(ticket, path, guid);
return new DeploymentClientOutputStream(fTransport, ticket, outputToken);
}
/* (non-Javadoc)
* @see org.alfresco.deployment.DeploymentReceiverService#shutDown(java.lang.String, java.lang.String)
*/
public void shutDown(String user, String password)
{
fTransport.shutDown(user, password);
}
public void setGuid(String ticket, String path, String guid)
{
fTransport.setGuid(ticket, path, guid);
}
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.deploy;
import java.util.List;
import org.alfresco.deployment.DeploymentReceiverTransport;
import org.alfresco.deployment.DeploymentTransportOutputFilter;
/**
*
* DeploymentReceiverTransportAdapter are used to adapt the interface used by the FSR Client to the
* interface used by the underlying transport implementation.
*
* The DeploymentReceiverTransport objects returned will typically be proxy classes to a remote service.
*
* @see org.alfresco.deployment.impl.client.DeploymentReceiverTransportAdapterRMI
* @see org.alfresco.deployment.impl.client.DeploymentReceiverTransportAdapterSpringHTTP
* @see org.alfresco.deployment.impl.client.DeploymentReceiverTransportAdapterHessian
*
* @author mrogers
*
*/
public interface DeploymentReceiverTransportAdapter
{
/**
* getObject is a factory method to get a DeploymentReceiverTransport object, which will typically
* be a proxy to a remote service.
*
* It is up to the adapters themselves to decide whether hostName, port or URL takes precedence.
*
* @param adapterName the name of this adapter
* @param hostName the name of the host to connect to
* @param port the port to connect to
* @param version the version of the website
* @param the path of the website to be deployed
* @return a DeploymentRecieverTransport
*/
public DeploymentReceiverTransport getTransport(String hostName, int port, int version, String srcPath);
/**
* Get the content transformers for this transport - if the transport does not support
* content transformation then simply return null;
* @return the content transformers or null if there are no transformers.
*/
public List<DeploymentTransportOutputFilter>getTransformers();
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.deploy;
import java.text.MessageFormat;
import org.alfresco.deployment.DeploymentReceiverTransport;
import org.springframework.remoting.caucho.HessianProxyFactoryBean;
/**
* This class adapts the Hessian protocol to DeploymentReceiverTransport
*
* @author mrogers
*/
public class DeploymentReceiverTransportAdapterHessian extends AbstractDeploymentReceiverTransportAdapter implements DeploymentReceiverTransportAdapter
{
/**
* The pattern to use when constructing the URL from hostname and port
*
* eg http://localhost:8080/FSR/deployment
*/
private String urlPattern = "http://{1}:{2}/FSR/deployment";
public DeploymentReceiverTransport getTransport(String host,
int port, int version, String srcPath)
{
MessageFormat f = new MessageFormat(urlPattern);
Object[] objs = { host, port };
String URL = f.format(objs);
// Code to use Hessian transport provided via Spring
HessianProxyFactoryBean factory = new HessianProxyFactoryBean();
factory.setServiceInterface(DeploymentReceiverTransport.class);
factory.setServiceUrl(URL);
factory.afterPropertiesSet();
DeploymentReceiverTransport transport = (DeploymentReceiverTransport) factory.getObject();
return transport;
}
public void setUrlPattern(String urlPattern) {
this.urlPattern = urlPattern;
}
public String getUrlPattern() {
return urlPattern;
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.deploy;
import org.alfresco.deployment.DeploymentReceiverTransport;
import org.springframework.remoting.rmi.RmiProxyFactoryBean;
/**
* Transport adapter to connect to the FSR using RMI protocol.
*
* @author mrogers
*
*/
public class DeploymentReceiverTransportAdapterRMI extends AbstractDeploymentReceiverTransportAdapter implements DeploymentReceiverTransportAdapter {
public DeploymentReceiverTransport getTransport(String hostName,
int port, int version, String srcPath)
{
// Code to use RMI transport
RmiProxyFactoryBean factory = new RmiProxyFactoryBean();
factory.setRefreshStubOnConnectFailure(true);
factory.setServiceInterface(DeploymentReceiverTransport.class);
factory.setServiceUrl("rmi://" + hostName + ":" + port + "/deployment");
factory.afterPropertiesSet();
DeploymentReceiverTransport transport = (DeploymentReceiverTransport)factory.getObject();
return transport;
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing
*/
package org.alfresco.repo.deploy;
import java.text.MessageFormat;
import org.alfresco.deployment.DeploymentReceiverTransport;
import org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean;
/**
* Transport adapter to connect to the FSR using Spring over HTTP protocol.
*
* @author mrogers
*
*/
public class DeploymentReceiverTransportAdapterSpringHTTP extends AbstractDeploymentReceiverTransportAdapter implements DeploymentReceiverTransportAdapter {
/**
* The pattern to use when constructing the URL from hostname and port
* {1} substitues for hostname {2} substitues for port
* Default format results in the following URL http://localhost:8080/alfrescoFSR/deployment
*/
private String urlPattern = "http://{1}:{2}/alfrescoFSR/deployment";
public DeploymentReceiverTransport getTransport(String host,
int port, int version, String srcPath)
{
MessageFormat f = new MessageFormat(getUrlPattern());
Object[] objs = { host, port };
String URL = f.format(objs);
// Code to use HTTP spring transport
HttpInvokerProxyFactoryBean factory = new HttpInvokerProxyFactoryBean();
factory.setServiceInterface(DeploymentReceiverTransport.class);
factory.setServiceUrl(URL);
factory.afterPropertiesSet();
DeploymentReceiverTransport transport = (DeploymentReceiverTransport) factory.getObject();
return transport;
}
public void setUrlPattern(String urlPattern) {
this.urlPattern = urlPattern;
}
public String getUrlPattern() {
return urlPattern;
}
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.deploy;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
import org.alfresco.service.cmr.avm.deploy.DeploymentEvent;
class DeploymentWork
{
private DeploymentEvent event;
private AVMNodeDescriptor src;
private String ticket;
public DeploymentWork(DeploymentEvent event, String ticket)
{
this.event = event;
this.ticket = ticket;
}
public DeploymentWork(DeploymentEvent event, String ticket, AVMNodeDescriptor src)
{
this.event = event;
this.ticket = ticket;
this.setSrc(src);
}
public DeploymentEvent getEvent()
{
return event;
}
public String getTicket()
{
return this.ticket;
}
public void setSrc(AVMNodeDescriptor src) {
this.src = src;
}
public AVMNodeDescriptor getSrc() {
return src;
}
}

View File

@@ -26,11 +26,15 @@
package org.alfresco.repo.deploy;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.alfresco.repo.avm.AVMServiceTestBase;
import org.alfresco.repo.avm.util.BulkLoader;
import org.alfresco.service.cmr.avm.deploy.DeploymentCallback;
import org.alfresco.service.cmr.avm.deploy.DeploymentEvent;
import org.alfresco.service.cmr.avm.deploy.DeploymentReport;
import org.alfresco.service.cmr.avm.deploy.DeploymentReportCallback;
import org.alfresco.service.cmr.avm.deploy.DeploymentService;
import org.alfresco.util.Deleter;
import org.alfresco.util.NameMatcher;
@@ -62,7 +66,11 @@ public class FSDeploymentTest extends AVMServiceTestBase
NameMatcher matcher = (NameMatcher)fContext.getBean("globalPathExcluder");
setupBasicTree();
fService.createFile("main:/a/b", "fudge.bak").close();
DeploymentReport report = service.deployDifferenceFS(-1, "main:/", "localhost", 44100, "Giles", "Watcher", "sampleTarget", matcher, false, false, false, null);
DeploymentReport report = new DeploymentReport();
List<DeploymentCallback> callbacks = new ArrayList<DeploymentCallback>();
callbacks.add(new DeploymentReportCallback(report));
service.deployDifferenceFS(-1, "main:/", "localhost", "default", 44100, "Giles", "Watcher", "sampleTarget", matcher, false, false, false, callbacks);
int count = 0;
for (DeploymentEvent event : report)
{
@@ -70,7 +78,14 @@ public class FSDeploymentTest extends AVMServiceTestBase
count++;
}
assertEquals(10, count);
report = service.deployDifferenceFS(-1, "main:/", "localhost", 44100, "Giles", "Watcher", "sampleTarget", matcher, false, false, false, null);
report = new DeploymentReport();
callbacks = new ArrayList<DeploymentCallback>();
callbacks.add(new DeploymentReportCallback(report));
callbacks.add(new DeploymentReportCallback(report));
service.deployDifferenceFS(-1, "main:/", "localhost", "default", 44100, "Giles", "Watcher", "sampleTarget", matcher, false, false, false, callbacks);
count = 0;
for (DeploymentEvent event : report)
{
@@ -80,7 +95,13 @@ public class FSDeploymentTest extends AVMServiceTestBase
assertEquals(2, count);
fService.createFile("main:/d", "jonathan").close();
fService.removeNode("main:/a/b");
report = service.deployDifferenceFS(-1, "main:/", "localhost", 44100, "Giles", "Watcher", "sampleTarget", matcher, false, false, false, null);
report = new DeploymentReport();
callbacks = new ArrayList<DeploymentCallback>();
callbacks.add(new DeploymentReportCallback(report));
service.deployDifferenceFS(-1, "main:/", "localhost", "default", 44100, "Giles", "Watcher", "sampleTarget", matcher, false, false, false, callbacks);
count = 0;
for (DeploymentEvent event : report)
{
@@ -90,7 +111,12 @@ public class FSDeploymentTest extends AVMServiceTestBase
assertEquals(4, count);
fService.removeNode("main:/d/e");
fService.createFile("main:/d", "e").close();
report = service.deployDifferenceFS(-1, "main:/", "localhost", 44100, "Giles", "Watcher", "sampleTarget", matcher, false, false, false, null);
report = new DeploymentReport();
callbacks = new ArrayList<DeploymentCallback>();
callbacks.add(new DeploymentReportCallback(report));
service.deployDifferenceFS(-1, "main:/", "localhost", "default", 44100, "Giles", "Watcher", "sampleTarget", matcher, false, false, false, callbacks);
count = 0;
for (DeploymentEvent event : report)
{
@@ -102,7 +128,11 @@ public class FSDeploymentTest extends AVMServiceTestBase
fService.createDirectory("main:/d", "e");
fService.createFile("main:/d/e", "Warren.txt").close();
fService.createFile("main:/d/e", "It's a silly name.txt").close();
report = service.deployDifferenceFS(-1, "main:/", "localhost", 44100, "Giles", "Watcher", "sampleTarget", matcher, false, false, false, null);
report = new DeploymentReport();
callbacks = new ArrayList<DeploymentCallback>();
callbacks.add(new DeploymentReportCallback(report));
service.deployDifferenceFS(-1, "main:/", "localhost", "default", 44100, "Giles", "Watcher", "sampleTarget", matcher, false, false, false, callbacks);
count = 0;
for (DeploymentEvent event : report)
{
@@ -113,10 +143,18 @@ public class FSDeploymentTest extends AVMServiceTestBase
BulkLoader loader = new BulkLoader();
loader.setAvmService(fService);
loader.recursiveLoad("source/java/org/alfresco/repo/avm", "main:/");
report = service.deployDifferenceFS(-1, "main:/", "localhost", 44100, "Giles", "Watcher", "sampleTarget", matcher, false, false, false, null);
report = new DeploymentReport();
callbacks = new ArrayList<DeploymentCallback>();
callbacks.add(new DeploymentReportCallback(report));
service.deployDifferenceFS(-1, "main:/", "localhost", "default", 44100, "Giles", "Watcher", "sampleTarget", matcher, false, false, false, callbacks);
fService.removeNode("main:/avm/hibernate");
fService.getFileOutputStream("main:/avm/AVMServiceTest.java").close();
report = service.deployDifferenceFS(-1, "main:/", "localhost", 44100, "Giles", "Watcher", "sampleTarget", matcher, false, false, false, null);
report = new DeploymentReport();
callbacks = new ArrayList<DeploymentCallback>();
callbacks.add(new DeploymentReportCallback(report));
service.deployDifferenceFS(-1, "main:/", "localhost", "default", 44100, "Giles", "Watcher", "sampleTarget", matcher, false, false, false, callbacks);
count = 0;
for (DeploymentEvent event : report)
{

View File

@@ -34,6 +34,7 @@ import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.attributes.AttributeService;
import org.alfresco.service.cmr.audit.AuditService;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.avm.deploy.DeploymentService;
import org.alfresco.service.cmr.avm.locking.AVMLockingService;
import org.alfresco.service.cmr.avmsync.AVMSyncService;
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
@@ -451,4 +452,14 @@ public class ServiceDescriptorRegistry
{
return (TaggingService)getService(TAGGING_SERVICE);
}
/* (non-Javadoc)
* @see org.alfresco.service.ServiceRegistry#getDeploymentService()
*/
public DeploymentService getDeploymentService() {
return (DeploymentService) getService(DEPLOYMENT_SERVICE);
}
}

View File

@@ -62,6 +62,7 @@ import org.alfresco.service.cmr.thumbnail.ThumbnailService;
import org.alfresco.service.cmr.version.VersionService;
import org.alfresco.service.cmr.view.ExporterService;
import org.alfresco.service.cmr.view.ImporterService;
import org.alfresco.service.cmr.avm.deploy.DeploymentService;
import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.descriptor.DescriptorService;
import org.alfresco.service.namespace.NamespaceService;
@@ -125,6 +126,7 @@ public interface ServiceRegistry
static final QName VIRT_SERVER_REGISTRY = QName.createQName(NamespaceService.ALFRESCO_URI, "VirtServerRegistry");
static final QName THUMBNAIL_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "ThumbnailService");
static final QName TAGGING_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "TaggingService");
static final QName DEPLOYMENT_SERVICE = QName.createQName(NamespaceService.ALFRESCO_URI, "DeploymentService");
/**
* Get the list of services provided by the Repository
@@ -411,4 +413,11 @@ public interface ServiceRegistry
*/
@NotAuditable
TaggingService getTaggingService();
/**
* Get the Deployment Service
* @return the deployment service (or null, if one is not provided)
*/
@NotAuditable
DeploymentService getDeploymentService();
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) 2005-2008 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.service.cmr.avm.deploy;
public class DeploymentReportCallback implements DeploymentCallback
{
private DeploymentReport report;
public DeploymentReportCallback(DeploymentReport report )
{
this.report = report;
}
/**
* Called each time something happens during deployment.
* This is called synchronously by the deployer and should
* therefore be handled rapidly, if possible.
* @param event The event that occurred.
*/
public void eventOccurred(DeploymentEvent event){
report.add(event);
}
}

View File

@@ -3,6 +3,7 @@
*/
package org.alfresco.service.cmr.avm.deploy;
import java.util.Set;
import java.util.List;
import org.alfresco.service.cmr.action.ActionService;
@@ -29,9 +30,11 @@ public interface DeploymentService
* @param dontDo If this is set then this is a dry run.
* @param callback A possibly null callback.
*/
public DeploymentReport deployDifference(int version, String srcPath,
String hostName, int port,
String userName, String password,
public void deployDifference(int version, String srcPath,
String hostName,
int port,
String userName,
String password,
String dstPath,
NameMatcher matcher,
boolean createDst,
@@ -54,23 +57,37 @@ public interface DeploymentService
* Deploy to a filesystem on another machine.
* @param version The version to deploy from.
* @param srcPath The path to deploy from.
* @param adapterName The name of the transport adapter to connect to the remote system.
* The value "default" means use the traditional RMI used for versions of Alfresco prior to 3.0
* @param hostName The hostname of the filesystem receiver.
* @param port The port to connect to.
* @param userName The username for authentication
* @param password The password for authentication
* @param userName The username for authentication of the target
* @param password The password for authentication of the target
* @param dstTarget The target on the deployment receiver.
* @param createDst Flag for whether a missing destination should be created.
* @param dontDelete Don't delete deleted nodes from destination.
* @param dontDo If this is set, this is a dry run.
* @param callback A possibly null callback.
*/
public DeploymentReport deployDifferenceFS(int version, String srcPath,
String hostName, int port,
String userName, String password,
public void deployDifferenceFS(int version,
String srcPath,
String adapterName,
String hostName,
int port,
String userName,
String password,
String dstTarget,
NameMatcher matcher,
boolean createDst,
boolean dontDelete,
boolean dontDo,
List<DeploymentCallback> callback);
/**
* Get the names of the transport adapters.
*
* @return the adapters
*/
public Set<String> getAdapterNames();
}

View File

@@ -71,6 +71,7 @@ public class ThreadPoolExecutorFactoryBean implements FactoryBean, InitializingB
private static final boolean DEFAULT_THREAD_DAEMON = Boolean.TRUE;
private static final int DEFAULT_WORK_QUEUE_SIZE = -1;
private static final RejectedExecutionHandler DEFAULT_REJECTED_EXECUTION_HANDLER = new ThreadPoolExecutor.CallerRunsPolicy();
private String poolName = "";
private int corePoolSize;
private int maximumPoolSize;
@@ -183,6 +184,11 @@ public class ThreadPoolExecutorFactoryBean implements FactoryBean, InitializingB
threadFactory.setThreadDaemon(threadDaemon);
threadFactory.setThreadPriority(threadPriority);
if(poolName.length() > 0)
{
threadFactory.setNamePrefix(poolName);
}
if (workQueueSize < 0)
{
workQueueSize = Integer.MAX_VALUE;
@@ -227,4 +233,14 @@ public class ThreadPoolExecutorFactoryBean implements FactoryBean, InitializingB
{
return ThreadPoolExecutor.class;
}
public String getPoolName()
{
return this.poolName;
}
public void setPoolName(String poolName)
{
this.poolName = poolName;
}
}

View File

@@ -54,7 +54,7 @@ public class TraceableThreadFactory implements ThreadFactory
}
private final ThreadGroup group;
private final String namePrefix;
private String namePrefix;
private final AtomicInteger threadNumber;
private boolean threadDaemon;
private int threadPriority;
@@ -98,4 +98,15 @@ public class TraceableThreadFactory implements ThreadFactory
return thread;
}
public void setNamePrefix(String namePrefix)
{
this.namePrefix = namePrefix;
}
public String getNamePrefix()
{
return this.namePrefix;
}
}