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
archiva-base/archiva-consumers/archiva-lucene-consumers/src/main/java/org/apache/maven/archiva/consumers/lucene
archiva-scheduled/src/main/java/org/apache/maven/archiva/scheduled
archiva-web/archiva-webapp/src/main
java/org/apache/maven/archiva/web
resources
webapp/WEB-INF/jsp/admin
|
@ -19,12 +19,30 @@ package org.apache.maven.archiva.consumers.lucene;
|
||||||
* under the License.
|
* 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.AbstractMonitoredConsumer;
|
||||||
import org.apache.maven.archiva.consumers.ConsumerException;
|
import org.apache.maven.archiva.consumers.ConsumerException;
|
||||||
import org.apache.maven.archiva.consumers.DatabaseUnprocessedArtifactConsumer;
|
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.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.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IndexArtifactConsumer
|
* IndexArtifactConsumer
|
||||||
|
@ -38,41 +56,88 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public class IndexArtifactConsumer
|
public class IndexArtifactConsumer
|
||||||
extends AbstractMonitoredConsumer
|
extends AbstractMonitoredConsumer
|
||||||
implements DatabaseUnprocessedArtifactConsumer
|
implements DatabaseUnprocessedArtifactConsumer, RegistryListener, Initializable
|
||||||
{
|
{
|
||||||
|
private static final String INDEX_ERROR = "indexing_error";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @plexus.configuration default-value="index-artifact"
|
* @plexus.configuration default-value="index-artifact"
|
||||||
*/
|
*/
|
||||||
private String id;
|
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;
|
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()
|
public void beginScan()
|
||||||
{
|
{
|
||||||
// TODO Auto-generated method stub
|
/* nothing to do here */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void completeScan()
|
public void completeScan()
|
||||||
{
|
{
|
||||||
// TODO Auto-generated method stub
|
/* nothing to do here */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List getIncludedTypes()
|
public List getIncludedTypes()
|
||||||
{
|
{
|
||||||
// TODO Auto-generated method stub
|
return null; // TODO: define these as a list of artifacts.
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processArchivaArtifact( ArchivaArtifact artifact )
|
public void processArchivaArtifact( ArchivaArtifact artifact )
|
||||||
throws ConsumerException
|
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()
|
public String getDescription()
|
||||||
|
@ -90,4 +155,60 @@ public class IndexArtifactConsumer
|
||||||
return false;
|
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 );
|
dataMap.put( DatabaseTaskJob.TASK_QUEUE, databaseUpdateQueue );
|
||||||
databaseJob.setJobDataMap( dataMap );
|
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
|
try
|
||||||
{
|
{
|
||||||
CronTrigger trigger = new CronTrigger( DATABASE_JOB_TRIGGER, DATABASE_SCAN_GROUP, cronString );
|
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.ArchivaTaskScheduler;
|
||||||
import org.apache.maven.archiva.scheduled.DefaultArchivaTaskScheduler;
|
import org.apache.maven.archiva.scheduled.DefaultArchivaTaskScheduler;
|
||||||
import org.apache.maven.archiva.scheduled.tasks.ArchivaTask;
|
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.scheduled.tasks.RepositoryTask;
|
||||||
import org.apache.maven.archiva.security.ArchivaRoleConstants;
|
import org.apache.maven.archiva.security.ArchivaRoleConstants;
|
||||||
import org.codehaus.plexus.redback.rbac.Resource;
|
import org.codehaus.plexus.redback.rbac.Resource;
|
||||||
|
@ -36,12 +37,16 @@ import org.codehaus.plexus.xwork.action.PlexusActionSupport;
|
||||||
/**
|
/**
|
||||||
* Configures the application.
|
* 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
|
extends PlexusActionSupport
|
||||||
implements SecureAction
|
implements SecureAction
|
||||||
{
|
{
|
||||||
|
private static final String REPO_SUCCESS = "repoSucces";
|
||||||
|
|
||||||
|
private static final String DB_SUCCESS = "dbSuccess";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @plexus.requirement
|
* @plexus.requirement
|
||||||
*/
|
*/
|
||||||
|
@ -49,7 +54,7 @@ public class IndexRepositoryAction
|
||||||
|
|
||||||
private String repoid;
|
private String repoid;
|
||||||
|
|
||||||
public String run()
|
public String scanRepository()
|
||||||
{
|
{
|
||||||
if ( StringUtils.isBlank( repoid ) )
|
if ( StringUtils.isBlank( repoid ) )
|
||||||
{
|
{
|
||||||
|
@ -106,6 +111,48 @@ public class IndexRepositoryAction
|
||||||
return SUCCESS;
|
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 )
|
public void addActionMessage( String aMessage )
|
||||||
{
|
{
|
||||||
super.addActionMessage( aMessage );
|
super.addActionMessage( aMessage );
|
|
@ -144,5 +144,6 @@ public class ConfigurationSynchronization
|
||||||
{
|
{
|
||||||
Banner.display( getLogger(), ArchivaVersion.determineVersion( this.getClass().getClassLoader() ) );
|
Banner.display( getLogger(), ArchivaVersion.determineVersion( this.getClass().getClassLoader() ) );
|
||||||
synchConfiguration();
|
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.objectFactory = org.codehaus.plexus.xwork.PlexusObjectFactory
|
||||||
webwork.url.includeParams = none
|
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
|
# 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>
|
<result name="confirm" type="redirect-action">deleteRepository</result>
|
||||||
</action>
|
</action>
|
||||||
|
|
||||||
<action name="indexRepository" class="indexRepositoryAction" method="run">
|
<action name="indexRepository" class="schedulerAction" method="scanRepository">
|
||||||
<result type="redirect-action">repositories</result>
|
<result type="redirect-action">repositories</result>
|
||||||
</action>
|
</action>
|
||||||
|
|
||||||
|
@ -344,6 +344,10 @@
|
||||||
<result name="input">/WEB-INF/jsp/admin/database.jsp</result>
|
<result name="input">/WEB-INF/jsp/admin/database.jsp</result>
|
||||||
</action>
|
</action>
|
||||||
|
|
||||||
|
<action name="updateDatabase" class="schedulerAction" method="updateDatabase">
|
||||||
|
<result type="redirect-action">database</result>
|
||||||
|
</action>
|
||||||
|
|
||||||
<!-- .\ CONFIGURATION \.___________________________________________ -->
|
<!-- .\ CONFIGURATION \.___________________________________________ -->
|
||||||
|
|
||||||
<action name="configure" class="configureAction" method="input">
|
<action name="configure" class="configureAction" method="input">
|
||||||
|
|
|
@ -57,6 +57,10 @@
|
||||||
</table>
|
</table>
|
||||||
</ww:form>
|
</ww:form>
|
||||||
|
|
||||||
|
<ww:form action="updateDatabase" theme="simple">
|
||||||
|
<ww:submit value="Update Database Now"/>
|
||||||
|
</ww:form>
|
||||||
|
|
||||||
<h2>Database - Unprocessed Artifacts Scanning</h2>
|
<h2>Database - Unprocessed Artifacts Scanning</h2>
|
||||||
|
|
||||||
<c:choose>
|
<c:choose>
|
||||||
|
|
|
@ -157,7 +157,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<redback:ifAuthorized permission="archiva-run-indexer">
|
<redback:ifAuthorized permission="archiva-run-indexer">
|
||||||
<ww:form action="indexRepository">
|
<ww:form action="indexRepository" theme="simple">
|
||||||
<ww:hidden name="repoid" value="%{'${repository.id}'}"/>
|
<ww:hidden name="repoid" value="%{'${repository.id}'}"/>
|
||||||
<ww:submit value="Scan Repository Now"/>
|
<ww:submit value="Scan Repository Now"/>
|
||||||
</ww:form>
|
</ww:form>
|
||||||
|
|
Loading…
Reference in New Issue