Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

NXCM-4799 guard against NPE during unsupported index operations

Reworked handling of isIndexable, isGroup, etc repository states
to make sure not applicable operations are not attempted, i.e.
adding items to not-indexable repository, etc.

Added null checks to shared and sharedSingle methods with a warning
if IndexingContext is null.

Signed-off-by: Igor Fedorenko <igor@ifedorenko.com>
  • Loading branch information...
commit 3f9d3ec1872948db434a0fc18b2a695b0a06aa93 1 parent 516f3ae
@ifedorenko ifedorenko authored
View
286 ...ns/indexer/nexus-indexer-lucene-plugin/src/main/java/org/sonatype/nexus/index/DefaultIndexerManager.java
@@ -191,6 +191,48 @@
private final Logger logger = LoggerFactory.getLogger(getClass());
+ /**
+ * Indexing is supported for this repository.
+ */
+ private boolean SUPPORTED( Repository repository )
+ {
+ return !repository.getRepositoryKind().isFacetAvailable( ShadowRepository.class )
+ && repository.getRepositoryKind().isFacetAvailable( MavenRepository.class )
+ && repository.getRepositoryContentClass().isCompatible( maven2 );
+ }
+
+ /**
+ * Index is maintained for the repository. Implies SUPPORTED.
+ */
+ private boolean INDEXABLE( Repository repository )
+ {
+ return SUPPORTED( repository ) && repository.isIndexable();
+ }
+
+ /**
+ * The repository is in service for indexing purposes
+ */
+ private boolean INSERVICE( Repository repository )
+ {
+ return LocalStatus.IN_SERVICE.equals( repository.getLocalStatus() );
+ }
+
+ /**
+ * Repository is a proxy repository.
+ */
+ private boolean ISPROXY( Repository repository )
+ {
+ return repository.getRepositoryKind().isFacetAvailable( MavenProxyRepository.class );
+ }
+
+ /**
+ * Repository is a group repository.
+ */
+ private boolean ISGROUP(Repository repository)
+ {
+ return repository.getRepositoryKind().isFacetAvailable( GroupRepository.class );
+ }
+
@Requirement
private NexusIndexer mavenIndexer;
@@ -318,55 +360,6 @@ public void resetConfiguration()
// Context management et al
// ----------------------------------------------------------------------------
- protected boolean isIndexingSupported( Repository repository )
- {
- // indexing is supported if:
- // repo has NO Shadow facet available (is not a shadow)
- // repo has facet MavenRepository available (is implementation tied)
- // repo had contentClass compatible with Maven2 contentClass
- return !repository.getRepositoryKind().isFacetAvailable( ShadowRepository.class )
- && repository.getRepositoryKind().isFacetAvailable( MavenRepository.class )
- && repository.getRepositoryContentClass().isCompatible( maven2 );
- }
-
- protected void logSkippingRepositoryMessage( Repository repository )
- {
- boolean isSupported = isIndexingSupported( repository );
- boolean isIndexed = repository.isIndexable();
-
- if ( logger.isDebugEnabled() )
- {
- StringBuilder sb = new StringBuilder( "Indexing is " );
-
- if ( !isSupported )
- {
- sb.append( "not " );
- }
-
- sb.append( "supported on repository \"" + repository.getName() + "\" (ID=\"" + repository.getId() + "\")" );
-
- if ( isSupported )
- {
- sb.append( " and is set as " );
-
- if ( !isIndexed )
- {
- sb.append( "not " );
- }
-
- sb.append( "indexed. " );
- }
- else
- {
- sb.append( ". " );
- }
-
- sb.append( "Skipping it." );
-
- logger.debug( sb.toString() );
- }
- }
-
public void addRepositoryIndexContext( String repositoryId )
throws IOException, NoSuchRepositoryException
{
@@ -378,6 +371,11 @@ public void addRepositoryIndexContext( String repositoryId )
public void addRepositoryIndexContext( final Repository repository )
throws IOException, NoSuchRepositoryException
{
+ if (!INDEXABLE( repository ))
+ {
+ return;
+ }
+
if ( repository.getRepositoryKind().isFacetAvailable( GroupRepository.class ) )
{
// group repository
@@ -411,13 +409,6 @@ private void addRepositoryIndexContext( final Repository repository, IndexingCon
repository.getId() );
}
- if ( !isIndexingSupported( repository ) || !repository.isIndexable() )
- {
- logSkippingRepositoryMessage( repository );
-
- return;
- }
-
IndexingContext ctx = null;
File indexDirectory = getRepositoryIndexDirectory( repository );
@@ -462,13 +453,6 @@ public void removeRepositoryIndexContext( String repositoryId, final boolean del
public void removeRepositoryIndexContext( final Repository repository, final boolean deleteFiles )
throws IOException
{
- if ( !isIndexingSupported( repository ) )
- {
- logSkippingRepositoryMessage( repository );
-
- return;
- }
-
exclusiveSingle( repository, new Runnable()
{
@Override
@@ -483,7 +467,7 @@ public void run( final IndexingContext context )
}
else
{
- logger.debug( "Could not remove null indexing context for repository {}", repository.getId() );
+ logger.debug( "Could not remove <null> indexing context for repository {}", repository.getId() );
}
}
} );
@@ -496,10 +480,8 @@ public void updateRepositoryIndexContext( final String repositoryId )
// cannot do "!repository.isIndexable()" since we may be called to handle that config change (using events)!
// the repo might be already non-indexable, but the context would still exist!
- if ( !isIndexingSupported( repository ) )
+ if ( !SUPPORTED( repository ) )
{
- logSkippingRepositoryMessage( repository );
-
return;
}
@@ -525,9 +507,9 @@ public void run( IndexingContext context )
// remove context, if it already existed (ctx != null) and any of the following is true:
// is a group OR repo path changed OR we have an isIndexed transition happening
if ( context != null
- && ( repository.getRepositoryKind().isFacetAvailable( GroupRepository.class )
- || !context.getRepository().getAbsolutePath().equals( repoRoot.getAbsolutePath() )
- || !repository.isIndexable() || context.isSearchable() != repository.isSearchable() ) )
+ && ( ISGROUP( repository ) || !INDEXABLE( repository )
+ || !context.getRepository().getAbsolutePath().equals( repoRoot.getAbsolutePath() )
+ || context.isSearchable() != repository.isSearchable() ) )
{
// remove the context
removeRepositoryIndexContext( repository, false );
@@ -536,7 +518,7 @@ public void run( IndexingContext context )
// add context, if it did not existed yet (ctx == null) or any of the following is true:
// is a group OR repo path changed OR we have an isIndexed transition happening
- if ( repository.isIndexable() && context == null )
+ if ( INDEXABLE( repository ) && context == null )
{
// recreate the context
try
@@ -616,21 +598,8 @@ protected NexusIndexer getNexusIndexer()
public void addItemToIndex( final Repository repository, final StorageItem item )
throws IOException
{
- // is indexing supported at all on this repository?
- // sadly, the nexus-indexer is maven2 only, hence we check is the repo
- // from where we get the event is a maven2 repo, is indexing supported at all
- if ( !isIndexingSupported( repository ) )
+ if ( !INDEXABLE( repository ) || !INSERVICE( repository ) )
{
- logSkippingRepositoryMessage( repository );
-
- return;
- }
-
- // do we have to maintain index context at all?
- if ( !repository.isIndexable() )
- {
- logSkippingRepositoryMessage( repository );
-
return;
}
@@ -733,29 +702,14 @@ private void addItemToIndex( Repository repository, StorageItem item, IndexingCo
public void removeItemFromIndex( final Repository repository, final StorageItem item )
throws IOException
{
- // is indexing supported at all on this repository?
- // sadly, the nexus-indexer is maven2 only, hence we check is the repo
- // from where we get the event is a maven2 repo, is indexing supported at all
- if ( !isIndexingSupported( repository ) || !MavenRepository.class.isAssignableFrom( repository.getClass() ) )
+ if ( !INDEXABLE( repository ) || !INSERVICE( repository ) )
{
- logSkippingRepositoryMessage( repository );
-
- return;
- }
-
- // do we have to maintain index context at all?
- if ( !repository.isIndexable() )
- {
- logSkippingRepositoryMessage( repository );
-
return;
}
// index for proxy repos shouldn't change just because you deleted something locally
- if ( repository.getRepositoryKind().isFacetAvailable( ProxyRepository.class ) )
+ if ( ISPROXY(repository) )
{
- logSkippingRepositoryMessage( repository );
-
return;
}
@@ -927,7 +881,7 @@ protected void reindexRepository( final String path, final Repository repository
if ( CASCADE )
{
- if ( repository.getRepositoryKind().isFacetAvailable( GroupRepository.class ) )
+ if ( ISGROUP( repository ) )
{
List<Repository> members = repository.adaptToFacet( GroupRepository.class ).getMemberRepositories();
@@ -955,22 +909,12 @@ protected void reindexRepository( final String path, final Repository repository
private void reindexRepository( final Repository repository, final String fromPath, final boolean fullReindex )
throws IOException
{
- if ( !LocalStatus.IN_SERVICE.equals( repository.getLocalStatus() ) )
- {
- return;
- }
-
- if ( !isIndexingSupported( repository ) )
- {
- return;
- }
-
- if ( !repository.isIndexable() )
+ if ( !INDEXABLE( repository ) || !INSERVICE( repository ) )
{
return;
}
- if ( repository.getRepositoryKind().isFacetAvailable( GroupRepository.class ) )
+ if ( ISGROUP( repository ) )
{
return;
}
@@ -986,7 +930,7 @@ private void reindexRepository( final Repository repository, final String fromPa
public void run( final IndexingContext context )
throws IOException
{
- if ( repository.getRepositoryKind().isFacetAvailable( ProxyRepository.class ) )
+ if ( ISPROXY( repository ) )
{
updateRemoteIndex( repository.adaptToFacet( ProxyRepository.class ), context, fullReindex );
}
@@ -1074,7 +1018,7 @@ public void downloadRepositoryIndex( final Repository repository, final Set<Stri
if ( CASCADE )
{
- if ( repository.getRepositoryKind().isFacetAvailable( GroupRepository.class ) )
+ if ( ISGROUP( repository ) )
{
List<Repository> members = repository.adaptToFacet( GroupRepository.class ).getMemberRepositories();
@@ -1085,7 +1029,7 @@ public void downloadRepositoryIndex( final Repository repository, final Set<Stri
}
}
- if ( repository.getRepositoryKind().isFacetAvailable( ProxyRepository.class ) )
+ if ( ISPROXY( repository ) )
{
downloadRepositoryIndex( repository.adaptToFacet( ProxyRepository.class ), false );
}
@@ -1096,19 +1040,7 @@ protected void downloadRepositoryIndex( final ProxyRepository repository, final
{
TaskUtil.checkInterruption();
- if ( !LocalStatus.IN_SERVICE.equals( repository.getLocalStatus() ) )
- {
- return;
- }
-
- if ( !isIndexingSupported( repository ) )
- {
- logSkippingRepositoryMessage( repository );
-
- return;
- }
-
- if ( !repository.isIndexable() )
+ if ( !INDEXABLE( repository ) || !ISPROXY( repository ) )
{
return;
}
@@ -1158,7 +1090,7 @@ private void updateRemoteIndex( final ProxyRepository repository, final Indexing
final boolean forceFullUpdate ) throws IOException
{
// ensure this is a proxy repo, since download may happen with proxies only
- if ( !repository.getRepositoryKind().isFacetAvailable( MavenProxyRepository.class ) )
+ if ( !INDEXABLE( repository ) || !ISPROXY( repository ) )
{
return;
}
@@ -1202,7 +1134,7 @@ public InputStream retrieve( String name )
// We need to use ProxyRepository and get it's RemoteStorage stuff to completely
// avoid "transparent" proxying, and even the slightest possibility to return
// some stale file from cache to the updater.
- if ( repository.getRepositoryKind().isFacetAvailable( ProxyRepository.class ) )
+ if ( ISPROXY( repository ) )
{
ProxyRepository proxy = repository.adaptToFacet( ProxyRepository.class );
@@ -1373,7 +1305,7 @@ protected void publishRepositoryIndex( final Repository repository, Set<String>
if ( CASCADE )
{
- if ( repository.getRepositoryKind().isFacetAvailable( GroupRepository.class ) )
+ if ( ISGROUP( repository ) )
{
List<Repository> members = repository.adaptToFacet( GroupRepository.class ).getMemberRepositories();
@@ -1394,21 +1326,7 @@ protected void publishRepositoryIndex( final Repository repository, Set<String>
protected void publishRepositoryIndex( final Repository repository )
throws IOException
{
- if ( !LocalStatus.IN_SERVICE.equals( repository.getLocalStatus() ) )
- {
- return;
- }
-
- // is indexing supported at all?
- if ( !isIndexingSupported( repository ) )
- {
- logSkippingRepositoryMessage( repository );
-
- return;
- }
-
- // shadows are not capable to publish indexes
- if ( !repository.isIndexable() )
+ if (!INDEXABLE( repository ) && !INSERVICE( repository ))
{
return;
}
@@ -1624,7 +1542,7 @@ protected void optimizeIndex( final Repository repository, final Set<String> pro
if ( CASCADE )
{
- if ( repository.getRepositoryKind().isFacetAvailable( GroupRepository.class ) )
+ if ( ISGROUP( repository ) )
{
GroupRepository group = repository.adaptToFacet( GroupRepository.class );
@@ -1645,7 +1563,7 @@ protected void optimizeIndex( final Repository repository, final Set<String> pro
protected void optimizeRepositoryIndex( final Repository repository )
throws CorruptIndexException, IOException
{
- if ( !LocalStatus.IN_SERVICE.equals( repository.getLocalStatus() ) )
+ if ( !INDEXABLE( repository ) )
{
return;
}
@@ -1696,7 +1614,7 @@ public FlatSearchResponse searchArtifactFlat( String term, String repositoryId,
bq.add( q2, BooleanClause.Occur.SHOULD );
- FlatSearchRequest req = new FlatSearchRequest( bq, ArtifactInfo.REPOSITORY_VERSION_COMPARATOR );;
+ FlatSearchRequest req = new FlatSearchRequest( bq, ArtifactInfo.REPOSITORY_VERSION_COMPARATOR );
// if ( from != null )
// {
@@ -2282,16 +2200,16 @@ public LockedIndexingContexts( Map<String,IndexingContext> contexts, Lock lock )
/**
* Executes the runnable while holding shared lock on the specified repository index. If the repository is a group,
* also acquires shared locks on all member repositories. Repositories without indexing contexts are silently
- * ignored. The context passed to the runnable is read-only, operations that modify index through
- * UnsupportedOperationException. The indexing context passed to the runnable can be after return from this method,
- * the caveat is that the context will return empty results after underlying Lucene index is closed.
+ * ignored. The context passed to the runnable is read-only, operations that modify index throw
+ * UnsupportedOperationException. The indexing context passed to the runnable can be used after return from this
+ * method, the caveat is that the context will return empty results after underlying Lucene index is closed.
*/
public void shared( Repository repository, Runnable runnable )
throws IOException
{
Lock lock = null;
IndexingContext lockedContext = null;
- if ( repository.getRepositoryKind().isFacetAvailable( GroupRepository.class ) )
+ if ( ISGROUP( repository ) )
{
Map<String, Repository> members = new HashMap<String, Repository>();
addGroupMembers( members, (GroupRepository) repository );
@@ -2360,6 +2278,10 @@ public Directory getIndexDirectory()
lock.unlock();
}
}
+ else
+ {
+ logger.warn( "Could not perform index operation on repository {}", repository.getId(), new Exception() );
+ }
}
/**
@@ -2373,11 +2295,22 @@ private void sharedSingle( Repository repository, Runnable runnable )
lock.lock();
try
{
- if (repository.isIndexable())
+ IndexingContext ctx = getRepositoryIndexContext( repository );
+ if ( ctx != null )
{
- IndexingContext ctx = getRepositoryIndexContext( repository );
runnable.run( ctx );
}
+ else
+ {
+ if ( logger.isDebugEnabled() )
+ {
+ // this always happens during RepositoryRegistry.addRepository, which triggers archetype-catalog.xml
+ // generation before the repository is added to the indexer manager.
+ // this is not expected to happen in any other cases, so logger.warn is not a typo
+ logger.warn( "Could not perform index operation on repository {}", repository.getId(),
+ new Exception() );
+ }
+ }
}
finally
{
@@ -2439,7 +2372,15 @@ public void run( IndexingContext target )
// and temporary context is populated based contains old/stale configuration
// need to detect when this happens based on target timestamp for example and skip replace
- target.replace( temporary.getIndexDirectory() );
+ if (target != null)
+ {
+ target.replace( temporary.getIndexDirectory() );
+ }
+ else
+ {
+ logger.warn( "Could not perform index operation on repository {}", repository.getId(),
+ new Exception() );
+ }
}
} );
}
@@ -2514,33 +2455,38 @@ private ReentrantLock getReindexLock( final Repository repository )
private LockedIndexingContexts lockSearchTargetIndexingContexts( String repositoryId )
throws NoSuchRepositoryException
{
- List<Repository> repositories;
+ List<Repository> repositories = new ArrayList<Repository>();
if ( repositoryId != null )
{
Repository repository = getRepository( repositoryId );
- if ( repository.getRepositoryKind().isFacetAvailable( GroupRepository.class ) )
+ if ( ISGROUP( repository ) )
{
Map<String, Repository> members = new HashMap<String, Repository>();
addGroupMembers( members, (GroupRepository) repository );
- repositories = new ArrayList<Repository>( members.values() );
+ repositories.addAll( members.values() );
}
else
{
- repositories = Collections.singletonList( repository );
+ repositories.add( repository );
}
}
else
{
- repositories = repositoryRegistry.getRepositories();
+ for ( Repository repository : repositoryRegistry.getRepositories() )
+ {
+ if ( INDEXABLE( repository ) && repository.isSearchable() && !ISGROUP( repository ) )
+ {
+ repositories.add( repository );
+ }
+ }
}
return lockIndexingContexts( repositories, null );
}
/**
- * Acquires shared locks on specified repositories. Not-searchable repositories and repositories without indexing
- * context are silently ignored. Returns read-only contexts that are safe to use without explicit repository index
- * locking/unlocking.
+ * Acquires shared locks on specified repositories. Repositories without indexing context are silently ignored.
+ * Returns read-only contexts that are safe to use without explicit repository index locking/unlocking.
*/
private LockedIndexingContexts lockIndexingContexts( Collection<Repository> repositories, String force )
{
@@ -2571,7 +2517,7 @@ public int compare( Repository o1, Repository o2 )
lock.lock(); // at this point repository index cannot be added or removed, we can safely use it
IndexingContext context = getRepositoryIndexContext( repository );
- if ( !repository.getId().equals( force ) && ( context == null || !context.isSearchable() ) )
+ if ( !repository.getId().equals( force ) && context == null )
{
lock.unlock();
continue;
@@ -2596,9 +2542,9 @@ public int compare( Repository o1, Repository o2 )
{
for ( Repository member : group.getMemberRepositories() )
{
- if ( !repositories.containsKey( member.getId() ) )
+ if ( INDEXABLE( member ) && !repositories.containsKey( member.getId() ) )
{
- if ( member.getRepositoryKind().isFacetAvailable( GroupRepository.class ) )
+ if ( ISGROUP( member ) )
{
addGroupMembers( repositories, (GroupRepository) member );
}
View
4 ...dexer/nexus-indexer-lucene-plugin/src/test/java/org/sonatype/nexus/index/AbstractIndexerManagerTest.java
@@ -31,7 +31,7 @@
public abstract class AbstractIndexerManagerTest
extends AbstractMavenRepoContentTests
{
- protected IndexerManager indexerManager;
+ protected DefaultIndexerManager indexerManager;
protected NexusScheduler nexusScheduler;
@@ -45,7 +45,7 @@ protected void setUp()
nexusConfiguration.saveConfiguration();
- indexerManager = lookup( IndexerManager.class );
+ indexerManager = (DefaultIndexerManager) lookup( IndexerManager.class );
nexusScheduler = lookup( NexusScheduler.class );
}
View
1  .../indexer/nexus-indexer-lucene-plugin/src/test/java/org/sonatype/nexus/index/DefaultIndexerManagerIT.java
@@ -12,7 +12,6 @@
*/
package org.sonatype.nexus.index;
-import java.io.IOException;
import java.util.Collection;
import org.apache.maven.index.ArtifactInfo;
View
230 ...lugins/indexer/nexus-indexer-lucene-plugin/src/test/java/org/sonatype/nexus/index/RepositoryStateIT.java
@@ -0,0 +1,230 @@
+/**
+ * Sonatype Nexus (TM) Open Source Version
+ * Copyright (c) 2007-2012 Sonatype, Inc.
+ * All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
+ *
+ * This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
+ * which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
+ *
+ * Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
+ * of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
+ * Eclipse Foundation. All other trademarks are the property of their respective owners.
+ */
+package org.sonatype.nexus.index;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.MatchAllDocsQuery;
+import org.apache.lucene.search.Query;
+import org.apache.maven.index.ArtifactInfo;
+import org.apache.maven.index.Field;
+import org.apache.maven.index.FlatSearchRequest;
+import org.apache.maven.index.FlatSearchResponse;
+import org.apache.maven.index.IteratorSearchResponse;
+import org.apache.maven.index.MAVEN;
+import org.apache.maven.index.NexusIndexer;
+import org.apache.maven.index.context.IndexingContext;
+import org.apache.maven.index.expr.SourcedSearchExpression;
+import org.junit.Assert;
+import org.junit.Test;
+import org.sonatype.nexus.proxy.NoSuchRepositoryException;
+import org.sonatype.nexus.proxy.ResourceStoreRequest;
+import org.sonatype.nexus.proxy.item.ContentLocator;
+import org.sonatype.nexus.proxy.item.DefaultStorageFileItem;
+import org.sonatype.nexus.proxy.item.FileContentLocator;
+import org.sonatype.nexus.proxy.item.StorageFileItem;
+import org.sonatype.nexus.proxy.item.StorageItem;
+import org.sonatype.nexus.proxy.maven.MavenRepository;
+import org.sonatype.nexus.proxy.storage.UnsupportedStorageOperationException;
+
+public class RepositoryStateIT
+ extends AbstractIndexerManagerTest
+{
+ private NexusIndexer mavenIndexer;
+
+ private static final ContentLocator contentLocator = new ContentLocator()
+ {
+ @Override
+ public boolean isReusable()
+ {
+ return false;
+ }
+
+ @Override
+ public String getMimeType()
+ {
+ return null;
+ }
+
+ @Override
+ public InputStream getContent()
+ throws IOException
+ {
+ return null;
+ }
+ };
+
+ @Override
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ mavenIndexer = lookup( NexusIndexer.class );
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ mavenIndexer = null;
+
+ super.tearDown();
+ }
+
+ @Test
+ public void testNotIndexable()
+ throws Exception
+ {
+ releases.setIndexable( false );
+ nexusConfiguration.saveConfiguration();
+ wairForAsyncEventsToCalmDown();
+ waitForTasksToStop();
+
+ // ideally this test should verify that indexer manager ignores non-indexable repositories
+ // but at least make sure indexer manager does not throw exceptions
+
+ indexerManager.addRepositoryIndexContext( releases.getId() );
+
+ // not-indexable repository do not have indexing context
+ Assert.assertNull( indexerManager.getRepositoryIndexContext( releases ) );
+
+ // TODO figure out how to assert these operations don't do anything
+
+ ResourceStoreRequest request = new ResourceStoreRequest( "item", true, false );
+ StorageFileItem item =
+ new DefaultStorageFileItem( releases, request, true /* canRead */, true/* canWrite */, contentLocator );
+
+ indexerManager.addItemToIndex( releases, item );
+ indexerManager.removeItemFromIndex( apacheSnapshots, item );
+
+ indexerManager.reindexRepository( "/", releases.getId(), true );
+ indexerManager.optimizeRepositoryIndex( releases.getId() );
+
+ Query query = new MatchAllDocsQuery();
+ IteratorSearchResponse iterator =
+ indexerManager.searchQueryIterator( query, releases.getId(), null /* from */, null/* count */,
+ null/* hitLimit */, false/* uniqueRGA */, null/* filters */);
+ iterator.close();
+
+ iterator =
+ indexerManager.searchQueryIterator( query, null/* repositoryId */, null /* from */, null/* count */,
+ null/* hitLimit */, false/* uniqueRGA */, null/* filters */);
+ iterator.close();
+
+ indexerManager.removeRepositoryIndexContext( releases.getId(), false );
+ }
+
+ @Test
+ public void testNotSearchable()
+ throws Exception
+ {
+ // searchable flag only affects untargeted queries
+
+ fillInRepo();
+
+ snapshots.setSearchable( false );
+ nexusConfiguration.saveConfiguration();
+ wairForAsyncEventsToCalmDown();
+ waitForTasksToStop();
+
+ IndexingContext ctx = indexerManager.getRepositoryIndexContext( snapshots );
+
+ Assert.assertNotNull( ctx );
+
+ String itemPath =
+ "/org/sonatype/plexus/plexus-plugin-manager/1.1-SNAPSHOT/plexus-plugin-manager-1.1-20081125.071530-1.pom";
+ deployFile( snapshots, "apache-snapshots-2", itemPath );
+
+ StorageItem item = createItem( snapshots, itemPath );
+
+ indexerManager.addItemToIndex( snapshots, item );
+ Assert.assertNull( search( (MavenRepository) null, "org.sonatype.plexus", "plexus-plugin-manager",
+ "1.1-SNAPSHOT" ) );
+ Assert.assertNotNull( search( snapshots, "org.sonatype.plexus", "plexus-plugin-manager", "1.1-SNAPSHOT" ) );
+
+ indexerManager.removeItemFromIndex( snapshots, item );
+ Assert.assertNull( search( (MavenRepository) null, "org.sonatype.plexus", "plexus-plugin-manager",
+ "1.1-SNAPSHOT" ) );
+ Assert.assertNull( search( snapshots, "org.sonatype.nexus", "plexus-plugin-manager", "1.1-SNAPSHOT" ) );
+
+ indexerManager.reindexRepository( null, snapshots.getId(), true );
+ // TODO assert
+
+ indexerManager.optimizeRepositoryIndex( snapshots.getId() );
+ // TODO assert
+
+ indexerManager.removeRepositoryIndexContext( snapshots.getId(), false );
+
+ Assert.assertNull( indexerManager.getRepositoryIndexContext( snapshots ) );
+ }
+
+ private void deployFile( MavenRepository repository, String repoFrom, String path )
+ throws IOException, UnsupportedStorageOperationException
+ {
+ File repos = new File( getBasedir(), "src/test/resources/reposes" ).getCanonicalFile();
+ FileContentLocator content = new FileContentLocator( new File( repos, repoFrom + path ), "mime-type" );
+ ResourceStoreRequest request = new ResourceStoreRequest( path );
+ StorageItem item = new DefaultStorageFileItem( repository, request, true, true, content );
+ repository.getLocalStorage().storeItem( repository, item );
+ }
+
+ private BooleanQuery newGavQuery( String groupId, String artifactId, String version )
+ {
+ BooleanQuery query = new BooleanQuery();
+ addBooleanClause( query, MAVEN.GROUP_ID, groupId );
+ addBooleanClause( query, MAVEN.ARTIFACT_ID, artifactId );
+ addBooleanClause( query, MAVEN.VERSION, version );
+ return query;
+ }
+
+ private void addBooleanClause( BooleanQuery query, Field field, String value )
+ {
+ query.add( mavenIndexer.constructQuery( field, new SourcedSearchExpression( value ) ),
+ BooleanClause.Occur.MUST );
+ }
+
+ private ArtifactInfo search( MavenRepository repository, String groupId, String artifactId, String version )
+ throws NoSuchRepositoryException, IOException
+ {
+ BooleanQuery query = newGavQuery( groupId, artifactId, version );
+ String repoId = repository != null ? repository.getId() : null;
+ IteratorSearchResponse iterator =
+ indexerManager.searchQueryIterator( query, repoId, null, null, null, false, null );
+ try
+ {
+ if ( iterator.getTotalHitsCount() == 0 )
+ {
+ return null;
+ }
+ Assert.assertEquals( 1, iterator.getTotalHitsCount() );
+ ArtifactInfo ai = iterator.iterator().next();
+ Assert.assertEquals( version, ai.version );
+ return ai;
+ }
+ finally
+ {
+ iterator.close();
+ }
+ }
+
+ private StorageItem createItem( MavenRepository repository, String path )
+ throws Exception
+ {
+ return repository.retrieveItem( new ResourceStoreRequest( path ) );
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.