diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java index f45e2b13c..e08a9d7b3 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AbstractTracker.java @@ -69,6 +69,7 @@ public abstract class AbstractTracker implements Tracker protected boolean transformContent; protected String shardTemplate; protected volatile boolean rollback; + protected final Type type; /* @@ -82,11 +83,12 @@ public abstract class AbstractTracker implements Tracker /** * Default constructor, strictly for testing. */ - protected AbstractTracker() + protected AbstractTracker(Type type) { + this.type = type; } - protected AbstractTracker(Properties p, SOLRAPIClient client, String coreName, InformationServer informationServer) + protected AbstractTracker(Properties p, SOLRAPIClient client, String coreName, InformationServer informationServer,Type type) { this.props = p; this.client = client; @@ -110,6 +112,9 @@ public abstract class AbstractTracker implements Tracker this.trackerStats = this.infoSrv.getTrackerStats(); alfrescoVersion = p.getProperty("alfresco.version", "5.0.0"); + + this.type = type; + log.info("Solr built for Alfresco version: " + alfrescoVersion); } @@ -310,6 +315,11 @@ public abstract class AbstractTracker implements Tracker { return props; } + + public Type getType() + { + return type; + } } diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AclTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AclTracker.java index 1f2118be3..ac16758d1 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AclTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/AclTracker.java @@ -75,13 +75,13 @@ public class AclTracker extends AbstractTracker */ AclTracker() { - super(); + super(Tracker.Type.ACL); } public AclTracker(Properties p, SOLRAPIClient client, String coreName, InformationServer informationServer) { - super(p, client, coreName, informationServer); + super(p, client, coreName, informationServer, Tracker.Type.ACL); changeSetAclsBatchSize = Integer.parseInt(p.getProperty("alfresco.changeSetAclsBatchSize", "100")); aclBatchSize = Integer.parseInt(p.getProperty("alfresco.aclBatchSize", "10")); shardMethod = p.getProperty("shard.method", SHARD_METHOD_DBID); diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CascadeTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CascadeTracker.java index 3dac07080..ca151a5b1 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CascadeTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CascadeTracker.java @@ -19,22 +19,18 @@ package org.alfresco.solr.tracker; import java.io.IOException; -import java.util.*; -import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; +import java.util.Set; -import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.httpclient.AuthenticationException; -import org.alfresco.repo.index.shard.ShardMethodEnum; -import org.alfresco.repo.index.shard.ShardState; -import org.alfresco.repo.index.shard.ShardStateBuilder; -import org.alfresco.solr.AlfrescoSolrDataModel; -import org.alfresco.solr.BoundedDeque; import org.alfresco.solr.InformationServer; -import org.alfresco.solr.NodeReport; -import org.alfresco.solr.TrackerState; -import org.alfresco.solr.adapters.IOpenBitSet; -import org.alfresco.solr.client.*; -import org.alfresco.solr.client.Node.SolrApiNodeStatus; +import org.alfresco.solr.client.NodeMetaData; +import org.alfresco.solr.client.SOLRAPIClient; +import org.alfresco.solr.client.Transaction; import org.apache.commons.codec.EncoderException; import org.json.JSONException; import org.slf4j.Logger; @@ -54,14 +50,14 @@ public class CascadeTracker extends AbstractTracker implements Tracker public CascadeTracker(Properties p, SOLRAPIClient client, String coreName, InformationServer informationServer) { - super(p, client, coreName, informationServer); + super(p, client, coreName, informationServer, Tracker.Type.Cascade); threadHandler = new ThreadHandler(p, coreName, "CascadeTracker"); } CascadeTracker() { - // Testing purposes only + super(Tracker.Type.Cascade); } @Override diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CommitTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CommitTracker.java index 185cb9ab7..b1569502b 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CommitTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/CommitTracker.java @@ -21,9 +21,7 @@ package org.alfresco.solr.tracker; import java.util.List; import java.util.Properties; -import java.util.concurrent.Semaphore; import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; import org.alfresco.solr.InformationServer; import org.alfresco.solr.client.SOLRAPIClient; @@ -53,7 +51,7 @@ public class CommitTracker extends AbstractTracker **/ CommitTracker() { - super(); + super(Tracker.Type.Commit); } public CommitTracker(Properties p, @@ -62,7 +60,7 @@ public class CommitTracker extends AbstractTracker InformationServer informationServer, List trackers) { - super(p, client, coreName, informationServer); + super(p, client, coreName, informationServer, Tracker.Type.Commit); //Set the trackers for(Tracker tracker : trackers) { diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ContentTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ContentTracker.java index eba54c27b..28b4fc698 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ContentTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ContentTracker.java @@ -21,9 +21,6 @@ import java.io.IOException; import java.util.List; import java.util.Properties; -import java.util.Set; -import java.util.WeakHashMap; -import java.util.concurrent.Semaphore; import org.alfresco.solr.AlfrescoSolrDataModel.TenantAclIdDbId; import org.alfresco.solr.InformationServer; @@ -48,7 +45,7 @@ public class ContentTracker extends AbstractTracker implements Tracker public ContentTracker(Properties p, SOLRAPIClient client, String coreName, InformationServer informationServer) { - super(p, client, coreName, informationServer); + super(p, client, coreName, informationServer, Tracker.Type.Content); contentReadBatchSize = Integer.parseInt(p.getProperty("alfresco.contentReadBatchSize", "100")); contentUpdateBatchSize = Integer.parseInt(p.getProperty("alfresco.contentUpdateBatchSize", "1000")); threadHandler = new ThreadHandler(p, coreName, "ContentTracker"); @@ -56,7 +53,7 @@ public class ContentTracker extends AbstractTracker implements Tracker ContentTracker() { - // Testing purposes only + super(Tracker.Type.Content); } @Override diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java index 3dc6ec74b..253bc2559 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/MetadataTracker.java @@ -19,7 +19,12 @@ package org.alfresco.solr.tracker; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Properties; +import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; import org.alfresco.error.AlfrescoRuntimeException; @@ -62,7 +67,6 @@ public class MetadataTracker extends AbstractTracker implements Tracker private static final int DEFAULT_NODE_BATCH_SIZE = 10; private int transactionDocsBatchSize = DEFAULT_TRANSACTION_DOCS_BATCH_SIZE; private int nodeBatchSize = DEFAULT_NODE_BATCH_SIZE; - private int maxTransactionDocumentIdCacheSize = 700000; private ConcurrentLinkedQueue transactionsToReindex = new ConcurrentLinkedQueue(); private ConcurrentLinkedQueue transactionsToIndex = new ConcurrentLinkedQueue(); private ConcurrentLinkedQueue transactionsToPurge = new ConcurrentLinkedQueue(); @@ -76,7 +80,7 @@ public class MetadataTracker extends AbstractTracker implements Tracker public MetadataTracker(Properties p, SOLRAPIClient client, String coreName, InformationServer informationServer) { - super(p, client, coreName, informationServer); + super(p, client, coreName, informationServer, Tracker.Type.MetaData); //System.out.println("####### MetadatTracker() ########"); transactionDocsBatchSize = Integer.parseInt(p.getProperty("alfresco.transactionDocsBatchSize", "100")); shardMethod = p.getProperty("shard.method", SHARD_METHOD_DBID); @@ -92,7 +96,7 @@ public class MetadataTracker extends AbstractTracker implements Tracker MetadataTracker() { - // Testing purposes only + super(Tracker.Type.MetaData); } @Override diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ModelTracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ModelTracker.java index 8d0b399ca..07b75c6d5 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ModelTracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/ModelTracker.java @@ -32,11 +32,6 @@ import java.util.Properties; import java.util.Set; import java.util.concurrent.locks.ReentrantReadWriteLock; -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; -import javax.naming.NoInitialContextException; - import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.httpclient.AuthenticationException; import org.alfresco.repo.dictionary.M2Model; @@ -108,7 +103,7 @@ public class ModelTracker extends AbstractTracker implements Tracker public ModelTracker(String solrHome, Properties p, SOLRAPIClient client, String coreName, InformationServer informationServer) { - super(p, client, coreName, informationServer); + super(p, client, coreName, informationServer, Tracker.Type.Model); String normalSolrHome = SolrResourceLoader.normalizeDir(solrHome); alfrescoModelDir = new File(ConfigUtil.locateProperty("solr.model.dir", normalSolrHome+"alfrescoModels")); log.info("Alfresco Model dir " + alfrescoModelDir); @@ -192,7 +187,7 @@ public class ModelTracker extends AbstractTracker implements Tracker */ ModelTracker() { - // Testing purposes only + super(Tracker.Type.Model); } @Override diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SolrTrackerScheduler.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SolrTrackerScheduler.java index 016e3b422..77801a3f5 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SolrTrackerScheduler.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/SolrTrackerScheduler.java @@ -73,7 +73,14 @@ public class SolrTrackerScheduler { log.error("Failed to schedule " + jobType + " Job.", e); } - + /** + * Schedules individual trackers based on the solrcore properties. + * + * @author Michael Suzuki + * @param tracker + * @param coreName + * @param props + */ public void schedule(Tracker tracker, String coreName, Properties props) { String jobName = this.getJobName(tracker, coreName); @@ -85,27 +92,29 @@ public class SolrTrackerScheduler try { String cron = null; - if(tracker instanceof AclTracker) + switch (tracker.getType()) { + case ACL: cron = props.getProperty("alfresco.acl.tracker.cron", DEFAULT_CRON); - } - if(tracker instanceof ContentTracker) - { + break; + case Model: + cron = props.getProperty("alfresco.model.tracker.cron", DEFAULT_CRON); + break; + case Content: cron = props.getProperty("alfresco.content.tracker.cron", DEFAULT_CRON); - } - if(tracker instanceof MetadataTracker) - { + break; + case MetaData: cron = props.getProperty("alfresco.metadata.tracker.cron", DEFAULT_CRON); - } - if(tracker instanceof CascadeTracker) - { + break; + case Cascade: cron = props.getProperty("alfresco.cascade.tracker.cron", DEFAULT_CRON); - } - if(tracker instanceof CommitTracker) - { + break; + case Commit: cron = props.getProperty("alfresco.commit.tracker.cron", DEFAULT_CRON); + break; + default: props.getProperty(DEFAULT_CRON); + break; } - cron = cron == null ? DEFAULT_CRON : cron; trigger = new CronTrigger(jobName, SOLR_JOB_GROUP, cron); log.info("Scheduling job " + jobName); scheduler.scheduleJob(job, trigger); diff --git a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/Tracker.java b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/Tracker.java index 522d363d5..194bd1867 100644 --- a/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/Tracker.java +++ b/search-services/alfresco-search/src/main/java/org/alfresco/solr/tracker/Tracker.java @@ -48,4 +48,15 @@ public interface Tracker void invalidateState(); TrackerState getTrackerState(); + + Type getType(); + + enum Type{ + Model, + Content, + ACL, + Cascade, + Commit, + MetaData + } } diff --git a/search-services/alfresco-search/src/main/resources/solr/instance/templates/rerank/conf/solrcore.properties b/search-services/alfresco-search/src/main/resources/solr/instance/templates/rerank/conf/solrcore.properties index 5217a9205..d77ded20e 100644 --- a/search-services/alfresco-search/src/main/resources/solr/instance/templates/rerank/conf/solrcore.properties +++ b/search-services/alfresco-search/src/main/resources/solr/instance/templates/rerank/conf/solrcore.properties @@ -64,7 +64,7 @@ alfresco.content.tracker.cron=0/15 * * * * ? * alfresco.metadata.tracker.cron=0/15 * * * * ? * alfresco.cascade.tracker.cron=0/15 * * * * ? * alfresco.commit.tracker.cron=0/15 * * * * ? * - +alfresco.model.tracker.cron=0/15 * * * * ? * alfresco.commitInterval=2000 alfresco.newSearcherInterval=3000 diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ContentTrackerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ContentTrackerTest.java index 8d51db4d2..a2e74acfb 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ContentTrackerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/ContentTrackerTest.java @@ -27,6 +27,7 @@ import java.util.Properties; import org.alfresco.solr.AlfrescoSolrDataModel.TenantAclIdDbId; import org.alfresco.solr.SolrInformationServer; import org.alfresco.solr.client.SOLRAPIClient; +import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -133,4 +134,10 @@ public class ContentTrackerTest order.verify(srv).getDocsWithUncleanContent(0 + READ_BATCH + READ_BATCH, READ_BATCH); } + @Test + public void typeCheck() + { + Assert.assertTrue(contentTracker.getType().equals(Tracker.Type.Content)); + } + } diff --git a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/SolrTrackerSchedulerTest.java b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/SolrTrackerSchedulerTest.java index 7b5d92bd4..4a52146a6 100644 --- a/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/SolrTrackerSchedulerTest.java +++ b/search-services/alfresco-search/src/test/java/org/alfresco/solr/tracker/SolrTrackerSchedulerTest.java @@ -33,7 +33,10 @@ import static org.mockito.Mockito.when; import java.util.Arrays; import java.util.Properties; +import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.solr.AlfrescoCoreAdminHandler; +import org.alfresco.solr.InformationServer; +import org.alfresco.solr.client.SOLRAPIClient; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -53,29 +56,33 @@ public class SolrTrackerSchedulerTest { @Mock private AlfrescoCoreAdminHandler adminHandler; - @Mock - private ModelTracker modelTracker; - @Mock - private ContentTracker contentTracker; - @Mock - private MetadataTracker metadataTracker; - @Mock - private AclTracker aclTracker; - @Mock - private CascadeTracker cascadeTracker; - @Mock - private CascadeTracker cascadeTrackerScheduled; - private SolrTrackerScheduler trackerScheduler; private String CORE_NAME = "coreName"; private Scheduler spiedQuartzScheduler; - + @Mock + SOLRAPIClient client; + String coreName = "alfresco"; + @Mock + InformationServer informationServer; + Properties props; @Before public void setUp() throws Exception { this.trackerScheduler = new SolrTrackerScheduler(adminHandler); this.spiedQuartzScheduler = spy(this.trackerScheduler.scheduler); this.trackerScheduler.scheduler = spiedQuartzScheduler; + props = new Properties(); + props.put("alfresco.stores", "workspace://SpacesStore"); + props.put("alfresco.batch.count", "5000"); + props.put("alfresco.maxLiveSearchers", "2"); + props.put("enable.slave", "false"); + props.put("enable.master", "true"); + props.put("shard.count", "1"); + props.put("shard.instance", "0"); + props.put("shard.method", "SHARD_METHOD_DBID"); + props.put("alfresco.template", ""); + props.put("alfresco.index.transformContent", "true"); + props.put("alfresco.version", "5.0.0"); } @After @@ -91,8 +98,8 @@ public class SolrTrackerSchedulerTest public void testAclSchedule() throws SchedulerException { String exp = "0/12 * * * * ? *"; - Properties props = mock(Properties.class); - when(props.getProperty("alfresco.acl.tracker.cron", "0/15 * * * * ? *")).thenReturn(exp); + props.put("alfresco.acl.tracker.cron", exp); + AclTracker aclTracker = new AclTracker(props, client, coreName, informationServer); this.trackerScheduler.schedule(aclTracker, CORE_NAME, props); verify(spiedQuartzScheduler).scheduleJob(any(JobDetail.class), any(Trigger.class)); checkCronExpression(exp); @@ -100,15 +107,14 @@ public class SolrTrackerSchedulerTest @Test public void testContentTrackerSchedule() throws SchedulerException { - Properties props = mock(Properties.class); String exp = "0/5 * * * * ? *"; - when(props.getProperty("alfresco.content.tracker.cron", "0/15 * * * * ? *")).thenReturn(exp); + props.put("alfresco.content.tracker.cron", exp); + ContentTracker contentTracker = new ContentTracker(props, client, coreName, informationServer); this.trackerScheduler.schedule(contentTracker, CORE_NAME, props); verify(spiedQuartzScheduler).scheduleJob(any(JobDetail.class), any(Trigger.class)); - //loop all jobs by groupname checkCronExpression(exp); - } + private void checkCronExpression(String exp) throws SchedulerException { for (String jobName : this.trackerScheduler.scheduler.getJobNames(SolrTrackerScheduler.SOLR_JOB_GROUP)) @@ -123,8 +129,8 @@ public class SolrTrackerSchedulerTest public void testMetaDataTrackerSchedule() throws SchedulerException { String exp = "0/4 * * * * ? *"; - Properties props = mock(Properties.class); - when(props.getProperty("alfresco.metadata.tracker.cron", "0/15 * * * * ? *")).thenReturn(exp); + props.put("alfresco.metadata.tracker.cron", exp); + MetadataTracker metadataTracker = new MetadataTracker(props, client, exp, informationServer); this.trackerScheduler.schedule(metadataTracker, CORE_NAME, props); verify(spiedQuartzScheduler).scheduleJob(any(JobDetail.class), any(Trigger.class)); checkCronExpression(exp); @@ -133,8 +139,8 @@ public class SolrTrackerSchedulerTest public void testSchedule() throws SchedulerException { String exp = "0/1 * * * * ? *"; - Properties props = mock(Properties.class); - when(props.getProperty("alfresco.cascade.tracker.cron", "0/15 * * * * ? *")).thenReturn(exp); + props.put("alfresco.cascade.tracker.cron",exp); + CascadeTracker cascadeTracker = new CascadeTracker(props, client, exp, informationServer); this.trackerScheduler.schedule(cascadeTracker, CORE_NAME, props); verify(spiedQuartzScheduler).scheduleJob(any(JobDetail.class), any(Trigger.class)); checkCronExpression(exp); @@ -149,6 +155,9 @@ public class SolrTrackerSchedulerTest @Test public void testDeleteTrackerJobs() throws SchedulerException { + ContentTracker contentTracker = new ContentTracker(); + MetadataTracker metadataTracker = new MetadataTracker(); + AclTracker aclTracker = new AclTracker(); this.trackerScheduler.deleteTrackerJobs(CORE_NAME, Arrays.asList(new Tracker[] { contentTracker, metadataTracker, aclTracker })); verify(spiedQuartzScheduler, times(3)).deleteJob(anyString(), eq(SolrTrackerScheduler.SOLR_JOB_GROUP)); @@ -157,6 +166,7 @@ public class SolrTrackerSchedulerTest @Test public void testDeleteTrackerJob() throws SchedulerException { + ModelTracker modelTracker = new ModelTracker(); this.trackerScheduler.deleteTrackerJob(CORE_NAME, modelTracker); verify(spiedQuartzScheduler).deleteJob(anyString(), eq(SolrTrackerScheduler.SOLR_JOB_GROUP)); } @@ -164,16 +174,16 @@ public class SolrTrackerSchedulerTest @Test public void testDeleteTrackerInstanceJob() throws SchedulerException { - Properties props = mock(Properties.class); - when(props.getProperty("alfresco.cascade.tracker.cron", "0/15 * * * * ? *")).thenReturn("0/15 * * * * ? *"); - this.trackerScheduler.schedule(cascadeTrackerScheduled, CORE_NAME, props); + CascadeTracker cascadeTracker = new CascadeTracker(props, client, coreName, informationServer); + CascadeTracker cascadeTracker2 = new CascadeTracker(props, client, coreName, informationServer); + this.trackerScheduler.schedule(cascadeTracker, CORE_NAME, props); //Try deleting the same class but a different instance. It not possible. - this.trackerScheduler.deleteJobForTrackerInstance(CORE_NAME, cascadeTracker); + this.trackerScheduler.deleteJobForTrackerInstance(CORE_NAME, cascadeTracker2); verify(spiedQuartzScheduler, never()).deleteJob(anyString(), eq(SolrTrackerScheduler.SOLR_JOB_GROUP)); //No try deleting the exact instance of the tracker class - this.trackerScheduler.deleteJobForTrackerInstance(CORE_NAME, cascadeTrackerScheduled); + this.trackerScheduler.deleteJobForTrackerInstance(CORE_NAME, cascadeTracker); verify(spiedQuartzScheduler, times(1)).deleteJob(anyString(), eq(SolrTrackerScheduler.SOLR_JOB_GROUP)); } @@ -190,5 +200,15 @@ public class SolrTrackerSchedulerTest this.trackerScheduler.pauseAll(); verify(this.spiedQuartzScheduler).pauseAll(); } + @Test + public void testModeltTrackerSchedule() throws SchedulerException + { + String exp = "0/20 * * * * ? *"; + props.put("alfresco.model.tracker.cron", exp); + ModelTracker modelTracker = new ModelTracker("alfresco", props, client, CORE_NAME, informationServer); + this.trackerScheduler.schedule(modelTracker, CORE_NAME, props); + verify(spiedQuartzScheduler).scheduleJob(any(JobDetail.class), any(Trigger.class)); + checkCronExpression(exp); + } }