mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
transfer service : now deals with restored nodes + unit tests.
work in progress on sync of folders containing alien nodes - incomplete so commented out. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@21329 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -188,13 +188,24 @@
|
|||||||
</aspect>
|
</aspect>
|
||||||
|
|
||||||
<aspect name="trx:transferred">
|
<aspect name="trx:transferred">
|
||||||
<title>Nodes with this aspect are have been transferred from one repository to another
|
<title>Nodes with this aspect have been transferred from one repository to another
|
||||||
</title>
|
</title>
|
||||||
<properties>
|
<properties>
|
||||||
<property name="trx:repositoryId">
|
<property name="trx:repositoryId">
|
||||||
<title>Source RepositoryId</title>
|
<title>Source RepositoryId</title>
|
||||||
<type>d:text</type>
|
<type>d:text</type>
|
||||||
<mandatory enforced="false">true</mandatory>
|
<mandatory enforced="true">true</mandatory>
|
||||||
|
</property>
|
||||||
|
<property name="trx:fromRepositoryId">
|
||||||
|
<title>The repository that this node was transferred from</title>
|
||||||
|
<type>d:text</type>
|
||||||
|
<mandatory enforced="true">true</mandatory>
|
||||||
|
</property>
|
||||||
|
<property name="trx:alien">
|
||||||
|
<title>Alien Content</title>
|
||||||
|
<type>d:boolean</type>
|
||||||
|
<mandatory enforced="false">false</mandatory>
|
||||||
|
<default>false</default>
|
||||||
</property>
|
</property>
|
||||||
</properties>
|
</properties>
|
||||||
</aspect>
|
</aspect>
|
||||||
|
@@ -79,6 +79,7 @@
|
|||||||
<property name="manifestProcessorFactory" ref="transferManifestProcessorFactory" />
|
<property name="manifestProcessorFactory" ref="transferManifestProcessorFactory" />
|
||||||
<property name="behaviourFilter" ref="policyBehaviourFilter" />
|
<property name="behaviourFilter" ref="policyBehaviourFilter" />
|
||||||
<property name="progressMonitor" ref="transferProgressMonitor" />
|
<property name="progressMonitor" ref="transferProgressMonitor" />
|
||||||
|
<property name="policyComponent" ref="policyComponent" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="transferProgressMonitor"
|
<bean id="transferProgressMonitor"
|
||||||
|
30
source/java/org/alfresco/repo/policy/package-info.java
Normal file
30
source/java/org/alfresco/repo/policy/package-info.java
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* The Policy Component.
|
||||||
|
*
|
||||||
|
* Policy Component for managing Policies and Behaviours.
|
||||||
|
* <p>
|
||||||
|
* This component provides the ability to:
|
||||||
|
* <p>
|
||||||
|
* <ul>
|
||||||
|
* <li>a) Register policies</li>
|
||||||
|
* <li>b) Bind behaviours to policies</li>
|
||||||
|
* <li>c) Invoke policy behaviours</li>
|
||||||
|
* </ul>
|
||||||
|
* <p>
|
||||||
|
* A behaviour may be bound to a Policy before the Policy is registered. In
|
||||||
|
* this case, the behaviour is not validated (i.e. checked to determine if it
|
||||||
|
* supports the policy interface) until the Policy is registered. Otherwise,
|
||||||
|
* the behaviour is validated at bind-time.
|
||||||
|
* <p>
|
||||||
|
* Policies may be selectively "turned off" by the Behaviour Filter.
|
||||||
|
* @see org.alfresco.repo.policy.PolicyComponent
|
||||||
|
* @see org.alfresco.repo.policy.BehaviourFilter
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.policy;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -218,30 +218,15 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
|
|||||||
if (nodeService.exists(archiveNodeRef))
|
if (nodeService.exists(archiveNodeRef))
|
||||||
{
|
{
|
||||||
// We have found a node in the archive store that has the same
|
// We have found a node in the archive store that has the same
|
||||||
// UUID as the one that we've
|
// UUID as the one that we've been sent. If it remains it may cause problems later on
|
||||||
// been sent. We'll restore that archived node to a temporary
|
// We delete from the archive store and treat the new node as a create.
|
||||||
// location and then try
|
|
||||||
// processing this node again
|
|
||||||
if (log.isInfoEnabled())
|
if (log.isInfoEnabled())
|
||||||
{
|
{
|
||||||
log.info("Located an archived node with UUID matching transferred node: " + archiveNodeRef);
|
log.info("Located an archived node with UUID matching transferred node: " + archiveNodeRef);
|
||||||
log.info("Attempting to restore " + archiveNodeRef);
|
log.info("Attempting to restore " + archiveNodeRef);
|
||||||
}
|
}
|
||||||
logProgress("Restoring node from archive: " + archiveNodeRef);
|
logProgress("Delete node from archive: " + archiveNodeRef);
|
||||||
|
nodeService.deleteNode(archiveNodeRef);
|
||||||
ChildAssociationRef tempLocation = getTemporaryLocation(node.getNodeRef());
|
|
||||||
NodeRef restoredNodeRef = nodeService.restoreNode(archiveNodeRef, tempLocation.getParentRef(),
|
|
||||||
tempLocation.getTypeQName(), tempLocation.getQName());
|
|
||||||
if (log.isInfoEnabled())
|
|
||||||
{
|
|
||||||
log.info("Successfully restored node as " + restoredNodeRef + " - retrying transferred node");
|
|
||||||
}
|
|
||||||
//Check to see if the node we've just restored is the parent of any orphans
|
|
||||||
checkOrphans(restoredNodeRef);
|
|
||||||
//Process the received node information again now that we've restored it
|
|
||||||
//(should be handled as an update now)
|
|
||||||
processTransferManifestNode(node);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log.isDebugEnabled())
|
if (log.isDebugEnabled())
|
||||||
@@ -304,6 +289,7 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
|
|||||||
log.debug("injecting repositoryId property");
|
log.debug("injecting repositoryId property");
|
||||||
props.put(TransferModel.PROP_REPOSITORY_ID, header.getRepositoryId());
|
props.put(TransferModel.PROP_REPOSITORY_ID, header.getRepositoryId());
|
||||||
}
|
}
|
||||||
|
props.put(TransferModel.PROP_FROM_REPOSITORY_ID, header.getRepositoryId());
|
||||||
|
|
||||||
// Create the corresponding node...
|
// Create the corresponding node...
|
||||||
ChildAssociationRef newNode = nodeService.createNode(parentNodeRef, parentAssocType, parentAssocName, node
|
ChildAssociationRef newNode = nodeService.createNode(parentNodeRef, parentAssocType, parentAssocName, node
|
||||||
@@ -425,6 +411,7 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
|
|||||||
log.debug("injecting repositoryId property");
|
log.debug("injecting repositoryId property");
|
||||||
props.put(TransferModel.PROP_REPOSITORY_ID, header.getRepositoryId());
|
props.put(TransferModel.PROP_REPOSITORY_ID, header.getRepositoryId());
|
||||||
}
|
}
|
||||||
|
props.put(TransferModel.PROP_FROM_REPOSITORY_ID, header.getRepositoryId());
|
||||||
|
|
||||||
// Split out the content properties and sanitise the others
|
// Split out the content properties and sanitise the others
|
||||||
Map<QName, Serializable> contentProps = processProperties(nodeToUpdate, props, existingProps);
|
Map<QName, Serializable> contentProps = processProperties(nodeToUpdate, props, existingProps);
|
||||||
|
@@ -38,7 +38,11 @@ import javax.xml.parsers.SAXParser;
|
|||||||
import javax.xml.parsers.SAXParserFactory;
|
import javax.xml.parsers.SAXParserFactory;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.node.NodeServicePolicies;
|
||||||
import org.alfresco.repo.policy.BehaviourFilter;
|
import org.alfresco.repo.policy.BehaviourFilter;
|
||||||
|
import org.alfresco.repo.policy.JavaBehaviour;
|
||||||
|
import org.alfresco.repo.policy.PolicyComponent;
|
||||||
|
import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
|
||||||
import org.alfresco.repo.rule.RuleModel;
|
import org.alfresco.repo.rule.RuleModel;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||||
@@ -76,7 +80,10 @@ import org.springframework.util.FileCopyUtils;
|
|||||||
* @author brian
|
* @author brian
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class RepoTransferReceiverImpl implements TransferReceiver
|
public class RepoTransferReceiverImpl implements TransferReceiver,
|
||||||
|
NodeServicePolicies.OnCreateChildAssociationPolicy,
|
||||||
|
NodeServicePolicies.BeforeDeleteNodePolicy
|
||||||
|
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* This embedded class is used to push requests for asynchronous commits onto a different thread
|
* This embedded class is used to push requests for asynchronous commits onto a different thread
|
||||||
@@ -150,6 +157,7 @@ public class RepoTransferReceiverImpl implements TransferReceiver
|
|||||||
private ActionService actionService;
|
private ActionService actionService;
|
||||||
private TenantService tenantService;
|
private TenantService tenantService;
|
||||||
private RuleService ruleService;
|
private RuleService ruleService;
|
||||||
|
private PolicyComponent policyComponent;
|
||||||
|
|
||||||
private Map<String,NodeRef> transferLockFolderMap = new ConcurrentHashMap<String, NodeRef>();
|
private Map<String,NodeRef> transferLockFolderMap = new ConcurrentHashMap<String, NodeRef>();
|
||||||
private Map<String,NodeRef> transferTempFolderMap = new ConcurrentHashMap<String, NodeRef>();
|
private Map<String,NodeRef> transferTempFolderMap = new ConcurrentHashMap<String, NodeRef>();
|
||||||
@@ -167,6 +175,19 @@ public class RepoTransferReceiverImpl implements TransferReceiver
|
|||||||
PropertyCheck.mandatory(this, "transferLockFolderPath", transferLockFolderPath);
|
PropertyCheck.mandatory(this, "transferLockFolderPath", transferLockFolderPath);
|
||||||
PropertyCheck.mandatory(this, "inboundTransferRecordsPath", inboundTransferRecordsPath);
|
PropertyCheck.mandatory(this, "inboundTransferRecordsPath", inboundTransferRecordsPath);
|
||||||
PropertyCheck.mandatory(this, "rootStagingDirectory", rootStagingDirectory);
|
PropertyCheck.mandatory(this, "rootStagingDirectory", rootStagingDirectory);
|
||||||
|
PropertyCheck.mandatory(this, "policyComponent", policyComponent);
|
||||||
|
|
||||||
|
// // Register policy behaviours
|
||||||
|
// this.getPolicyComponent().bindAssociationBehaviour(
|
||||||
|
// NodeServicePolicies.OnCreateChildAssociationPolicy.QNAME,
|
||||||
|
// TransferModel.ASPECT_TRANSFERRED,
|
||||||
|
// new JavaBehaviour(this, "onCreateChildAssociation", NotificationFrequency.EVERY_EVENT));
|
||||||
|
//
|
||||||
|
// this.getPolicyComponent().bindClassBehaviour(
|
||||||
|
// NodeServicePolicies.BeforeDeleteNodePolicy.QNAME,
|
||||||
|
// this,
|
||||||
|
// new JavaBehaviour(this, "beforeDeleteNode", NotificationFrequency.EVERY_EVENT));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -902,4 +923,98 @@ public class RepoTransferReceiverImpl implements TransferReceiver
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPolicyComponent(PolicyComponent policyComponent)
|
||||||
|
{
|
||||||
|
this.policyComponent = policyComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PolicyComponent getPolicyComponent()
|
||||||
|
{
|
||||||
|
return policyComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When a new node is created as a child of a Transferred node then
|
||||||
|
* the transferred nodes need to be marked as Alien nodes.
|
||||||
|
*
|
||||||
|
* The tree needs to be walked upwards to mark all parent transferred nodes as alien.
|
||||||
|
*/
|
||||||
|
public void onCreateChildAssociation(ChildAssociationRef childAssocRef,
|
||||||
|
boolean isNewNode)
|
||||||
|
{
|
||||||
|
|
||||||
|
log.debug("on create child association to transferred node");
|
||||||
|
|
||||||
|
ChildAssociationRef ref = childAssocRef;
|
||||||
|
|
||||||
|
if(childAssocRef.isPrimary())
|
||||||
|
{
|
||||||
|
while(ref != null)
|
||||||
|
{
|
||||||
|
NodeRef parentNodeRef = ref.getParentRef();
|
||||||
|
NodeRef childNodeRef = ref.getChildRef();
|
||||||
|
|
||||||
|
if(nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_TRANSFERRED))
|
||||||
|
{
|
||||||
|
Boolean isAlien = (Boolean)nodeService.getProperty(parentNodeRef, TransferModel.PROP_ALIEN);
|
||||||
|
|
||||||
|
if (!isAlien)
|
||||||
|
{
|
||||||
|
log.debug("setting node as alien:" + parentNodeRef);
|
||||||
|
nodeService.setProperty(parentNodeRef, TransferModel.PROP_ALIEN, Boolean.TRUE);
|
||||||
|
ref = nodeService.getPrimaryParent(parentNodeRef);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log.debug("parent node is already alien");
|
||||||
|
ref = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log.debug("parent is not a transferred node");
|
||||||
|
ref = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When an old node is deleted that is a child of a transferred node the tree may need to be walked to
|
||||||
|
* mark parent folder as non alien.
|
||||||
|
*/
|
||||||
|
public void beforeDeleteNode(NodeRef nodeRef)
|
||||||
|
{
|
||||||
|
log.debug("on delete node - need to check for transferred node");
|
||||||
|
|
||||||
|
ChildAssociationRef ref = nodeService.getPrimaryParent(nodeRef);
|
||||||
|
|
||||||
|
while(ref != null)
|
||||||
|
{
|
||||||
|
NodeRef parentNodeRef = ref.getParentRef();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Was the parent node transferred ?
|
||||||
|
*/
|
||||||
|
if(nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_TRANSFERRED))
|
||||||
|
{
|
||||||
|
log.debug("parent node was transferred - check siblings");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the siblings of this node to see whether there are any other alien nodes.
|
||||||
|
*/
|
||||||
|
// nodeService.getChildAssocs(parentNodeRef);
|
||||||
|
// BUGBUG Code not complete
|
||||||
|
ref = null;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log.debug("parent is not a transferred node");
|
||||||
|
ref = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -38,7 +38,8 @@ public interface TransferModel
|
|||||||
*/
|
*/
|
||||||
static final QName ASPECT_TRANSFERRED = QName.createQName(TRANSFER_MODEL_1_0_URI, "transferred");
|
static final QName ASPECT_TRANSFERRED = QName.createQName(TRANSFER_MODEL_1_0_URI, "transferred");
|
||||||
static final QName PROP_REPOSITORY_ID = QName.createQName(TRANSFER_MODEL_1_0_URI, "repositoryId");
|
static final QName PROP_REPOSITORY_ID = QName.createQName(TRANSFER_MODEL_1_0_URI, "repositoryId");
|
||||||
|
static final QName PROP_FROM_REPOSITORY_ID = QName.createQName(TRANSFER_MODEL_1_0_URI, "fromRepositoryId");
|
||||||
|
static final QName PROP_ALIEN = QName.createQName(TRANSFER_MODEL_1_0_URI, "alien");
|
||||||
/*
|
/*
|
||||||
* Type : Transfer Group
|
* Type : Transfer Group
|
||||||
*/
|
*/
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user