diff --git a/config/alfresco/extension/replicating-content-services-context.xml.sample b/config/alfresco/extension/replicating-content-services-context.xml.sample
index 94ed1270cb..50dfd42992 100644
--- a/config/alfresco/extension/replicating-content-services-context.xml.sample
+++ b/config/alfresco/extension/replicating-content-services-context.xml.sample
@@ -11,29 +11,44 @@
- s:/backups/alfresco
+ ${dir.contentstore}/../backups/alfresco
-
+ depends-on="fileContentStore, backupContentStore" >
- fileContentStore
+
- backupContentStore
+
-
-
- true
+
+
+
+
+
+
+ org.alfresco.repo.content.replication.ContentStoreReplicator$ContentStoreReplicatorJob
+
+
+
+
+
-
-
- 60
+
+
+
+
+
+ 0 0 03 * * ?
diff --git a/source/java/org/alfresco/repo/content/replication/ContentStoreReplicator.java b/source/java/org/alfresco/repo/content/replication/ContentStoreReplicator.java
index 34df7f6bdb..63f131fb95 100644
--- a/source/java/org/alfresco/repo/content/replication/ContentStoreReplicator.java
+++ b/source/java/org/alfresco/repo/content/replication/ContentStoreReplicator.java
@@ -18,7 +18,6 @@ package org.alfresco.repo.content.replication;
import java.util.Set;
-import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.content.ContentStore;
import org.alfresco.repo.node.index.IndexRecovery;
import org.alfresco.service.cmr.repository.ContentReader;
@@ -48,18 +47,12 @@ public class ContentStoreReplicator
private ContentStore sourceStore;
private ContentStore targetStore;
- /** used to ensure that this instance gets started once only */
- private boolean started;
- /** set this on to keep replicating and never stop. The default is true
. */
- private boolean runContinuously;
- /** the time to wait between passes */
- private long waitTime;
+ /** used to ensure that the threads don't queue up on this component */
+ private boolean busy;
public ContentStoreReplicator()
{
- this.started = false;
- this.runContinuously = true;
- this.waitTime = 60000L;
+ this.busy = false;
}
/**
@@ -83,43 +76,44 @@ public class ContentStoreReplicator
}
/**
- * Set whether the thread should run continuously or terminate after
- * a first pass.
- *
- * @param runContinuously true to run continously (default)
+ * @deprecated use the {@link ContentStoreReplicatorJob job} to trigger
*/
public void setRunContinuously(boolean runContinuously)
{
- this.runContinuously = runContinuously;
+ logger.warn(
+ "Property 'runContinuously' has been deprecated.\n" +
+ " Use the " + ContentStoreReplicatorJob.class.getName() + " to trigger");
}
/**
- * Set the time to wait between replication passes (in seconds)
- *
- * @param waitTime the time between passes (in seconds). Default is 60s.
+ * @deprecated use the {@link ContentStoreReplicatorJob job} to trigger
*/
public void setWaitTime(long waitTime)
{
- // convert to millis
- this.waitTime = waitTime * 1000L;
+ logger.warn(
+ "Property 'runContinuously' has been deprecated.\n" +
+ " Use the " + ContentStoreReplicatorJob.class.getName() + " to trigger");
}
/**
- * Kick off the replication thread. This method can be used once.
+ * Kick off the replication thread. If one is already busy, then this method does
+ * nothing.
*/
public synchronized void start()
{
- if (started)
+ if (busy)
{
- throw new AlfrescoRuntimeException("This ContentStoreReplicator has already been started");
+ return;
}
// create a low-priority, daemon thread to do the work
Runnable runnable = new ReplicationRunner();
Thread thread = new Thread(runnable);
+ thread.setName("ContentStoreReplicator");
thread.setPriority(Thread.MIN_PRIORITY);
thread.setDaemon(true);
// start it
thread.start();
+ busy = true;
}
/**
@@ -131,38 +125,18 @@ public class ContentStoreReplicator
{
public void run()
{
- // keep this thread going permanently
- while (true)
+ try
{
- try
- {
- ContentStoreReplicator.this.replicate();
- // check if the process should terminate
- if (!runContinuously)
- {
- // the thread has caught up with all the available work and should not
- // run continuously
- if (logger.isDebugEnabled())
- {
- logger.debug("Thread quitting - first pass of replication complete:");
- }
- break;
- }
- // pause the the required wait time
- synchronized(ContentStoreReplicator.this)
- {
- ContentStoreReplicator.this.wait(waitTime);
- }
- }
- catch (InterruptedException e)
- {
- // ignore
- }
- catch (Throwable e)
- {
- // report
- logger.error("Replication failure", e);
- }
+ ContentStoreReplicator.this.replicate();
+ }
+ catch (Throwable e)
+ {
+ // report
+ logger.error("Replication failure", e);
+ }
+ finally
+ {
+ busy = false;
}
}
}
@@ -246,7 +220,7 @@ public class ContentStoreReplicator
*
* @author Derek Hulley
*/
- public class ContentStoreReplicatorJob implements Job
+ public static class ContentStoreReplicatorJob implements Job
{
/** KEY_CONTENT_STORE_REPLICATOR = 'contentStoreReplicator' */
public static final String KEY_CONTENT_STORE_REPLICATOR = "contentStoreReplicator";
diff --git a/source/java/org/alfresco/repo/content/replication/ContentStoreReplicatorTest.java b/source/java/org/alfresco/repo/content/replication/ContentStoreReplicatorTest.java
index a3b5cd9cf5..7399da06c8 100644
--- a/source/java/org/alfresco/repo/content/replication/ContentStoreReplicatorTest.java
+++ b/source/java/org/alfresco/repo/content/replication/ContentStoreReplicatorTest.java
@@ -61,8 +61,6 @@ public class ContentStoreReplicatorTest extends TestCase
replicator = new ContentStoreReplicator();
replicator.setSourceStore(sourceStore);
replicator.setTargetStore(targetStore);
- replicator.setRunContinuously(false); // replicate once
- replicator.setWaitTime(0);
}
/**
@@ -111,8 +109,6 @@ public class ContentStoreReplicatorTest extends TestCase
*/
public void testContinuousReplication() throws Exception
{
- replicator.setRunContinuously(true);
- replicator.setWaitTime(0L);
replicator.start();
String duplicateUrl = AbstractContentStore.createNewUrl();
@@ -150,4 +146,15 @@ public class ContentStoreReplicatorTest extends TestCase
sourceUrls.containsAll(targetUrls);
targetUrls.contains(sourceUrls);
}
+
+ /**
+ * Call the replicator repeatedly to check that it prevents concurrent use
+ */
+ public void testRepeatedReplication() throws Exception
+ {
+ for (int i = 0; i < 10; i++)
+ {
+ replicator.start();
+ }
+ }
}