mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Callback mechanism for notifying CIFS when Stores are
created or purged, and when versions are created or purged. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4541 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -165,6 +165,14 @@
|
|||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="createStoreTxnListener" class="org.alfresco.repo.avm.CreateStoreTxnListener"/>
|
||||||
|
|
||||||
|
<bean id="purgeStoreTxnListener" class="org.alfresco.repo.avm.PurgeStoreTxnListener"/>
|
||||||
|
|
||||||
|
<bean id="createVersionTxnListener" class="org.alfresco.repo.avm.CreateVersionTxnListener"/>
|
||||||
|
|
||||||
|
<bean id="purgeVersionTxnListener" class="org.alfresco.repo.avm.PurgeVersionTxnListener"/>
|
||||||
|
|
||||||
<bean id="avmRepository" class="org.alfresco.repo.avm.AVMRepository">
|
<bean id="avmRepository" class="org.alfresco.repo.avm.AVMRepository">
|
||||||
<property name="nodeIssuer">
|
<property name="nodeIssuer">
|
||||||
<ref bean="nodeIssuer"/>
|
<ref bean="nodeIssuer"/>
|
||||||
@@ -178,6 +186,18 @@
|
|||||||
<property name="contentStore">
|
<property name="contentStore">
|
||||||
<ref bean="fileContentStore"/>
|
<ref bean="fileContentStore"/>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="createStoreTxnListener">
|
||||||
|
<ref bean="createStoreTxnListener"/>
|
||||||
|
</property>
|
||||||
|
<property name="purgeStoreTxnListener">
|
||||||
|
<ref bean="purgeStoreTxnListener"/>
|
||||||
|
</property>
|
||||||
|
<property name="createVersionTxnListener">
|
||||||
|
<ref bean="createVersionTxnListener"/>
|
||||||
|
</property>
|
||||||
|
<property name="purgeVersionTxnListener">
|
||||||
|
<ref bean="purgeVersionTxnListener"/>
|
||||||
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- A Local implementation of the Remote AVM interface. -->
|
<!-- A Local implementation of the Remote AVM interface. -->
|
||||||
|
@@ -30,6 +30,7 @@ import java.util.SortedMap;
|
|||||||
import org.alfresco.repo.content.ContentStore;
|
import org.alfresco.repo.content.ContentStore;
|
||||||
import org.alfresco.repo.domain.DbAccessControlList;
|
import org.alfresco.repo.domain.DbAccessControlList;
|
||||||
import org.alfresco.repo.domain.PropertyValue;
|
import org.alfresco.repo.domain.PropertyValue;
|
||||||
|
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||||
import org.alfresco.service.cmr.avm.AVMBadArgumentException;
|
import org.alfresco.service.cmr.avm.AVMBadArgumentException;
|
||||||
import org.alfresco.service.cmr.avm.AVMCycleException;
|
import org.alfresco.service.cmr.avm.AVMCycleException;
|
||||||
import org.alfresco.service.cmr.avm.AVMException;
|
import org.alfresco.service.cmr.avm.AVMException;
|
||||||
@@ -86,6 +87,28 @@ public class AVMRepository
|
|||||||
*/
|
*/
|
||||||
private LookupCache fLookupCache;
|
private LookupCache fLookupCache;
|
||||||
|
|
||||||
|
// A bunch of TransactionListeners that do work for this.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One for create store.
|
||||||
|
*/
|
||||||
|
private CreateStoreTxnListener fCreateStoreTxnListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One for purge store.
|
||||||
|
*/
|
||||||
|
private PurgeStoreTxnListener fPurgeStoreTxnListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One for create version.
|
||||||
|
*/
|
||||||
|
private CreateVersionTxnListener fCreateVersionTxnListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One for purge version.
|
||||||
|
*/
|
||||||
|
private PurgeVersionTxnListener fPurgeVersionTxnListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new one.
|
* Create a new one.
|
||||||
*/
|
*/
|
||||||
@@ -130,6 +153,26 @@ public class AVMRepository
|
|||||||
fLookupCache = cache;
|
fLookupCache = cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setCreateStoreTxnListener(CreateStoreTxnListener listener)
|
||||||
|
{
|
||||||
|
fCreateStoreTxnListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPurgeStoreTxnListener(PurgeStoreTxnListener listener)
|
||||||
|
{
|
||||||
|
fPurgeStoreTxnListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateVersionTxnListener(CreateVersionTxnListener listener)
|
||||||
|
{
|
||||||
|
fCreateVersionTxnListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPurgeVersionTxnListener(PurgeVersionTxnListener listener)
|
||||||
|
{
|
||||||
|
fPurgeVersionTxnListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a file.
|
* Create a file.
|
||||||
* @param path The path to the containing directory.
|
* @param path The path to the containing directory.
|
||||||
@@ -311,6 +354,7 @@ public class AVMRepository
|
|||||||
*/
|
*/
|
||||||
public void createAVMStore(String name)
|
public void createAVMStore(String name)
|
||||||
{
|
{
|
||||||
|
AlfrescoTransactionSupport.bindListener(fCreateStoreTxnListener);
|
||||||
if (getAVMStoreByName(name) != null)
|
if (getAVMStoreByName(name) != null)
|
||||||
{
|
{
|
||||||
throw new AVMExistsException("AVMStore exists: " + name);
|
throw new AVMExistsException("AVMStore exists: " + name);
|
||||||
@@ -320,6 +364,7 @@ public class AVMRepository
|
|||||||
AVMStore rep = new AVMStoreImpl(this, name);
|
AVMStore rep = new AVMStoreImpl(this, name);
|
||||||
// Special handling for AVMStore creation.
|
// Special handling for AVMStore creation.
|
||||||
rep.getRoot().setStoreNew(null);
|
rep.getRoot().setStoreNew(null);
|
||||||
|
fCreateStoreTxnListener.storeCreated(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -672,27 +717,6 @@ public class AVMRepository
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Snapshot the given repositories.
|
|
||||||
* @param repositories The list of AVMStore name to snapshot.
|
|
||||||
* @return A List of version ids for each newly snapshotted AVMStore.
|
|
||||||
*/
|
|
||||||
public List<Integer> createSnapshot(List<String> repositories)
|
|
||||||
{
|
|
||||||
List<Integer> result = new ArrayList<Integer>();
|
|
||||||
for (String repName : repositories)
|
|
||||||
{
|
|
||||||
AVMStore store = getAVMStoreByName(repName);
|
|
||||||
if (store == null)
|
|
||||||
{
|
|
||||||
throw new AVMNotFoundException("Store not found.");
|
|
||||||
}
|
|
||||||
fLookupCache.onSnapshot(repName);
|
|
||||||
result.add(store.createSnapshot(null, null));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a snapshot of a single AVMStore.
|
* Create a snapshot of a single AVMStore.
|
||||||
* @param store The name of the repository.
|
* @param store The name of the repository.
|
||||||
@@ -702,6 +726,7 @@ public class AVMRepository
|
|||||||
*/
|
*/
|
||||||
public int createSnapshot(String storeName, String tag, String description)
|
public int createSnapshot(String storeName, String tag, String description)
|
||||||
{
|
{
|
||||||
|
AlfrescoTransactionSupport.bindListener(fCreateVersionTxnListener);
|
||||||
AVMStore store = getAVMStoreByName(storeName);
|
AVMStore store = getAVMStoreByName(storeName);
|
||||||
if (store == null)
|
if (store == null)
|
||||||
{
|
{
|
||||||
@@ -709,6 +734,7 @@ public class AVMRepository
|
|||||||
}
|
}
|
||||||
fLookupCache.onSnapshot(storeName);
|
fLookupCache.onSnapshot(storeName);
|
||||||
int result = store.createSnapshot(tag, description);
|
int result = store.createSnapshot(tag, description);
|
||||||
|
fCreateVersionTxnListener.versionCreated(storeName, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -745,6 +771,7 @@ public class AVMRepository
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void purgeAVMStore(String name)
|
public void purgeAVMStore(String name)
|
||||||
{
|
{
|
||||||
|
AlfrescoTransactionSupport.bindListener(fPurgeStoreTxnListener);
|
||||||
AVMStore store = getAVMStoreByName(name);
|
AVMStore store = getAVMStoreByName(name);
|
||||||
if (store == null)
|
if (store == null)
|
||||||
{
|
{
|
||||||
@@ -769,6 +796,7 @@ public class AVMRepository
|
|||||||
AVMDAOs.Instance().fAVMStorePropertyDAO.delete(store);
|
AVMDAOs.Instance().fAVMStorePropertyDAO.delete(store);
|
||||||
AVMDAOs.Instance().fAVMStoreDAO.delete(store);
|
AVMDAOs.Instance().fAVMStoreDAO.delete(store);
|
||||||
AVMDAOs.Instance().fAVMStoreDAO.invalidateCache();
|
AVMDAOs.Instance().fAVMStoreDAO.invalidateCache();
|
||||||
|
fPurgeStoreTxnListener.storePurged(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -778,6 +806,7 @@ public class AVMRepository
|
|||||||
*/
|
*/
|
||||||
public void purgeVersion(String name, int version)
|
public void purgeVersion(String name, int version)
|
||||||
{
|
{
|
||||||
|
AlfrescoTransactionSupport.bindListener(fPurgeVersionTxnListener);
|
||||||
AVMStore store = getAVMStoreByName(name);
|
AVMStore store = getAVMStoreByName(name);
|
||||||
if (store == null)
|
if (store == null)
|
||||||
{
|
{
|
||||||
@@ -785,6 +814,7 @@ public class AVMRepository
|
|||||||
}
|
}
|
||||||
fLookupCache.onDelete(name);
|
fLookupCache.onDelete(name);
|
||||||
store.purgeVersion(version);
|
store.purgeVersion(version);
|
||||||
|
fPurgeVersionTxnListener.versionPurged(name, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2279,6 +2309,8 @@ public class AVMRepository
|
|||||||
*/
|
*/
|
||||||
public void renameStore(String sourceName, String destName)
|
public void renameStore(String sourceName, String destName)
|
||||||
{
|
{
|
||||||
|
AlfrescoTransactionSupport.bindListener(fPurgeStoreTxnListener);
|
||||||
|
AlfrescoTransactionSupport.bindListener(fCreateStoreTxnListener);
|
||||||
AVMStore store = getAVMStoreByName(sourceName);
|
AVMStore store = getAVMStoreByName(sourceName);
|
||||||
if (store == null)
|
if (store == null)
|
||||||
{
|
{
|
||||||
@@ -2295,5 +2327,7 @@ public class AVMRepository
|
|||||||
store.setName(destName);
|
store.setName(destName);
|
||||||
fLookupCache.onDelete(sourceName);
|
fLookupCache.onDelete(sourceName);
|
||||||
AVMDAOs.Instance().fAVMStoreDAO.invalidateCache();
|
AVMDAOs.Instance().fAVMStoreDAO.invalidateCache();
|
||||||
|
fPurgeStoreTxnListener.storePurged(sourceName);
|
||||||
|
fCreateStoreTxnListener.storeCreated(destName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -75,6 +75,46 @@ public class AVMServiceTestBase extends TestCase
|
|||||||
fService = (AVMService)fContext.getBean("AVMService");
|
fService = (AVMService)fContext.getBean("AVMService");
|
||||||
fReaper = (OrphanReaper)fContext.getBean("orphanReaper");
|
fReaper = (OrphanReaper)fContext.getBean("orphanReaper");
|
||||||
fSyncService = (AVMSyncService)fContext.getBean("AVMSyncService");
|
fSyncService = (AVMSyncService)fContext.getBean("AVMSyncService");
|
||||||
|
CreateStoreTxnListener cstl = (CreateStoreTxnListener)fContext.getBean("createStoreTxnListener");
|
||||||
|
cstl.addCallback(
|
||||||
|
new CreateStoreCallback()
|
||||||
|
{
|
||||||
|
public void storeCreated(String name)
|
||||||
|
{
|
||||||
|
System.err.println("Store created: " + name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
PurgeStoreTxnListener pstl = (PurgeStoreTxnListener)fContext.getBean("purgeStoreTxnListener");
|
||||||
|
pstl.addCallback(
|
||||||
|
new PurgeStoreCallback()
|
||||||
|
{
|
||||||
|
public void storePurged(String name)
|
||||||
|
{
|
||||||
|
System.err.println("Store purged: " + name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
CreateVersionTxnListener cvtl = (CreateVersionTxnListener)fContext.getBean("createVersionTxnListener");
|
||||||
|
cvtl.addCallback(
|
||||||
|
new CreateVersionCallback()
|
||||||
|
{
|
||||||
|
public void versionCreated(String name, int versionID)
|
||||||
|
{
|
||||||
|
System.err.println("Version created: " + name + " " + versionID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
PurgeVersionTxnListener pvtl = (PurgeVersionTxnListener)fContext.getBean("purgeVersionTxnListener");
|
||||||
|
pvtl.addCallback(
|
||||||
|
new PurgeVersionCallback()
|
||||||
|
{
|
||||||
|
public void versionPurged(String name, int versionID)
|
||||||
|
{
|
||||||
|
System.err.println("Version purged: " + name + " " + versionID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
fService.createAVMStore("main");
|
fService.createAVMStore("main");
|
||||||
fStartTime = System.currentTimeMillis();
|
fStartTime = System.currentTimeMillis();
|
||||||
|
18
source/java/org/alfresco/repo/avm/CreateStoreCallback.java
Normal file
18
source/java/org/alfresco/repo/avm/CreateStoreCallback.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.avm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for listeners to new store events.
|
||||||
|
* @author britt
|
||||||
|
*/
|
||||||
|
public interface CreateStoreCallback
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A new store has been created.
|
||||||
|
* @param storeName The name of the new store.
|
||||||
|
*/
|
||||||
|
public void storeCreated(String storeName);
|
||||||
|
}
|
||||||
|
|
@@ -0,0 +1,89 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.avm;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.alfresco.repo.transaction.TransactionListenerAdapter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transaction listener for firing create store events.
|
||||||
|
* @author britt
|
||||||
|
*/
|
||||||
|
public class CreateStoreTxnListener extends TransactionListenerAdapter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Storage for stores created in a transaction.
|
||||||
|
*/
|
||||||
|
private ThreadLocal<List<String>> fCreatedStores;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callbacks to invoke on commit.
|
||||||
|
*/
|
||||||
|
private List<CreateStoreCallback> fCallbacks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor.
|
||||||
|
*/
|
||||||
|
public CreateStoreTxnListener()
|
||||||
|
{
|
||||||
|
fCreatedStores = new ThreadLocal<List<String>>();
|
||||||
|
fCallbacks = new ArrayList<CreateStoreCallback>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.repo.transaction.TransactionListenerAdapter#afterCommit()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void afterCommit()
|
||||||
|
{
|
||||||
|
List<String> created = fCreatedStores.get();
|
||||||
|
for (String name : created)
|
||||||
|
{
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
for (CreateStoreCallback cb : fCallbacks)
|
||||||
|
{
|
||||||
|
cb.storeCreated(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fCreatedStores.set(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.repo.transaction.TransactionListenerAdapter#afterRollback()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void afterRollback()
|
||||||
|
{
|
||||||
|
fCreatedStores.set(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* During the transaction somebody is responsible for
|
||||||
|
* calling this.
|
||||||
|
* @param storeName The name of the store that has been created.
|
||||||
|
*/
|
||||||
|
public void storeCreated(String storeName)
|
||||||
|
{
|
||||||
|
List<String> created = fCreatedStores.get();
|
||||||
|
if (created == null)
|
||||||
|
{
|
||||||
|
created = new ArrayList<String>();
|
||||||
|
fCreatedStores.set(created);
|
||||||
|
}
|
||||||
|
created.add(storeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a callback.
|
||||||
|
* @param cb The callback.
|
||||||
|
*/
|
||||||
|
public synchronized void addCallback(CreateStoreCallback cb)
|
||||||
|
{
|
||||||
|
fCallbacks.add(cb);
|
||||||
|
}
|
||||||
|
}
|
18
source/java/org/alfresco/repo/avm/CreateVersionCallback.java
Normal file
18
source/java/org/alfresco/repo/avm/CreateVersionCallback.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.avm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback interface for those interested in new version creation.
|
||||||
|
* @author britt
|
||||||
|
*/
|
||||||
|
public interface CreateVersionCallback
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A version of a store has been purged.
|
||||||
|
* @param storeName The name of the store in which a new version has been created.
|
||||||
|
* @param versionID The version id of the new version.
|
||||||
|
*/
|
||||||
|
public void versionCreated(String storeName, int versionID);
|
||||||
|
}
|
@@ -0,0 +1,91 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.avm;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.alfresco.repo.transaction.TransactionListenerAdapter;
|
||||||
|
import org.alfresco.util.Pair;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transaction listener that fires create version events.
|
||||||
|
* @author britt
|
||||||
|
*/
|
||||||
|
public class CreateVersionTxnListener extends TransactionListenerAdapter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Storage for versions created in a transaction.
|
||||||
|
*/
|
||||||
|
private ThreadLocal<List<Pair<String, Integer>>> fCreatedVersions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callbacks to invoke on commit.
|
||||||
|
*/
|
||||||
|
private List<CreateVersionCallback> fCallbacks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor.
|
||||||
|
*/
|
||||||
|
public CreateVersionTxnListener()
|
||||||
|
{
|
||||||
|
fCreatedVersions = new ThreadLocal<List<Pair<String, Integer>>>();
|
||||||
|
fCallbacks = new ArrayList<CreateVersionCallback>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.repo.transaction.TransactionListenerAdapter#afterCommit()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void afterCommit()
|
||||||
|
{
|
||||||
|
List<Pair<String, Integer>> created = fCreatedVersions.get();
|
||||||
|
for (Pair<String, Integer> version : created)
|
||||||
|
{
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
for (CreateVersionCallback cb : fCallbacks)
|
||||||
|
{
|
||||||
|
cb.versionCreated(version.getFirst(), version.getSecond());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fCreatedVersions.set(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.repo.transaction.TransactionListenerAdapter#afterRollback()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void afterRollback()
|
||||||
|
{
|
||||||
|
fCreatedVersions.set(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* During the transaction somebody is responsible for
|
||||||
|
* calling this.
|
||||||
|
* @param storeName The name of the store that just created a new version
|
||||||
|
* @param versionID The id of the new version.
|
||||||
|
*/
|
||||||
|
public void versionCreated(String storeName, int versionID)
|
||||||
|
{
|
||||||
|
List<Pair<String, Integer>> created = fCreatedVersions.get();
|
||||||
|
if (created == null)
|
||||||
|
{
|
||||||
|
created = new ArrayList<Pair<String, Integer>>();
|
||||||
|
fCreatedVersions.set(created);
|
||||||
|
}
|
||||||
|
created.add(new Pair<String, Integer>(storeName, versionID));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a callback.
|
||||||
|
* @param cb The callback.
|
||||||
|
*/
|
||||||
|
public synchronized void addCallback(CreateVersionCallback cb)
|
||||||
|
{
|
||||||
|
fCallbacks.add(cb);
|
||||||
|
}
|
||||||
|
}
|
@@ -20,7 +20,6 @@ package org.alfresco.repo.avm;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.alfresco.repo.avm.util.RawServices;
|
|
||||||
import org.alfresco.repo.domain.DbAccessControlList;
|
import org.alfresco.repo.domain.DbAccessControlList;
|
||||||
import org.alfresco.repo.transaction.TransactionUtil;
|
import org.alfresco.repo.transaction.TransactionUtil;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
|
17
source/java/org/alfresco/repo/avm/PurgeStoreCallback.java
Normal file
17
source/java/org/alfresco/repo/avm/PurgeStoreCallback.java
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.avm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback interface for those interested in store purges.
|
||||||
|
* @author britt
|
||||||
|
*/
|
||||||
|
public interface PurgeStoreCallback
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A store has been purged.
|
||||||
|
* @param storeName The name of the purged store.
|
||||||
|
*/
|
||||||
|
public void storePurged(String storeName);
|
||||||
|
}
|
89
source/java/org/alfresco/repo/avm/PurgeStoreTxnListener.java
Normal file
89
source/java/org/alfresco/repo/avm/PurgeStoreTxnListener.java
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.avm;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.alfresco.repo.transaction.TransactionListenerAdapter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transaction listener for firing purge store events.
|
||||||
|
* @author britt
|
||||||
|
*/
|
||||||
|
public class PurgeStoreTxnListener extends TransactionListenerAdapter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Storage for stores purged in a transaction.
|
||||||
|
*/
|
||||||
|
private ThreadLocal<List<String>> fPurgedStores;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callbacks to invoke on commit.
|
||||||
|
*/
|
||||||
|
private List<PurgeStoreCallback> fCallbacks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor.
|
||||||
|
*/
|
||||||
|
public PurgeStoreTxnListener()
|
||||||
|
{
|
||||||
|
fPurgedStores = new ThreadLocal<List<String>>();
|
||||||
|
fCallbacks = new ArrayList<PurgeStoreCallback>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.repo.transaction.TransactionListenerAdapter#afterCommit()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void afterCommit()
|
||||||
|
{
|
||||||
|
List<String> created = fPurgedStores.get();
|
||||||
|
for (String name : created)
|
||||||
|
{
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
for (PurgeStoreCallback cb : fCallbacks)
|
||||||
|
{
|
||||||
|
cb.storePurged(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fPurgedStores.set(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.repo.transaction.TransactionListenerAdapter#afterRollback()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void afterRollback()
|
||||||
|
{
|
||||||
|
fPurgedStores.set(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* During the transaction somebody is responsible for
|
||||||
|
* calling this.
|
||||||
|
* @param storeName The name of the store that has been purged.
|
||||||
|
*/
|
||||||
|
public void storePurged(String storeName)
|
||||||
|
{
|
||||||
|
List<String> purged = fPurgedStores.get();
|
||||||
|
if (purged == null)
|
||||||
|
{
|
||||||
|
purged = new ArrayList<String>();
|
||||||
|
fPurgedStores.set(purged);
|
||||||
|
}
|
||||||
|
purged.add(storeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a callback.
|
||||||
|
* @param cb The callback.
|
||||||
|
*/
|
||||||
|
public synchronized void addCallback(PurgeStoreCallback cb)
|
||||||
|
{
|
||||||
|
fCallbacks.add(cb);
|
||||||
|
}
|
||||||
|
}
|
@@ -1,141 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2006 Alfresco, Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Mozilla Public License version 1.1
|
|
||||||
* with a permitted attribution clause. You may obtain a
|
|
||||||
* copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.alfresco.org/legal/license.txt
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied. See the License for the specific
|
|
||||||
* language governing permissions and limitations under the
|
|
||||||
* License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.alfresco.repo.avm;
|
|
||||||
|
|
||||||
import org.alfresco.repo.avm.util.BulkLoader;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test the purge thread.
|
|
||||||
* @author britt
|
|
||||||
*/
|
|
||||||
public class PurgeTest extends AVMServiceTestBase
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Test purging a version.
|
|
||||||
*/
|
|
||||||
public void testPurgeVersion()
|
|
||||||
{
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// setupBasicTree();
|
|
||||||
// BulkLoader loader = new BulkLoader();
|
|
||||||
// loader.setAvmService(fService);
|
|
||||||
// long start = System.currentTimeMillis();
|
|
||||||
// loader.recursiveLoad("source/web", "main:/");
|
|
||||||
// System.err.println("Load time: " + (System.currentTimeMillis() - start) + "ms");
|
|
||||||
// fService.createSnapshot("main", null, null);
|
|
||||||
// System.err.println("Load time + snapshot: " + (System.currentTimeMillis() - start) + "ms");
|
|
||||||
// fService.purgeVersion(2, "main");
|
|
||||||
// fReaper.activate();
|
|
||||||
// while (fReaper.isActive())
|
|
||||||
// {
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// Thread.sleep(2000);
|
|
||||||
// }
|
|
||||||
// catch (InterruptedException e)
|
|
||||||
// {
|
|
||||||
// // Do nothing.
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// catch (Exception e)
|
|
||||||
// {
|
|
||||||
// e.printStackTrace(System.err);
|
|
||||||
// fail();
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test purging a version that's not the latest.
|
|
||||||
*/
|
|
||||||
public void testPurgeOlderVersion()
|
|
||||||
{
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// setupBasicTree();
|
|
||||||
// BulkLoader loader = new BulkLoader();
|
|
||||||
// loader.setAvmService(fService);
|
|
||||||
// long start = System.currentTimeMillis();
|
|
||||||
// loader.recursiveLoad("source", "main:/");
|
|
||||||
// System.err.println("Load time: " + (System.currentTimeMillis() - start) + "ms");
|
|
||||||
// fService.createSnapshot("main", null, null);
|
|
||||||
// System.err.println("Load time + snapshot: " + (System.currentTimeMillis() - start) + "ms");
|
|
||||||
// fService.removeNode("main:/source/java/org/alfresco", "repo");
|
|
||||||
// fService.createSnapshot("main", null, null);
|
|
||||||
// fService.purgeVersion(2, "main");
|
|
||||||
// fReaper.activate();
|
|
||||||
// while (fReaper.isActive())
|
|
||||||
// {
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// Thread.sleep(2000);
|
|
||||||
// }
|
|
||||||
// catch (InterruptedException e)
|
|
||||||
// {
|
|
||||||
// // Do nothing.
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// catch (Exception e)
|
|
||||||
// {
|
|
||||||
// e.printStackTrace(System.err);
|
|
||||||
// fail();
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test purging an entire store.
|
|
||||||
*/
|
|
||||||
public void testPurgeStore()
|
|
||||||
{
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// setupBasicTree();
|
|
||||||
// BulkLoader loader = new BulkLoader();
|
|
||||||
// loader.setAvmService(fService);
|
|
||||||
// long start = System.currentTimeMillis();
|
|
||||||
// loader.recursiveLoad("source", "main:/");
|
|
||||||
// System.err.println("Load time: " + (System.currentTimeMillis() - start) + "ms");
|
|
||||||
// fService.createSnapshot("main", null, null);
|
|
||||||
// System.err.println("Load time + snapshot: " + (System.currentTimeMillis() - start) + "ms");
|
|
||||||
// fService.createLayeredDirectory("main:/source", "main:/", "layer");
|
|
||||||
// fService.removeNode("main:/layer/java/org/alfresco", "repo");
|
|
||||||
// fService.createFile("main:/layer/java/org/alfresco", "goofy").close();
|
|
||||||
// fService.createSnapshot("main", null, null);
|
|
||||||
// fService.purgeAVMStore("main");
|
|
||||||
// fReaper.activate();
|
|
||||||
// while (fReaper.isActive())
|
|
||||||
// {
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
// Thread.sleep(2000);
|
|
||||||
// }
|
|
||||||
// catch (InterruptedException e)
|
|
||||||
// {
|
|
||||||
// // Do nothing.
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// catch (Exception e)
|
|
||||||
// {
|
|
||||||
// e.printStackTrace(System.err);
|
|
||||||
// fail();
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
141
source/java/org/alfresco/repo/avm/PurgeTestP.java
Normal file
141
source/java/org/alfresco/repo/avm/PurgeTestP.java
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2006 Alfresco, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Mozilla Public License version 1.1
|
||||||
|
* with a permitted attribution clause. You may obtain a
|
||||||
|
* copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.alfresco.org/legal/license.txt
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||||
|
* either express or implied. See the License for the specific
|
||||||
|
* language governing permissions and limitations under the
|
||||||
|
* License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.alfresco.repo.avm;
|
||||||
|
|
||||||
|
import org.alfresco.repo.avm.util.BulkLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the purge thread.
|
||||||
|
* @author britt
|
||||||
|
*/
|
||||||
|
public class PurgeTestP extends AVMServiceTestBase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Test purging a version.
|
||||||
|
*/
|
||||||
|
public void testPurgeVersion()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
setupBasicTree();
|
||||||
|
BulkLoader loader = new BulkLoader();
|
||||||
|
loader.setAvmService(fService);
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
loader.recursiveLoad("source/web", "main:/");
|
||||||
|
System.err.println("Load time: " + (System.currentTimeMillis() - start) + "ms");
|
||||||
|
fService.createSnapshot("main", null, null);
|
||||||
|
System.err.println("Load time + snapshot: " + (System.currentTimeMillis() - start) + "ms");
|
||||||
|
fService.purgeVersion(2, "main");
|
||||||
|
fReaper.activate();
|
||||||
|
while (fReaper.isActive())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.sleep(2000);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test purging a version that's not the latest.
|
||||||
|
*/
|
||||||
|
public void testPurgeOlderVersion()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
setupBasicTree();
|
||||||
|
BulkLoader loader = new BulkLoader();
|
||||||
|
loader.setAvmService(fService);
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
loader.recursiveLoad("source", "main:/");
|
||||||
|
System.err.println("Load time: " + (System.currentTimeMillis() - start) + "ms");
|
||||||
|
fService.createSnapshot("main", null, null);
|
||||||
|
System.err.println("Load time + snapshot: " + (System.currentTimeMillis() - start) + "ms");
|
||||||
|
fService.removeNode("main:/source/java/org/alfresco", "repo");
|
||||||
|
fService.createSnapshot("main", null, null);
|
||||||
|
fService.purgeVersion(2, "main");
|
||||||
|
fReaper.activate();
|
||||||
|
while (fReaper.isActive())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.sleep(2000);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test purging an entire store.
|
||||||
|
*/
|
||||||
|
public void testPurgeStore()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
setupBasicTree();
|
||||||
|
BulkLoader loader = new BulkLoader();
|
||||||
|
loader.setAvmService(fService);
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
loader.recursiveLoad("source", "main:/");
|
||||||
|
System.err.println("Load time: " + (System.currentTimeMillis() - start) + "ms");
|
||||||
|
fService.createSnapshot("main", null, null);
|
||||||
|
System.err.println("Load time + snapshot: " + (System.currentTimeMillis() - start) + "ms");
|
||||||
|
fService.createLayeredDirectory("main:/source", "main:/", "layer");
|
||||||
|
fService.removeNode("main:/layer/java/org/alfresco", "repo");
|
||||||
|
fService.createFile("main:/layer/java/org/alfresco", "goofy").close();
|
||||||
|
fService.createSnapshot("main", null, null);
|
||||||
|
fService.purgeAVMStore("main");
|
||||||
|
fReaper.activate();
|
||||||
|
while (fReaper.isActive())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.sleep(2000);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
source/java/org/alfresco/repo/avm/PurgeVersionCallback.java
Normal file
18
source/java/org/alfresco/repo/avm/PurgeVersionCallback.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.avm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Callback interface for those interested in versions being purged.
|
||||||
|
* @author britt
|
||||||
|
*/
|
||||||
|
public interface PurgeVersionCallback
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A version was purged from a store.
|
||||||
|
* @param storeName The name of the store from which a version was purged.
|
||||||
|
* @param versionID The id of the purged version.
|
||||||
|
*/
|
||||||
|
public void versionPurged(String storeName, int versionID);
|
||||||
|
}
|
@@ -0,0 +1,91 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.avm;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.alfresco.repo.transaction.TransactionListenerAdapter;
|
||||||
|
import org.alfresco.util.Pair;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transaction listener that fires purge version events.
|
||||||
|
* @author britt
|
||||||
|
*/
|
||||||
|
public class PurgeVersionTxnListener extends TransactionListenerAdapter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Storage for versions purged in a transaction.
|
||||||
|
*/
|
||||||
|
private ThreadLocal<List<Pair<String, Integer>>> fPurgedVersions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callbacks to invoke on commit.
|
||||||
|
*/
|
||||||
|
private List<PurgeVersionCallback> fCallbacks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor.
|
||||||
|
*/
|
||||||
|
public PurgeVersionTxnListener()
|
||||||
|
{
|
||||||
|
fPurgedVersions = new ThreadLocal<List<Pair<String, Integer>>>();
|
||||||
|
fCallbacks = new ArrayList<PurgeVersionCallback>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.repo.transaction.TransactionListenerAdapter#afterCommit()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void afterCommit()
|
||||||
|
{
|
||||||
|
List<Pair<String, Integer>> created = fPurgedVersions.get();
|
||||||
|
for (Pair<String, Integer> version : created)
|
||||||
|
{
|
||||||
|
synchronized (this)
|
||||||
|
{
|
||||||
|
for (PurgeVersionCallback cb : fCallbacks)
|
||||||
|
{
|
||||||
|
cb.versionPurged(version.getFirst(), version.getSecond());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fPurgedVersions.set(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.repo.transaction.TransactionListenerAdapter#afterRollback()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void afterRollback()
|
||||||
|
{
|
||||||
|
fPurgedVersions.set(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* During the transaction somebody is responsible for
|
||||||
|
* calling this.
|
||||||
|
* @param storeName The name of the store that just created a new version
|
||||||
|
* @param versionID The id of the new version.
|
||||||
|
*/
|
||||||
|
public void versionPurged(String storeName, int versionID)
|
||||||
|
{
|
||||||
|
List<Pair<String, Integer>> purged = fPurgedVersions.get();
|
||||||
|
if (purged == null)
|
||||||
|
{
|
||||||
|
purged = new ArrayList<Pair<String, Integer>>();
|
||||||
|
fPurgedVersions.set(purged);
|
||||||
|
}
|
||||||
|
purged.add(new Pair<String, Integer>(storeName, versionID));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a callback.
|
||||||
|
* @param cb The callback.
|
||||||
|
*/
|
||||||
|
public synchronized void addCallback(PurgeVersionCallback cb)
|
||||||
|
{
|
||||||
|
fCallbacks.add(cb);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user