From bf565c3f3a5d59112794a9db994d00c9dc800f49 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Fri, 25 May 2007 18:33:59 +0000 Subject: [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 --- .../consumers/lucene/IndexArtifactConsumer.java | 141 ++++++++++++++-- .../scheduled/DefaultArchivaTaskScheduler.java | 9 + .../web/action/admin/IndexRepositoryAction.java | 141 ---------------- .../archiva/web/action/admin/SchedulerAction.java | 188 +++++++++++++++++++++ .../web/startup/ConfigurationSynchronization.java | 1 + .../src/main/resources/webwork.properties | 2 +- .../archiva-webapp/src/main/resources/xwork.xml | 6 +- .../src/main/webapp/WEB-INF/jsp/admin/database.jsp | 4 + .../main/webapp/WEB-INF/jsp/admin/repositories.jsp | 2 +- 9 files changed, 340 insertions(+), 154 deletions(-) delete mode 100644 archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/IndexRepositoryAction.java create mode 100644 archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/SchedulerAction.java diff --git a/archiva-base/archiva-consumers/archiva-lucene-consumers/src/main/java/org/apache/maven/archiva/consumers/lucene/IndexArtifactConsumer.java b/archiva-base/archiva-consumers/archiva-lucene-consumers/src/main/java/org/apache/maven/archiva/consumers/lucene/IndexArtifactConsumer.java index 1038cb372..6f9ecff45 100644 --- a/archiva-base/archiva-consumers/archiva-lucene-consumers/src/main/java/org/apache/maven/archiva/consumers/lucene/IndexArtifactConsumer.java +++ b/archiva-base/archiva-consumers/archiva-lucene-consumers/src/main/java/org/apache/maven/archiva/consumers/lucene/IndexArtifactConsumer.java @@ -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; + } } diff --git a/archiva-scheduled/src/main/java/org/apache/maven/archiva/scheduled/DefaultArchivaTaskScheduler.java b/archiva-scheduled/src/main/java/org/apache/maven/archiva/scheduled/DefaultArchivaTaskScheduler.java index 083e9b07d..8d0e5690d 100644 --- a/archiva-scheduled/src/main/java/org/apache/maven/archiva/scheduled/DefaultArchivaTaskScheduler.java +++ b/archiva-scheduled/src/main/java/org/apache/maven/archiva/scheduled/DefaultArchivaTaskScheduler.java @@ -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 ); diff --git a/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/IndexRepositoryAction.java b/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/IndexRepositoryAction.java deleted file mode 100644 index fcb345892..000000000 --- a/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/IndexRepositoryAction.java +++ /dev/null @@ -1,141 +0,0 @@ -package org.apache.maven.archiva.web.action.admin; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.commons.lang.StringUtils; -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.RepositoryTask; -import org.apache.maven.archiva.security.ArchivaRoleConstants; -import org.codehaus.plexus.redback.rbac.Resource; -import org.codehaus.plexus.redback.xwork.interceptor.SecureAction; -import org.codehaus.plexus.redback.xwork.interceptor.SecureActionBundle; -import org.codehaus.plexus.redback.xwork.interceptor.SecureActionException; -import org.codehaus.plexus.taskqueue.TaskQueueException; -import org.codehaus.plexus.xwork.action.PlexusActionSupport; - -/** - * Configures the application. - * - * @plexus.component role="com.opensymphony.xwork.Action" role-hint="indexRepositoryAction" - */ -public class IndexRepositoryAction - extends PlexusActionSupport - implements SecureAction -{ - /** - * @plexus.requirement - */ - private ArchivaTaskScheduler taskScheduler; - - private String repoid; - - public String run() - { - if ( StringUtils.isBlank( repoid ) ) - { - addActionError( "Cannot run indexer on blank repository id." ); - return SUCCESS; - } - - RepositoryTask task = new RepositoryTask(); - task.setRepositoryId( repoid ); - task.setName( DefaultArchivaTaskScheduler.REPOSITORY_JOB + ":" + repoid ); - task.setQueuePolicy( ArchivaTask.QUEUE_POLICY_WAIT ); - - boolean scheduleTask = false; - - try - { - if ( taskScheduler.isProcessingAnyRepositoryTask() ) - { - if ( taskScheduler.isProcessingRepositoryTask( repoid ) ) - { - addActionError( "Repository [" + repoid + "] task was already queued." ); - } - else - { - scheduleTask = true; - } - } - else - { - scheduleTask = true; - } - } - catch ( ArchivaException e ) - { - scheduleTask = false; - addActionError( e.getMessage() ); - } - - if ( scheduleTask ) - { - try - { - taskScheduler.queueRepositoryTask( task ); - addActionMessage( "Your request to have repository [" + repoid + "] be indexed has been queued." ); - } - catch ( TaskQueueException e ) - { - addActionError( "Unable to queue your request to have repository [" + repoid + "] be indexed: " - + e.getMessage() ); - } - } - - // Return to the repositories screen. - return SUCCESS; - } - - public void addActionMessage( String aMessage ) - { - super.addActionMessage( aMessage ); - getLogger().info( "[ActionMessage] " + aMessage ); - } - - public void addActionError( String anErrorMessage ) - { - super.addActionError( anErrorMessage ); - getLogger().warn( "[ActionError] " + anErrorMessage ); - } - - public SecureActionBundle getSecureActionBundle() - throws SecureActionException - { - SecureActionBundle bundle = new SecureActionBundle(); - - bundle.setRequiresAuthentication( true ); - bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_RUN_INDEXER, Resource.GLOBAL ); - - return bundle; - } - - public String getRepoid() - { - return repoid; - } - - public void setRepoid( String repoid ) - { - this.repoid = repoid; - } -} diff --git a/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/SchedulerAction.java b/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/SchedulerAction.java new file mode 100644 index 000000000..fb0db8436 --- /dev/null +++ b/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/action/admin/SchedulerAction.java @@ -0,0 +1,188 @@ +package org.apache.maven.archiva.web.action.admin; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.commons.lang.StringUtils; +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; +import org.codehaus.plexus.redback.xwork.interceptor.SecureAction; +import org.codehaus.plexus.redback.xwork.interceptor.SecureActionBundle; +import org.codehaus.plexus.redback.xwork.interceptor.SecureActionException; +import org.codehaus.plexus.taskqueue.TaskQueueException; +import org.codehaus.plexus.xwork.action.PlexusActionSupport; + +/** + * Configures the application. + * + * @plexus.component role="com.opensymphony.xwork.Action" role-hint="schedulerAction" + */ +public class SchedulerAction + extends PlexusActionSupport + implements SecureAction +{ + private static final String REPO_SUCCESS = "repoSucces"; + + private static final String DB_SUCCESS = "dbSuccess"; + + /** + * @plexus.requirement + */ + private ArchivaTaskScheduler taskScheduler; + + private String repoid; + + public String scanRepository() + { + if ( StringUtils.isBlank( repoid ) ) + { + addActionError( "Cannot run indexer on blank repository id." ); + return SUCCESS; + } + + RepositoryTask task = new RepositoryTask(); + task.setRepositoryId( repoid ); + task.setName( DefaultArchivaTaskScheduler.REPOSITORY_JOB + ":" + repoid ); + task.setQueuePolicy( ArchivaTask.QUEUE_POLICY_WAIT ); + + boolean scheduleTask = false; + + try + { + if ( taskScheduler.isProcessingAnyRepositoryTask() ) + { + if ( taskScheduler.isProcessingRepositoryTask( repoid ) ) + { + addActionError( "Repository [" + repoid + "] task was already queued." ); + } + else + { + scheduleTask = true; + } + } + else + { + scheduleTask = true; + } + } + catch ( ArchivaException e ) + { + scheduleTask = false; + addActionError( e.getMessage() ); + } + + if ( scheduleTask ) + { + try + { + taskScheduler.queueRepositoryTask( task ); + addActionMessage( "Your request to have repository [" + repoid + "] be indexed has been queued." ); + } + catch ( TaskQueueException e ) + { + addActionError( "Unable to queue your request to have repository [" + repoid + "] be indexed: " + + e.getMessage() ); + } + } + + // Return to the repositories screen. + 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 ); + getLogger().info( "[ActionMessage] " + aMessage ); + } + + public void addActionError( String anErrorMessage ) + { + super.addActionError( anErrorMessage ); + getLogger().warn( "[ActionError] " + anErrorMessage ); + } + + public SecureActionBundle getSecureActionBundle() + throws SecureActionException + { + SecureActionBundle bundle = new SecureActionBundle(); + + bundle.setRequiresAuthentication( true ); + bundle.addRequiredAuthorization( ArchivaRoleConstants.OPERATION_RUN_INDEXER, Resource.GLOBAL ); + + return bundle; + } + + public String getRepoid() + { + return repoid; + } + + public void setRepoid( String repoid ) + { + this.repoid = repoid; + } +} diff --git a/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/startup/ConfigurationSynchronization.java b/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/startup/ConfigurationSynchronization.java index d6e4fecce..a6b62c117 100644 --- a/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/startup/ConfigurationSynchronization.java +++ b/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/startup/ConfigurationSynchronization.java @@ -144,5 +144,6 @@ public class ConfigurationSynchronization { Banner.display( getLogger(), ArchivaVersion.determineVersion( this.getClass().getClassLoader() ) ); synchConfiguration(); + archivaConfiguration.addChangeListener( this ); } } diff --git a/archiva-web/archiva-webapp/src/main/resources/webwork.properties b/archiva-web/archiva-webapp/src/main/resources/webwork.properties index b53334909..d9155d8ca 100644 --- a/archiva-web/archiva-webapp/src/main/resources/webwork.properties +++ b/archiva-web/archiva-webapp/src/main/resources/webwork.properties @@ -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 diff --git a/archiva-web/archiva-webapp/src/main/resources/xwork.xml b/archiva-web/archiva-webapp/src/main/resources/xwork.xml index 73cc1bfb5..79aeb4a7e 100644 --- a/archiva-web/archiva-webapp/src/main/resources/xwork.xml +++ b/archiva-web/archiva-webapp/src/main/resources/xwork.xml @@ -238,7 +238,7 @@ deleteRepository - + repositories @@ -344,6 +344,10 @@ /WEB-INF/jsp/admin/database.jsp + + database + + diff --git a/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/database.jsp b/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/database.jsp index 04a7e2ba0..7c34f97f8 100644 --- a/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/database.jsp +++ b/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/database.jsp @@ -56,6 +56,10 @@ + + + +

Database - Unprocessed Artifacts Scanning

diff --git a/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/repositories.jsp b/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/repositories.jsp index 7d3af58c6..7b3a9ca39 100644 --- a/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/repositories.jsp +++ b/archiva-web/archiva-webapp/src/main/webapp/WEB-INF/jsp/admin/repositories.jsp @@ -157,7 +157,7 @@ - + -- cgit v1.2.3