mirror of https://github.com/apache/archiva.git
[MRM-331]: Finding an Artifact gives an HTTP 500
git-svn-id: https://svn.apache.org/repos/asf/maven/archiva/trunk@541744 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
5a681a15c9
commit
bf565c3f3a
|
@ -19,12 +19,30 @@ package org.apache.maven.archiva.consumers.lucene;
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
|
||||
import org.apache.maven.archiva.configuration.ConfigurationNames;
|
||||
import org.apache.maven.archiva.configuration.RepositoryConfiguration;
|
||||
import org.apache.maven.archiva.consumers.AbstractMonitoredConsumer;
|
||||
import org.apache.maven.archiva.consumers.ConsumerException;
|
||||
import org.apache.maven.archiva.consumers.DatabaseUnprocessedArtifactConsumer;
|
||||
import org.apache.maven.archiva.indexer.RepositoryContentIndex;
|
||||
import org.apache.maven.archiva.indexer.RepositoryContentIndexFactory;
|
||||
import org.apache.maven.archiva.indexer.RepositoryIndexException;
|
||||
import org.apache.maven.archiva.indexer.hashcodes.HashcodesRecord;
|
||||
import org.apache.maven.archiva.model.ArchivaArtifact;
|
||||
import org.apache.maven.archiva.model.ArchivaRepository;
|
||||
import org.apache.maven.archiva.repository.ArchivaConfigurationAdaptor;
|
||||
import org.apache.maven.archiva.repository.layout.BidirectionalRepositoryLayout;
|
||||
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
|
||||
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
|
||||
import org.codehaus.plexus.registry.Registry;
|
||||
import org.codehaus.plexus.registry.RegistryListener;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* IndexArtifactConsumer
|
||||
|
@ -38,41 +56,88 @@ import java.util.List;
|
|||
*/
|
||||
public class IndexArtifactConsumer
|
||||
extends AbstractMonitoredConsumer
|
||||
implements DatabaseUnprocessedArtifactConsumer
|
||||
implements DatabaseUnprocessedArtifactConsumer, RegistryListener, Initializable
|
||||
{
|
||||
private static final String INDEX_ERROR = "indexing_error";
|
||||
|
||||
/**
|
||||
* @plexus.configuration default-value="index-artifact"
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* @plexus.configuration default-value="Index the artifact details for Full Text Search."
|
||||
* @plexus.configuration default-value="Index the artifact checksums for Find functionality."
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* @plexus.requirement
|
||||
*/
|
||||
private ArchivaConfiguration configuration;
|
||||
|
||||
/**
|
||||
* @plexus.requirement role="org.apache.maven.archiva.repository.layout.BidirectionalRepositoryLayout"
|
||||
*/
|
||||
private Map bidirectionalLayoutMap;
|
||||
|
||||
/**
|
||||
* @plexus.requirement role-hint="lucene"
|
||||
*/
|
||||
private RepositoryContentIndexFactory indexFactory;
|
||||
|
||||
private Map repositoryMap = new HashMap();
|
||||
|
||||
public void beginScan()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
/* nothing to do here */
|
||||
}
|
||||
|
||||
public void completeScan()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
/* nothing to do here */
|
||||
}
|
||||
|
||||
public List getIncludedTypes()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return null; // TODO: define these as a list of artifacts.
|
||||
}
|
||||
|
||||
public void processArchivaArtifact( ArchivaArtifact artifact )
|
||||
throws ConsumerException
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
HashcodesRecord record = new HashcodesRecord();
|
||||
record.setRepositoryId( artifact.getModel().getRepositoryId() );
|
||||
record.setArtifact( artifact );
|
||||
|
||||
IndexedRepositoryDetails pnl = getIndexedRepositoryDetails( artifact );
|
||||
String artifactPath = pnl.layout.toPath( artifact );
|
||||
record.setFilename( artifactPath );
|
||||
|
||||
try
|
||||
{
|
||||
pnl.index.modifyRecord( record );
|
||||
}
|
||||
catch ( RepositoryIndexException e )
|
||||
{
|
||||
triggerConsumerError( INDEX_ERROR, "Unable to index hashcodes: " + e.getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
private IndexedRepositoryDetails getIndexedRepositoryDetails( ArchivaArtifact artifact )
|
||||
{
|
||||
String repoId = artifact.getModel().getRepositoryId();
|
||||
if ( StringUtils.isBlank( repoId ) )
|
||||
{
|
||||
throw new IllegalStateException( "Unable to process artifact [" + artifact
|
||||
+ "] as it has no repository id associated with it." );
|
||||
}
|
||||
|
||||
return getIndexedRepositoryDetails( repoId );
|
||||
}
|
||||
|
||||
private IndexedRepositoryDetails getIndexedRepositoryDetails( String id )
|
||||
{
|
||||
return (IndexedRepositoryDetails) this.repositoryMap.get( id );
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
|
@ -90,4 +155,60 @@ public class IndexArtifactConsumer
|
|||
return false;
|
||||
}
|
||||
|
||||
public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
|
||||
{
|
||||
if ( ConfigurationNames.isRepositories( propertyName ) )
|
||||
{
|
||||
initRepositoryMap();
|
||||
}
|
||||
}
|
||||
|
||||
public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
public void initialize()
|
||||
throws InitializationException
|
||||
{
|
||||
initRepositoryMap();
|
||||
configuration.addChangeListener( this );
|
||||
}
|
||||
|
||||
private void initRepositoryMap()
|
||||
{
|
||||
synchronized ( this.repositoryMap )
|
||||
{
|
||||
this.repositoryMap.clear();
|
||||
|
||||
Iterator it = configuration.getConfiguration().getRepositories().iterator();
|
||||
while ( it.hasNext() )
|
||||
{
|
||||
RepositoryConfiguration repoconfig = (RepositoryConfiguration) it.next();
|
||||
if ( !repoconfig.isManaged() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ArchivaRepository repository = ArchivaConfigurationAdaptor.toArchivaRepository( repoconfig );
|
||||
IndexedRepositoryDetails pnl = new IndexedRepositoryDetails();
|
||||
|
||||
pnl.path = repository.getUrl().getPath();
|
||||
pnl.layout = (BidirectionalRepositoryLayout) this.bidirectionalLayoutMap.get( repoconfig.getLayout() );
|
||||
|
||||
pnl.index = indexFactory.createHashcodeIndex( repository );
|
||||
|
||||
this.repositoryMap.put( repoconfig.getId(), pnl );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class IndexedRepositoryDetails
|
||||
{
|
||||
public String path;
|
||||
|
||||
public BidirectionalRepositoryLayout layout;
|
||||
|
||||
public RepositoryContentIndex index;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -176,6 +176,15 @@ public class DefaultArchivaTaskScheduler
|
|||
dataMap.put( DatabaseTaskJob.TASK_QUEUE, databaseUpdateQueue );
|
||||
databaseJob.setJobDataMap( dataMap );
|
||||
|
||||
CronExpressionValidator cronValidator = new CronExpressionValidator();
|
||||
if ( !cronValidator.validate( cronString ) )
|
||||
{
|
||||
getLogger().warn(
|
||||
"Cron expression [" + cronString
|
||||
+ "] for database update is invalid. Defaulting to hourly." );
|
||||
cronString = CRON_HOURLY;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
CronTrigger trigger = new CronTrigger( DATABASE_JOB_TRIGGER, DATABASE_SCAN_GROUP, cronString );
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.apache.maven.archiva.common.ArchivaException;
|
|||
import org.apache.maven.archiva.scheduled.ArchivaTaskScheduler;
|
||||
import org.apache.maven.archiva.scheduled.DefaultArchivaTaskScheduler;
|
||||
import org.apache.maven.archiva.scheduled.tasks.ArchivaTask;
|
||||
import org.apache.maven.archiva.scheduled.tasks.DatabaseTask;
|
||||
import org.apache.maven.archiva.scheduled.tasks.RepositoryTask;
|
||||
import org.apache.maven.archiva.security.ArchivaRoleConstants;
|
||||
import org.codehaus.plexus.redback.rbac.Resource;
|
||||
|
@ -36,12 +37,16 @@ import org.codehaus.plexus.xwork.action.PlexusActionSupport;
|
|||
/**
|
||||
* Configures the application.
|
||||
*
|
||||
* @plexus.component role="com.opensymphony.xwork.Action" role-hint="indexRepositoryAction"
|
||||
* @plexus.component role="com.opensymphony.xwork.Action" role-hint="schedulerAction"
|
||||
*/
|
||||
public class IndexRepositoryAction
|
||||
public class SchedulerAction
|
||||
extends PlexusActionSupport
|
||||
implements SecureAction
|
||||
{
|
||||
private static final String REPO_SUCCESS = "repoSucces";
|
||||
|
||||
private static final String DB_SUCCESS = "dbSuccess";
|
||||
|
||||
/**
|
||||
* @plexus.requirement
|
||||
*/
|
||||
|
@ -49,7 +54,7 @@ public class IndexRepositoryAction
|
|||
|
||||
private String repoid;
|
||||
|
||||
public String run()
|
||||
public String scanRepository()
|
||||
{
|
||||
if ( StringUtils.isBlank( repoid ) )
|
||||
{
|
||||
|
@ -106,6 +111,48 @@ public class IndexRepositoryAction
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
public String updateDatabase()
|
||||
{
|
||||
DatabaseTask task = new DatabaseTask();
|
||||
task.setName( DefaultArchivaTaskScheduler.DATABASE_JOB + ":user-requested" );
|
||||
task.setQueuePolicy( ArchivaTask.QUEUE_POLICY_WAIT );
|
||||
|
||||
boolean scheduleTask = false;
|
||||
|
||||
try
|
||||
{
|
||||
if ( taskScheduler.isProcessingDatabaseTask() )
|
||||
{
|
||||
addActionError( "Database task was already queued." );
|
||||
}
|
||||
else
|
||||
{
|
||||
scheduleTask = true;
|
||||
}
|
||||
}
|
||||
catch ( ArchivaException e )
|
||||
{
|
||||
scheduleTask = false;
|
||||
addActionError( e.getMessage() );
|
||||
}
|
||||
|
||||
if ( scheduleTask )
|
||||
{
|
||||
try
|
||||
{
|
||||
taskScheduler.queueDatabaseTask( task );
|
||||
addActionMessage( "Your request to update the database has been queued." );
|
||||
}
|
||||
catch ( TaskQueueException e )
|
||||
{
|
||||
addActionError( "Unable to queue your request to update the database: " + e.getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
// Return to the database screen.
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
public void addActionMessage( String aMessage )
|
||||
{
|
||||
super.addActionMessage( aMessage );
|
|
@ -144,5 +144,6 @@ public class ConfigurationSynchronization
|
|||
{
|
||||
Banner.display( getLogger(), ArchivaVersion.determineVersion( this.getClass().getClassLoader() ) );
|
||||
synchConfiguration();
|
||||
archivaConfiguration.addChangeListener( this );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,6 @@ webwork.mapper.class = org.apache.maven.archiva.web.mapper.RepositoryActionMappe
|
|||
webwork.objectFactory = org.codehaus.plexus.xwork.PlexusObjectFactory
|
||||
webwork.url.includeParams = none
|
||||
|
||||
webwork.devMode = true
|
||||
# webwork.devMode = true
|
||||
|
||||
# TODO: package up a theme and share with Continuum. Should contain everything from xhtml, and set templateDir to WEB-INF/themes
|
||||
|
|
|
@ -238,7 +238,7 @@
|
|||
<result name="confirm" type="redirect-action">deleteRepository</result>
|
||||
</action>
|
||||
|
||||
<action name="indexRepository" class="indexRepositoryAction" method="run">
|
||||
<action name="indexRepository" class="schedulerAction" method="scanRepository">
|
||||
<result type="redirect-action">repositories</result>
|
||||
</action>
|
||||
|
||||
|
@ -344,6 +344,10 @@
|
|||
<result name="input">/WEB-INF/jsp/admin/database.jsp</result>
|
||||
</action>
|
||||
|
||||
<action name="updateDatabase" class="schedulerAction" method="updateDatabase">
|
||||
<result type="redirect-action">database</result>
|
||||
</action>
|
||||
|
||||
<!-- .\ CONFIGURATION \.___________________________________________ -->
|
||||
|
||||
<action name="configure" class="configureAction" method="input">
|
||||
|
|
|
@ -57,6 +57,10 @@
|
|||
</table>
|
||||
</ww:form>
|
||||
|
||||
<ww:form action="updateDatabase" theme="simple">
|
||||
<ww:submit value="Update Database Now"/>
|
||||
</ww:form>
|
||||
|
||||
<h2>Database - Unprocessed Artifacts Scanning</h2>
|
||||
|
||||
<c:choose>
|
||||
|
|
|
@ -157,7 +157,7 @@
|
|||
<tr>
|
||||
<td>
|
||||
<redback:ifAuthorized permission="archiva-run-indexer">
|
||||
<ww:form action="indexRepository">
|
||||
<ww:form action="indexRepository" theme="simple">
|
||||
<ww:hidden name="repoid" value="%{'${repository.id}'}"/>
|
||||
<ww:submit value="Scan Repository Now"/>
|
||||
</ww:form>
|
||||
|
|
Loading…
Reference in New Issue