aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdwin L. Punzalan <epunzalan@apache.org>2006-10-25 03:18:54 +0000
committerEdwin L. Punzalan <epunzalan@apache.org>2006-10-25 03:18:54 +0000
commitc15a3f3ec59e823f0fbe86f9ed7510d0ad03dcd5 (patch)
tree943a2ccefe62683dc54876630df4aed48ed20b51
parentadce668c68d9cc20fb6240b9f3c461876e0e431f (diff)
downloadarchiva-c15a3f3ec59e823f0fbe86f9ed7510d0ad03dcd5.tar.gz
archiva-c15a3f3ec59e823f0fbe86f9ed7510d0ad03dcd5.zip
PR: MRM-139
enabled use of plexus-taskqueue in addition to the scheduler. The scheduler now queues the tasks. git-svn-id: https://svn.apache.org/repos/asf/maven/archiva/trunk@467546 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--archiva-core/pom.xml5
-rw-r--r--archiva-core/src/main/java/org/apache/maven/archiva/scheduler/DefaultRepositoryTaskScheduler.java93
-rw-r--r--archiva-core/src/main/java/org/apache/maven/archiva/scheduler/RepositoryTaskJob.java16
-rw-r--r--archiva-core/src/main/java/org/apache/maven/archiva/scheduler/executors/IndexerTaskExecutor.java320
-rw-r--r--archiva-core/src/main/java/org/apache/maven/archiva/scheduler/task/IndexerTask.java282
-rw-r--r--archiva-core/src/main/java/org/apache/maven/archiva/scheduler/task/RepositoryTask.java2
-rw-r--r--archiva-core/src/main/resources/META-INF/plexus/components.xml40
-rw-r--r--archiva-webapp/src/main/resources/META-INF/plexus/application.xml4
8 files changed, 467 insertions, 295 deletions
diff --git a/archiva-core/pom.xml b/archiva-core/pom.xml
index 8862ab6b3..78e4b9384 100644
--- a/archiva-core/pom.xml
+++ b/archiva-core/pom.xml
@@ -34,6 +34,11 @@
<artifactId>plexus-quartz</artifactId>
<version>1.0-alpha-2</version>
</dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-taskqueue</artifactId>
+ <version>1.0-alpha-4-SNAPSHOT</version>
+ </dependency>
</dependencies>
<build>
<plugins>
diff --git a/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/DefaultRepositoryTaskScheduler.java b/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/DefaultRepositoryTaskScheduler.java
index bee12f078..4724fedc6 100644
--- a/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/DefaultRepositoryTaskScheduler.java
+++ b/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/DefaultRepositoryTaskScheduler.java
@@ -22,25 +22,31 @@ import org.apache.maven.archiva.configuration.ConfigurationChangeListener;
import org.apache.maven.archiva.configuration.ConfigurationStore;
import org.apache.maven.archiva.configuration.ConfigurationStoreException;
import org.apache.maven.archiva.configuration.InvalidConfigurationException;
-import org.apache.maven.archiva.scheduler.task.RepositoryTask;
+import org.apache.maven.archiva.indexer.RepositoryArtifactIndex;
+import org.apache.maven.archiva.indexer.RepositoryArtifactIndexFactory;
+import org.apache.maven.archiva.indexer.RepositoryIndexException;
+import org.apache.maven.archiva.scheduler.executors.IndexerTaskExecutor;
+import org.apache.maven.archiva.scheduler.task.IndexerTask;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Startable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.StartingException;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.StoppingException;
-import org.codehaus.plexus.scheduler.AbstractJob;
import org.codehaus.plexus.scheduler.Scheduler;
+import org.codehaus.plexus.taskqueue.TaskQueue;
+import org.codehaus.plexus.taskqueue.TaskQueueException;
+import org.codehaus.plexus.taskqueue.execution.TaskExecutionException;
import org.quartz.CronTrigger;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.SchedulerException;
+import java.io.File;
import java.text.ParseException;
/**
* Default implementation of a scheduling component for the application.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
- * @todo should we use plexus-taskqueue instead of or in addition to this?
* @plexus.component role="org.apache.maven.archiva.scheduler.RepositoryTaskScheduler"
*/
public class DefaultRepositoryTaskScheduler
@@ -53,19 +59,29 @@ public class DefaultRepositoryTaskScheduler
private Scheduler scheduler;
/**
+ * @plexus.requirement role-hint="indexer"
+ */
+ private TaskQueue indexerQueue;
+
+ /**
+ * @plexus.requirement role="org.codehaus.plexus.taskqueue.execution.TaskExecutor" role-hint="indexer"
+ */
+ private IndexerTaskExecutor indexerTaskExecutor;
+
+ /**
* @plexus.requirement
*/
private ConfigurationStore configurationStore;
+ /**
+ * @plexus.requirement
+ */
+ private RepositoryArtifactIndexFactory indexFactory;
+
private static final String DISCOVERER_GROUP = "DISCOVERER";
private static final String INDEXER_JOB = "indexerTask";
- /**
- * @plexus.requirement role-hint="indexer"
- */
- private RepositoryTask indexerTask;
-
public void start()
throws StartingException
{
@@ -97,22 +113,20 @@ public class DefaultRepositoryTaskScheduler
private void scheduleJobs( Configuration configuration )
throws ParseException, SchedulerException
{
- // TODO: would be nice to queue jobs that are triggered so we could avoid two running at the same time (so have a queue for discovery based jobs so they didn't thrash the repo)
if ( configuration.getIndexPath() != null )
{
- JobDetail jobDetail = createJobDetail( INDEXER_JOB, indexerTask );
+ JobDetail jobDetail = createJobDetail( INDEXER_JOB );
getLogger().info( "Scheduling indexer: " + configuration.getIndexerCronExpression() );
CronTrigger trigger =
new CronTrigger( INDEXER_JOB + "Trigger", DISCOVERER_GROUP, configuration.getIndexerCronExpression() );
scheduler.scheduleJob( jobDetail, trigger );
- // TODO: run as a job so it doesn't block startup/configuration saving
try
{
- indexerTask.executeNowIfNeeded();
+ queueNowIfNeeded();
}
- catch ( TaskExecutionException e )
+ catch ( org.codehaus.plexus.taskqueue.execution.TaskExecutionException e )
{
getLogger().error( "Error executing task first time, continuing anyway: " + e.getMessage(), e );
}
@@ -123,13 +137,14 @@ public class DefaultRepositoryTaskScheduler
}
}
- private JobDetail createJobDetail( String jobName, RepositoryTask task )
+ private JobDetail createJobDetail( String jobName )
{
JobDetail jobDetail = new JobDetail( jobName, DISCOVERER_GROUP, RepositoryTaskJob.class );
+
JobDataMap dataMap = new JobDataMap();
- dataMap.put( AbstractJob.LOGGER, getLogger() );
- dataMap.put( RepositoryTaskJob.TASK_KEY, task );
+ dataMap.put( RepositoryTaskJob.TASK_QUEUE, indexerQueue );
jobDetail.setJobDataMap( dataMap );
+
return jobDetail;
}
@@ -170,9 +185,51 @@ public class DefaultRepositoryTaskScheduler
}
public void runIndexer()
- throws TaskExecutionException
+ throws org.apache.maven.archiva.scheduler.TaskExecutionException
+ {
+ IndexerTask task = new IndexerTask();
+ task.setJobName( "INDEX_INIT" );
+ try
+ {
+ indexerQueue.put( task );
+ }
+ catch ( TaskQueueException e )
+ {
+ throw new org.apache.maven.archiva.scheduler.TaskExecutionException( e.getMessage(), e );
+ }
+ }
+
+ public void queueNowIfNeeded()
+ throws org.codehaus.plexus.taskqueue.execution.TaskExecutionException
{
- indexerTask.execute();
+ Configuration configuration;
+ try
+ {
+ configuration = configurationStore.getConfigurationFromStore();
+ }
+ catch ( ConfigurationStoreException e )
+ {
+ throw new TaskExecutionException( e.getMessage(), e );
+ }
+
+ File indexPath = new File( configuration.getIndexPath() );
+
+ try
+ {
+ RepositoryArtifactIndex artifactIndex = indexFactory.createStandardIndex( indexPath );
+ if ( !artifactIndex.exists() )
+ {
+ runIndexer();
+ }
+ }
+ catch ( RepositoryIndexException e )
+ {
+ throw new TaskExecutionException( e.getMessage(), e );
+ }
+ catch ( org.apache.maven.archiva.scheduler.TaskExecutionException e )
+ {
+ throw new TaskExecutionException( e.getMessage(), e );
+ }
}
}
diff --git a/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/RepositoryTaskJob.java b/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/RepositoryTaskJob.java
index f94ae2130..6b859a526 100644
--- a/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/RepositoryTaskJob.java
+++ b/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/RepositoryTaskJob.java
@@ -16,8 +16,10 @@ package org.apache.maven.archiva.scheduler;
* limitations under the License.
*/
-import org.apache.maven.archiva.scheduler.task.RepositoryTask;
+import org.apache.maven.archiva.scheduler.task.IndexerTask;
import org.codehaus.plexus.scheduler.AbstractJob;
+import org.codehaus.plexus.taskqueue.TaskQueue;
+import org.codehaus.plexus.taskqueue.TaskQueueException;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
@@ -30,6 +32,8 @@ public class RepositoryTaskJob
{
static final String TASK_KEY = "EXECUTION";
+ static final String TASK_QUEUE = "TASK_QUEUE";
+
/**
* Execute the discoverer and the indexer.
*
@@ -43,12 +47,16 @@ public class RepositoryTaskJob
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
setJobDataMap( dataMap );
- RepositoryTask executor = (RepositoryTask) dataMap.get( TASK_KEY );
+ TaskQueue indexerQueue = (TaskQueue) dataMap.get( TASK_QUEUE );
+
+ IndexerTask task = new IndexerTask();
+ task.setJobName( context.getJobDetail().getName() );
+
try
{
- executor.execute();
+ indexerQueue.put( task );
}
- catch ( TaskExecutionException e )
+ catch ( TaskQueueException e )
{
throw new JobExecutionException( e );
}
diff --git a/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/executors/IndexerTaskExecutor.java b/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/executors/IndexerTaskExecutor.java
new file mode 100644
index 000000000..e91949af3
--- /dev/null
+++ b/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/executors/IndexerTaskExecutor.java
@@ -0,0 +1,320 @@
+package org.apache.maven.archiva.scheduler.executors;
+
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+import org.apache.maven.archiva.configuration.Configuration;
+import org.apache.maven.archiva.configuration.ConfigurationStore;
+import org.apache.maven.archiva.configuration.ConfiguredRepositoryFactory;
+import org.apache.maven.archiva.configuration.RepositoryConfiguration;
+import org.apache.maven.archiva.configuration.ConfigurationStoreException;
+import org.apache.maven.archiva.discoverer.ArtifactDiscoverer;
+import org.apache.maven.archiva.discoverer.DiscovererException;
+import org.apache.maven.archiva.discoverer.MetadataDiscoverer;
+import org.apache.maven.archiva.discoverer.filter.MetadataFilter;
+import org.apache.maven.archiva.discoverer.filter.SnapshotArtifactFilter;
+import org.apache.maven.archiva.indexer.RepositoryArtifactIndex;
+import org.apache.maven.archiva.indexer.RepositoryArtifactIndexFactory;
+import org.apache.maven.archiva.indexer.RepositoryIndexException;
+import org.apache.maven.archiva.indexer.record.IndexRecordExistsArtifactFilter;
+import org.apache.maven.archiva.indexer.record.RepositoryIndexRecordFactory;
+import org.apache.maven.archiva.reporting.ReportExecutor;
+import org.apache.maven.archiva.reporting.ReportGroup;
+import org.apache.maven.archiva.reporting.ReportingDatabase;
+import org.apache.maven.archiva.reporting.ReportingMetadataFilter;
+import org.apache.maven.archiva.reporting.ReportingStoreException;
+import org.apache.maven.archiva.scheduler.task.IndexerTask;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.filter.AndArtifactFilter;
+import org.apache.maven.project.MavenProjectBuilder;
+import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.taskqueue.Task;
+import org.codehaus.plexus.taskqueue.execution.TaskExecutionException;
+import org.codehaus.plexus.taskqueue.execution.TaskExecutor;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Edwin Punzalan
+ *
+ * @plexus.component role="org.codehaus.plexus.taskqueue.execution.TaskExecutor" role-hint="indexer"
+ */
+public class IndexerTaskExecutor
+ extends AbstractLogEnabled
+ implements TaskExecutor
+{
+ /**
+ * Configuration store.
+ *
+ * @plexus.requirement
+ */
+ private ConfigurationStore configurationStore;
+
+ /**
+ * @plexus.requirement
+ */
+ private RepositoryArtifactIndexFactory indexFactory;
+
+ /**
+ * @plexus.requirement
+ */
+ private ConfiguredRepositoryFactory repoFactory;
+
+ /**
+ * @plexus.requirement role="org.apache.maven.archiva.discoverer.ArtifactDiscoverer"
+ */
+ private Map artifactDiscoverers;
+
+ /**
+ * @plexus.requirement role="org.apache.maven.archiva.discoverer.MetadataDiscoverer"
+ */
+ private Map metadataDiscoverers;
+
+ /**
+ * @plexus.requirement role-hint="standard"
+ */
+ private RepositoryIndexRecordFactory recordFactory;
+
+ /**
+ * @plexus.requirement
+ */
+ private ReportExecutor reportExecutor;
+
+ /**
+ * @plexus.requirement role-hint="health"
+ */
+ private ReportGroup reportGroup;
+
+ private static final int ARTIFACT_BUFFER_SIZE = 1000;
+
+ public void executeTask( Task task )
+ throws TaskExecutionException
+ {
+ IndexerTask indexerTask = (IndexerTask) task;
+
+ getLogger().info( "Executing task from queue with job name: " + indexerTask.getJobName() );
+
+ execute();
+ }
+
+ public void execute()
+ throws TaskExecutionException
+ {
+ Configuration configuration;
+ try
+ {
+ configuration = configurationStore.getConfigurationFromStore();
+ }
+ catch ( ConfigurationStoreException e )
+ {
+ throw new TaskExecutionException( e.getMessage(), e );
+ }
+
+ File indexPath = new File( configuration.getIndexPath() );
+
+ execute( configuration, indexPath );
+ }
+
+ public void executeNowIfNeeded()
+ throws TaskExecutionException
+ {
+ Configuration configuration;
+ try
+ {
+ configuration = configurationStore.getConfigurationFromStore();
+ }
+ catch ( ConfigurationStoreException e )
+ {
+ throw new TaskExecutionException( e.getMessage(), e );
+ }
+
+ File indexPath = new File( configuration.getIndexPath() );
+
+ try
+ {
+ RepositoryArtifactIndex artifactIndex = indexFactory.createStandardIndex( indexPath );
+ if ( !artifactIndex.exists() )
+ {
+ execute( configuration, indexPath );
+ }
+ }
+ catch ( RepositoryIndexException e )
+ {
+ throw new TaskExecutionException( e.getMessage(), e );
+ }
+ }
+
+ private void execute( Configuration configuration, File indexPath )
+ throws TaskExecutionException
+ {
+ long time = System.currentTimeMillis();
+ getLogger().info( "Starting repository indexing process" );
+
+ RepositoryArtifactIndex index = indexFactory.createStandardIndex( indexPath );
+
+ try
+ {
+ Collection keys;
+ if ( index.exists() )
+ {
+ keys = index.getAllRecordKeys();
+ }
+ else
+ {
+ keys = Collections.EMPTY_LIST;
+ }
+
+ for ( Iterator i = configuration.getRepositories().iterator(); i.hasNext(); )
+ {
+ RepositoryConfiguration repositoryConfiguration = (RepositoryConfiguration) i.next();
+
+ if ( repositoryConfiguration.isIndexed() )
+ {
+ List blacklistedPatterns = new ArrayList();
+ if ( repositoryConfiguration.getBlackListPatterns() != null )
+ {
+ blacklistedPatterns.addAll( repositoryConfiguration.getBlackListPatterns() );
+ }
+ if ( configuration.getGlobalBlackListPatterns() != null )
+ {
+ blacklistedPatterns.addAll( configuration.getGlobalBlackListPatterns() );
+ }
+ boolean includeSnapshots = repositoryConfiguration.isIncludeSnapshots();
+
+ ArtifactRepository repository = repoFactory.createRepository( repositoryConfiguration );
+ ReportingDatabase reporter = reportExecutor.getReportDatabase( repository, reportGroup );
+
+ // keep original value in case there is another process under way
+ long origStartTime = reporter.getStartTime();
+ reporter.setStartTime( System.currentTimeMillis() );
+
+ // Discovery process
+ String layoutProperty = repositoryConfiguration.getLayout();
+ ArtifactDiscoverer discoverer = (ArtifactDiscoverer) artifactDiscoverers.get( layoutProperty );
+ AndArtifactFilter filter = new AndArtifactFilter();
+ filter.add( new IndexRecordExistsArtifactFilter( keys ) );
+ if ( !includeSnapshots )
+ {
+ filter.add( new SnapshotArtifactFilter() );
+ }
+
+ // Save some memory by not tracking paths we won't use
+ // TODO: Plexus CDC should be able to inject this configuration
+ discoverer.setTrackOmittedPaths( false );
+
+ getLogger().info( "Searching repository " + repositoryConfiguration.getName() );
+ List artifacts = discoverer.discoverArtifacts( repository, blacklistedPatterns, filter );
+
+ if ( !artifacts.isEmpty() )
+ {
+ getLogger().info( "Discovered " + artifacts.size() + " unindexed artifacts" );
+
+ // Work through these in batches, then flush the project cache.
+ for ( int j = 0; j < artifacts.size(); j += ARTIFACT_BUFFER_SIZE )
+ {
+ int end = j + ARTIFACT_BUFFER_SIZE;
+ List currentArtifacts =
+ artifacts.subList( j, end > artifacts.size() ? artifacts.size() : end );
+
+ // TODO: proper queueing of this in case it was triggered externally (not harmful to do so at present, but not optimal)
+
+ // run the reports. Done intermittently to avoid losing track of what is indexed since
+ // that is what the filter is based on.
+ reportExecutor.runArtifactReports( reportGroup, currentArtifacts, repository );
+
+ index.indexArtifacts( currentArtifacts, recordFactory );
+
+ // MNG-142 - the project builder retains a lot of objects in its inflexible cache. This is a hack
+ // around that. TODO: remove when it is configurable
+ flushProjectBuilderCacheHack();
+ }
+ }
+
+ MetadataFilter metadataFilter = new ReportingMetadataFilter( reporter );
+
+ MetadataDiscoverer metadataDiscoverer =
+ (MetadataDiscoverer) metadataDiscoverers.get( layoutProperty );
+ List metadata =
+ metadataDiscoverer.discoverMetadata( repository, blacklistedPatterns, metadataFilter );
+
+ if ( !metadata.isEmpty() )
+ {
+ getLogger().info( "Discovered " + metadata.size() + " unprocessed metadata files" );
+
+ // run the reports
+ reportExecutor.runMetadataReports( reportGroup, metadata, repository );
+ }
+
+ reporter.setStartTime( origStartTime );
+ }
+ }
+ }
+ catch ( RepositoryIndexException e )
+ {
+ throw new TaskExecutionException( e.getMessage(), e );
+ }
+ catch ( DiscovererException e )
+ {
+ throw new TaskExecutionException( e.getMessage(), e );
+ }
+ catch ( ReportingStoreException e )
+ {
+ throw new TaskExecutionException( e.getMessage(), e );
+ }
+
+ time = System.currentTimeMillis() - time;
+ getLogger().info( "Finished repository indexing process in " + time + "ms" );
+ }
+
+ /**
+ * @todo remove when no longer needed (MNG-142)
+ * @plexus.requirement
+ */
+ private MavenProjectBuilder projectBuilder;
+
+ private void flushProjectBuilderCacheHack()
+ {
+ try
+ {
+ if ( projectBuilder != null )
+ {
+ java.lang.reflect.Field f = projectBuilder.getClass().getDeclaredField( "rawProjectCache" );
+ f.setAccessible( true );
+ Map cache = (Map) f.get( projectBuilder );
+ cache.clear();
+
+ f = projectBuilder.getClass().getDeclaredField( "processedProjectCache" );
+ f.setAccessible( true );
+ cache = (Map) f.get( projectBuilder );
+ cache.clear();
+ }
+ }
+ catch ( NoSuchFieldException e )
+ {
+ throw new RuntimeException( e );
+ }
+ catch ( IllegalAccessException e )
+ {
+ throw new RuntimeException( e );
+ }
+ }
+}
diff --git a/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/task/IndexerTask.java b/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/task/IndexerTask.java
index d563b7b28..ec653e112 100644
--- a/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/task/IndexerTask.java
+++ b/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/task/IndexerTask.java
@@ -16,294 +16,30 @@ package org.apache.maven.archiva.scheduler.task;
* limitations under the License.
*/
-import org.apache.maven.archiva.configuration.Configuration;
-import org.apache.maven.archiva.configuration.ConfigurationStore;
-import org.apache.maven.archiva.configuration.ConfigurationStoreException;
-import org.apache.maven.archiva.configuration.ConfiguredRepositoryFactory;
-import org.apache.maven.archiva.configuration.RepositoryConfiguration;
-import org.apache.maven.archiva.discoverer.ArtifactDiscoverer;
-import org.apache.maven.archiva.discoverer.DiscovererException;
-import org.apache.maven.archiva.discoverer.MetadataDiscoverer;
-import org.apache.maven.archiva.discoverer.filter.MetadataFilter;
-import org.apache.maven.archiva.discoverer.filter.SnapshotArtifactFilter;
-import org.apache.maven.archiva.indexer.RepositoryArtifactIndex;
-import org.apache.maven.archiva.indexer.RepositoryArtifactIndexFactory;
-import org.apache.maven.archiva.indexer.RepositoryIndexException;
-import org.apache.maven.archiva.indexer.record.IndexRecordExistsArtifactFilter;
-import org.apache.maven.archiva.indexer.record.RepositoryIndexRecordFactory;
-import org.apache.maven.archiva.reporting.ReportExecutor;
-import org.apache.maven.archiva.reporting.ReportGroup;
-import org.apache.maven.archiva.reporting.ReportingDatabase;
-import org.apache.maven.archiva.reporting.ReportingMetadataFilter;
-import org.apache.maven.archiva.reporting.ReportingStoreException;
-import org.apache.maven.archiva.scheduler.TaskExecutionException;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.artifact.resolver.filter.AndArtifactFilter;
-import org.apache.maven.project.MavenProjectBuilder;
-import org.codehaus.plexus.logging.AbstractLogEnabled;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
+import org.codehaus.plexus.taskqueue.Task;
/**
* Task for discovering changes in the repository and updating the index accordingly.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
- * @plexus.component role="org.apache.maven.archiva.scheduler.task.RepositoryTask" role-hint="indexer"
*/
public class IndexerTask
- extends AbstractLogEnabled
- implements RepositoryTask
+ implements Task
{
- /**
- * Configuration store.
- *
- * @plexus.requirement
- */
- private ConfigurationStore configurationStore;
-
- /**
- * @plexus.requirement
- */
- private RepositoryArtifactIndexFactory indexFactory;
-
- /**
- * @plexus.requirement
- */
- private ConfiguredRepositoryFactory repoFactory;
-
- /**
- * @plexus.requirement role="org.apache.maven.archiva.discoverer.ArtifactDiscoverer"
- */
- private Map artifactDiscoverers;
-
- /**
- * @plexus.requirement role="org.apache.maven.archiva.discoverer.MetadataDiscoverer"
- */
- private Map metadataDiscoverers;
-
- /**
- * @plexus.requirement role-hint="standard"
- */
- private RepositoryIndexRecordFactory recordFactory;
-
- /**
- * @plexus.requirement
- */
- private ReportExecutor reportExecutor;
-
- /**
- * @plexus.requirement role-hint="health"
- */
- private ReportGroup reportGroup;
-
- private static final int ARTIFACT_BUFFER_SIZE = 1000;
-
- public void execute()
- throws TaskExecutionException
- {
- Configuration configuration;
- try
- {
- configuration = configurationStore.getConfigurationFromStore();
- }
- catch ( ConfigurationStoreException e )
- {
- throw new TaskExecutionException( e.getMessage(), e );
- }
-
- File indexPath = new File( configuration.getIndexPath() );
+ private String jobName;
- execute( configuration, indexPath );
- }
-
- private void execute( Configuration configuration, File indexPath )
- throws TaskExecutionException
+ public long getMaxExecutionTime()
{
- long time = System.currentTimeMillis();
- getLogger().info( "Starting repository indexing process" );
-
- RepositoryArtifactIndex index = indexFactory.createStandardIndex( indexPath );
-
- try
- {
- Collection keys;
- if ( index.exists() )
- {
- keys = index.getAllRecordKeys();
- }
- else
- {
- keys = Collections.EMPTY_LIST;
- }
-
- for ( Iterator i = configuration.getRepositories().iterator(); i.hasNext(); )
- {
- RepositoryConfiguration repositoryConfiguration = (RepositoryConfiguration) i.next();
-
- if ( repositoryConfiguration.isIndexed() )
- {
- List blacklistedPatterns = new ArrayList();
- if ( repositoryConfiguration.getBlackListPatterns() != null )
- {
- blacklistedPatterns.addAll( repositoryConfiguration.getBlackListPatterns() );
- }
- if ( configuration.getGlobalBlackListPatterns() != null )
- {
- blacklistedPatterns.addAll( configuration.getGlobalBlackListPatterns() );
- }
- boolean includeSnapshots = repositoryConfiguration.isIncludeSnapshots();
-
- ArtifactRepository repository = repoFactory.createRepository( repositoryConfiguration );
- ReportingDatabase reporter = reportExecutor.getReportDatabase( repository, reportGroup );
-
- // keep original value in case there is another process under way
- long origStartTime = reporter.getStartTime();
- reporter.setStartTime( System.currentTimeMillis() );
-
- // Discovery process
- String layoutProperty = repositoryConfiguration.getLayout();
- ArtifactDiscoverer discoverer = (ArtifactDiscoverer) artifactDiscoverers.get( layoutProperty );
- AndArtifactFilter filter = new AndArtifactFilter();
- filter.add( new IndexRecordExistsArtifactFilter( keys ) );
- if ( !includeSnapshots )
- {
- filter.add( new SnapshotArtifactFilter() );
- }
-
- // Save some memory by not tracking paths we won't use
- // TODO: Plexus CDC should be able to inject this configuration
- discoverer.setTrackOmittedPaths( false );
-
- getLogger().info( "Searching repository " + repositoryConfiguration.getName() );
- List artifacts = discoverer.discoverArtifacts( repository, blacklistedPatterns, filter );
-
- if ( !artifacts.isEmpty() )
- {
- getLogger().info( "Discovered " + artifacts.size() + " unindexed artifacts" );
-
- // Work through these in batches, then flush the project cache.
- for ( int j = 0; j < artifacts.size(); j += ARTIFACT_BUFFER_SIZE )
- {
- int end = j + ARTIFACT_BUFFER_SIZE;
- List currentArtifacts =
- artifacts.subList( j, end > artifacts.size() ? artifacts.size() : end );
-
- // TODO: proper queueing of this in case it was triggered externally (not harmful to do so at present, but not optimal)
-
- // run the reports. Done intermittently to avoid losing track of what is indexed since
- // that is what the filter is based on.
- reportExecutor.runArtifactReports( reportGroup, currentArtifacts, repository );
-
- index.indexArtifacts( currentArtifacts, recordFactory );
-
- // MNG-142 - the project builder retains a lot of objects in its inflexible cache. This is a hack
- // around that. TODO: remove when it is configurable
- flushProjectBuilderCacheHack();
- }
- }
-
- MetadataFilter metadataFilter = new ReportingMetadataFilter( reporter );
-
- MetadataDiscoverer metadataDiscoverer =
- (MetadataDiscoverer) metadataDiscoverers.get( layoutProperty );
- List metadata =
- metadataDiscoverer.discoverMetadata( repository, blacklistedPatterns, metadataFilter );
-
- if ( !metadata.isEmpty() )
- {
- getLogger().info( "Discovered " + metadata.size() + " unprocessed metadata files" );
-
- // run the reports
- reportExecutor.runMetadataReports( reportGroup, metadata, repository );
- }
-
- reporter.setStartTime( origStartTime );
- }
- }
- }
- catch ( RepositoryIndexException e )
- {
- throw new TaskExecutionException( e.getMessage(), e );
- }
- catch ( DiscovererException e )
- {
- throw new TaskExecutionException( e.getMessage(), e );
- }
- catch ( ReportingStoreException e )
- {
- throw new TaskExecutionException( e.getMessage(), e );
- }
-
- time = System.currentTimeMillis() - time;
- getLogger().info( "Finished repository indexing process in " + time + "ms" );
+ return 0;
}
- public void executeNowIfNeeded()
- throws TaskExecutionException
+ public String getJobName()
{
- Configuration configuration;
- try
- {
- configuration = configurationStore.getConfigurationFromStore();
- }
- catch ( ConfigurationStoreException e )
- {
- throw new TaskExecutionException( e.getMessage(), e );
- }
-
- File indexPath = new File( configuration.getIndexPath() );
-
- try
- {
- RepositoryArtifactIndex artifactIndex = indexFactory.createStandardIndex( indexPath );
- if ( !artifactIndex.exists() )
- {
- execute( configuration, indexPath );
- }
- }
- catch ( RepositoryIndexException e )
- {
- throw new TaskExecutionException( e.getMessage(), e );
- }
+ return jobName;
}
- /**
- * @todo remove when no longer needed (MNG-142)
- * @plexus.requirement
- */
- private MavenProjectBuilder projectBuilder;
-
- private void flushProjectBuilderCacheHack()
+ public void setJobName( String jobName )
{
- try
- {
- if ( projectBuilder != null )
- {
- java.lang.reflect.Field f = projectBuilder.getClass().getDeclaredField( "rawProjectCache" );
- f.setAccessible( true );
- Map cache = (Map) f.get( projectBuilder );
- cache.clear();
-
- f = projectBuilder.getClass().getDeclaredField( "processedProjectCache" );
- f.setAccessible( true );
- cache = (Map) f.get( projectBuilder );
- cache.clear();
- }
- }
- catch ( NoSuchFieldException e )
- {
- throw new RuntimeException( e );
- }
- catch ( IllegalAccessException e )
- {
- throw new RuntimeException( e );
- }
+ this.jobName = jobName;
}
-
}
diff --git a/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/task/RepositoryTask.java b/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/task/RepositoryTask.java
index ae4162c29..fc92f690b 100644
--- a/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/task/RepositoryTask.java
+++ b/archiva-core/src/main/java/org/apache/maven/archiva/scheduler/task/RepositoryTask.java
@@ -17,6 +17,7 @@ package org.apache.maven.archiva.scheduler.task;
*/
import org.apache.maven.archiva.scheduler.TaskExecutionException;
+import org.codehaus.plexus.taskqueue.Task;
/**
* A repository task.
@@ -24,6 +25,7 @@ import org.apache.maven.archiva.scheduler.TaskExecutionException;
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
*/
public interface RepositoryTask
+ extends Task
{
/**
* Execute the task.
diff --git a/archiva-core/src/main/resources/META-INF/plexus/components.xml b/archiva-core/src/main/resources/META-INF/plexus/components.xml
new file mode 100644
index 000000000..38934f21e
--- /dev/null
+++ b/archiva-core/src/main/resources/META-INF/plexus/components.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<component-set>
+ <components>
+
+ <component>
+ <role>org.codehaus.plexus.taskqueue.TaskQueue</role>
+ <role-hint>indexer</role-hint>
+ <implementation>org.codehaus.plexus.taskqueue.DefaultTaskQueue</implementation>
+ <lifecycle-handler>plexus-configurable</lifecycle-handler>
+ <configuration>
+ <task-entry-evaluators>
+ </task-entry-evaluators>
+ <task-exit-evaluators>
+ </task-exit-evaluators>
+ <task-viability-evaluators>
+ </task-viability-evaluators>
+ </configuration>
+ </component>
+
+ <component>
+ <role>org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor</role>
+ <role-hint>indexer</role-hint>
+ <implementation>org.codehaus.plexus.taskqueue.execution.ThreadedTaskQueueExecutor</implementation>
+ <requirements>
+ <requirement>
+ <role>org.codehaus.plexus.taskqueue.execution.TaskExecutor</role>
+ <role-hint>indexer</role-hint>
+ </requirement>
+ <requirement>
+ <role>org.codehaus.plexus.taskqueue.TaskQueue</role>
+ <role-hint>indexer</role-hint>
+ </requirement>
+ </requirements>
+ <configuration>
+ <name>indexer</name>
+ </configuration>
+ </component>
+
+ </components>
+</component-set>
diff --git a/archiva-webapp/src/main/resources/META-INF/plexus/application.xml b/archiva-webapp/src/main/resources/META-INF/plexus/application.xml
index 2c39f447e..ddf294dd9 100644
--- a/archiva-webapp/src/main/resources/META-INF/plexus/application.xml
+++ b/archiva-webapp/src/main/resources/META-INF/plexus/application.xml
@@ -441,5 +441,9 @@
<component>
<role>org.apache.maven.archiva.scheduler.RepositoryTaskScheduler</role>
</component>
+ <component>
+ <role>org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor</role>
+ <role-hint>indexer</role-hint>
+ </component>
</load-on-start>
</plexus>