Browse Source

Refactoring index merger

pull/51/head
Martin Stockhammer 5 years ago
parent
commit
aa68c370b2
11 changed files with 168 additions and 111 deletions
  1. 1
    1
      archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/main/java/org/apache/archiva/admin/repository/group/DefaultRepositoryGroupAdmin.java
  2. 1
    1
      archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/mock/MockMergedRemoteIndexesScheduler.java
  3. 1
    1
      archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/indexer/ArchivaIndexManager.java
  4. 1
    1
      archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/indexer/merger/MergedRemoteIndexesScheduler.java
  5. 0
    1
      archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/indexer/merger/DefaultMergedRemoteIndexesScheduler.java
  6. 80
    9
      archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RepositoryRegistry.java
  7. 1
    1
      archiva-modules/archiva-maven/archiva-maven-indexer/src/main/java/org/apache/archiva/indexer/maven/DefaultIndexMerger.java
  8. 1
    1
      archiva-modules/archiva-maven/archiva-maven-indexer/src/main/java/org/apache/archiva/indexer/maven/MavenIndexContext.java
  9. 1
    9
      archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven2/MavenRepositoryProvider.java
  10. 3
    14
      archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven2/MavenRepositoryProviderTest.java
  11. 78
    72
      archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/ArchivaDavResourceFactory.java

+ 1
- 1
archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/main/java/org/apache/archiva/admin/repository/group/DefaultRepositoryGroupAdmin.java View File

import org.apache.archiva.configuration.Configuration; import org.apache.archiva.configuration.Configuration;
import org.apache.archiva.configuration.RepositoryGroupConfiguration; import org.apache.archiva.configuration.RepositoryGroupConfiguration;
import org.apache.archiva.metadata.model.facets.AuditEvent; import org.apache.archiva.metadata.model.facets.AuditEvent;
import org.apache.archiva.scheduler.MergedRemoteIndexesScheduler;
import org.apache.archiva.indexer.merger.MergedRemoteIndexesScheduler;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

+ 1
- 1
archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/src/test/java/org/apache/archiva/admin/mock/MockMergedRemoteIndexesScheduler.java View File

*/ */


import org.apache.archiva.admin.model.beans.RepositoryGroup; import org.apache.archiva.admin.model.beans.RepositoryGroup;
import org.apache.archiva.scheduler.MergedRemoteIndexesScheduler;
import org.apache.archiva.indexer.merger.MergedRemoteIndexesScheduler;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;


import java.nio.file.Path; import java.nio.file.Path;

+ 1
- 1
archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/indexer/ArchivaIndexManager.java View File

ArchivaIndexingContext move(ArchivaIndexingContext context, Repository repo) throws IndexCreationFailedException; ArchivaIndexingContext move(ArchivaIndexingContext context, Repository repo) throws IndexCreationFailedException;


/** /**
* Returns the local path where the index is stored.
* Updates the local path where the index is stored using the repository information.
* @return * @return
*/ */
public void updateLocalIndexPath(Repository repo); public void updateLocalIndexPath(Repository repo);

+ 1
- 1
archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/indexer/merger/MergedRemoteIndexesScheduler.java View File

package org.apache.archiva.scheduler;
package org.apache.archiva.indexer.merger;


/* /*
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one

+ 0
- 1
archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/indexer/merger/DefaultMergedRemoteIndexesScheduler.java View File



import org.apache.archiva.repository.ManagedRepository; import org.apache.archiva.repository.ManagedRepository;
import org.apache.archiva.repository.RepositoryGroup; import org.apache.archiva.repository.RepositoryGroup;
import org.apache.archiva.scheduler.MergedRemoteIndexesScheduler;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

+ 80
- 9
archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/RepositoryRegistry.java View File

* under the License. * under the License.
*/ */


import org.apache.archiva.configuration.ArchivaConfiguration;
import org.apache.archiva.configuration.Configuration;
import org.apache.archiva.configuration.ConfigurationEvent;
import org.apache.archiva.configuration.ConfigurationListener;
import org.apache.archiva.configuration.IndeterminateConfigurationException;
import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.archiva.configuration.ProxyConnectorConfiguration;
import org.apache.archiva.configuration.RemoteRepositoryConfiguration;
import org.apache.archiva.configuration.*;
import org.apache.archiva.indexer.ArchivaIndexManager; import org.apache.archiva.indexer.ArchivaIndexManager;
import org.apache.archiva.indexer.ArchivaIndexingContext; import org.apache.archiva.indexer.ArchivaIndexingContext;
import org.apache.archiva.indexer.IndexCreationFailedException; import org.apache.archiva.indexer.IndexCreationFailedException;
private Map<String, RemoteRepository> remoteRepositories = new HashMap<>( ); private Map<String, RemoteRepository> remoteRepositories = new HashMap<>( );
private Map<String, RemoteRepository> uRemoteRepositories = Collections.unmodifiableMap( remoteRepositories ); private Map<String, RemoteRepository> uRemoteRepositories = Collections.unmodifiableMap( remoteRepositories );


private Map<String, RepositoryGroup> repositoryGroups = new HashMap<>();
private Map<String, RepositoryGroup> uRepositoryGroups = Collections.unmodifiableMap(repositoryGroups);

private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock( ); private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock( );


public void setArchivaConfiguration( ArchivaConfiguration archivaConfiguration) { public void setArchivaConfiguration( ArchivaConfiguration archivaConfiguration) {
} }
remoteRepositories.clear( ); remoteRepositories.clear( );
remoteRepositories.putAll( getRemoteRepositoriesFromConfig( ) ); remoteRepositories.putAll( getRemoteRepositoriesFromConfig( ) );

repositoryGroups.clear();
repositoryGroups.putAll(getRepositorGroupsFromConfig());

// archivaConfiguration.addChangeListener(this); // archivaConfiguration.addChangeListener(this);
archivaConfiguration.addListener(this); archivaConfiguration.addListener(this);
} }
} }
} }


private Map<String, RepositoryGroup> getRepositorGroupsFromConfig( )
{
try
{
List<RepositoryGroupConfiguration> repositoryGroupConfigurations =
getArchivaConfiguration( ).getConfiguration( ).getRepositoryGroups();

if ( repositoryGroupConfigurations == null )
{
return Collections.emptyMap();
}

Map<String, RepositoryGroup> repositoryGroupMap = new LinkedHashMap<>( repositoryGroupConfigurations.size( ) );

Map<RepositoryType, RepositoryProvider> providerMap = createProviderMap( );
for ( RepositoryGroupConfiguration repoConfig : repositoryGroupConfigurations )
{
RepositoryType repositoryType = RepositoryType.valueOf( repoConfig.getType( ) );
if ( providerMap.containsKey( repositoryType ) )
{
try
{
RepositoryGroup repo = createNewRepositoryGroup( providerMap.get( repositoryType ), repoConfig );
repositoryGroupMap.put( repo.getId( ), repo );
}
catch ( Exception e )
{
log.error( "Could not create repository group {}: {}", repoConfig.getId( ), e.getMessage( ), e );
}
}
}
return repositoryGroupMap;
} catch (Throwable e) {
log.error("Could not initialize repositories from config: {}",e.getMessage(), e );
//noinspection unchecked
return Collections.emptyMap();
}
}

RepositoryGroup createNewRepositoryGroup(RepositoryProvider provider, RepositoryGroupConfiguration config) throws RepositoryException {
RepositoryGroup repositoryGroup = provider.createRepositoryGroup(config);
repositoryGroup.addListener(this);
updateRepositoryReferences(provider, repositoryGroup, config);
return repositoryGroup;
}

private void updateRepositoryReferences(RepositoryProvider provider, RepositoryGroup group, RepositoryGroupConfiguration configuration) {
if (group instanceof EditableRepositoryGroup) {
EditableRepositoryGroup eGroup = (EditableRepositoryGroup) group;
eGroup.setRepositories(configuration.getRepositories().stream().map(r -> getManagedRepository(r)).collect(Collectors.toList()));
}
}

private ArchivaConfiguration getArchivaConfiguration( ) private ArchivaConfiguration getArchivaConfiguration( )
{ {
return this.archivaConfiguration; return this.archivaConfiguration;
rwLock.readLock( ).lock( ); rwLock.readLock( ).lock( );
try try
{ {
return Stream.concat( managedRepositories.values( ).stream( ), remoteRepositories.values( ).stream( ) ).collect( Collectors.toList( ) );
return Stream.concat( managedRepositories.values( ).stream( ), remoteRepositories.values( ).stream( )).collect( Collectors.toList( ) );
} }
finally finally
{ {
} }
} }


public Collection<RepositoryGroup> getRepositoryGroups() {
rwLock.readLock().lock();
try {
return uRepositoryGroups.values();
} finally {
rwLock.readLock().unlock();
}
}

/** /**
* Returns the repository with the given id. The returned repository may be a managed or remote repository. * Returns the repository with the given id. The returned repository may be a managed or remote repository.
* It returns null, if no repository is registered with the given id. * It returns null, if no repository is registered with the given id.
} }
} }


public RepositoryGroup getRepositoryGroup( String groupId ) {
rwLock.readLock().lock();
try {
return repositoryGroups.get(groupId);
} finally {
rwLock.readLock().unlock();
}
}

/** /**
* Adds a new repository to the current list, or replaces the repository definition with * Adds a new repository to the current list, or replaces the repository definition with
* the same id, if it exists already. * the same id, if it exists already.

+ 1
- 1
archiva-modules/archiva-maven/archiva-maven-indexer/src/main/java/org/apache/archiva/indexer/maven/DefaultIndexMerger.java View File

package org.apache.archiva.indexer.maven.merger;
package org.apache.archiva.indexer.maven;
/* /*
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file * or more contributor license agreements. See the NOTICE file

+ 1
- 1
archiva-modules/archiva-maven/archiva-maven-indexer/src/main/java/org/apache/archiva/indexer/maven/MavenIndexContext.java View File

private IndexingContext delegate; private IndexingContext delegate;
private Repository repository; private Repository repository;


MavenIndexContext(Repository repository, IndexingContext delegate) {
protected MavenIndexContext(Repository repository, IndexingContext delegate) {
this.delegate = delegate; this.delegate = delegate;
this.repository = repository; this.repository = repository;



+ 1
- 9
archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/repository/maven2/MavenRepositoryProvider.java View File

import java.time.Period; import java.time.Period;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;


@Inject @Inject
private ArchivaConfiguration archivaConfiguration; private ArchivaConfiguration archivaConfiguration;


@Inject
private RepositoryRegistry repositoryRegistry;

@Inject @Inject
private FileLockManager fileLockManager; private FileLockManager fileLockManager;


@Override @Override
public void updateRepositoryGroupInstance(EditableRepositoryGroup repositoryGroup, RepositoryGroupConfiguration configuration) throws RepositoryException { public void updateRepositoryGroupInstance(EditableRepositoryGroup repositoryGroup, RepositoryGroupConfiguration configuration) throws RepositoryException {
repositoryGroup.setName(repositoryGroup.getPrimaryLocale(), configuration.getName()); repositoryGroup.setName(repositoryGroup.getPrimaryLocale(), configuration.getName());
repositoryGroup.setRepositories(configuration.getRepositories().stream().map(rid -> repositoryRegistry.getManagedRepository(rid)).collect(Collectors.toList()));
repositoryGroup.setMergedIndexPath(configuration.getMergedIndexPath()); repositoryGroup.setMergedIndexPath(configuration.getMergedIndexPath());
repositoryGroup.setMergedIndexTTL(configuration.getMergedIndexTtl()); repositoryGroup.setMergedIndexTTL(configuration.getMergedIndexTtl());
repositoryGroup.setSchedulingDefinition(configuration.getCronExpression()); repositoryGroup.setSchedulingDefinition(configuration.getCronExpression());
// References to other repositories are set filled by the registry
} }


@Override @Override
// //
} }


public void setRepositoryRegistry(RepositoryRegistry reg) {
this.repositoryRegistry = reg;
}
} }

+ 3
- 14
archiva-modules/archiva-maven/archiva-maven-repository/src/test/java/org/apache/archiva/repository/maven2/MavenRepositoryProviderTest.java View File

mockConfiguration.getConfiguration().getArchivaRuntimeConfiguration().setRepositoryBaseDirectory( "repositories" ); mockConfiguration.getConfiguration().getArchivaRuntimeConfiguration().setRepositoryBaseDirectory( "repositories" );
provider.setArchivaConfiguration( mockConfiguration ); provider.setArchivaConfiguration( mockConfiguration );


reg = new RepositoryRegistryMock();
reg.setArchivaConfiguration(mockConfiguration);
provider.setRepositoryRegistry(reg);
} }


@After @After


@Test @Test
public void createRepositoryGroupWithCfg() throws RepositoryException { public void createRepositoryGroupWithCfg() throws RepositoryException {
MavenManagedRepository repo1 = new MavenManagedRepository( "test01", "My Test repo", Paths.get("target/repositories") );

MavenManagedRepository repo2 = new MavenManagedRepository( "test02", "My Test repo", Paths.get("target/repositories") );
reg.putRepository(repo1);
reg.putRepository(repo2);

assertNotNull(reg.getManagedRepository("test01"));
assertNotNull(reg.getManagedRepository("test02"));


RepositoryGroupConfiguration cfg = new RepositoryGroupConfiguration(); RepositoryGroupConfiguration cfg = new RepositoryGroupConfiguration();
cfg.setId("group2"); cfg.setId("group2");
assertEquals("0 0 03 ? * MON", grp.getSchedulingDefinition()); assertEquals("0 0 03 ? * MON", grp.getSchedulingDefinition());
assertEquals(".index-abc", grp.getMergedIndexPath().getName()); assertEquals(".index-abc", grp.getMergedIndexPath().getName());
assertEquals(504, grp.getMergedIndexTTL()); assertEquals(504, grp.getMergedIndexTTL());
assertEquals(2, grp.getRepositories().size());
assertTrue(grp.getRepositories().stream().anyMatch(r -> "test01".equals(r.getId())));
assertTrue(grp.getRepositories().stream().anyMatch(r -> "test02".equals(r.getId())));
assertEquals(0, grp.getRepositories().size());
// assertTrue(grp.getRepositories().stream().anyMatch(r -> "test01".equals(r.getId())));
// assertTrue(grp.getRepositories().stream().anyMatch(r -> "test02".equals(r.getId())));
} }


} }

+ 78
- 72
archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/ArchivaDavResourceFactory.java View File

import org.apache.archiva.common.utils.VersionUtil; import org.apache.archiva.common.utils.VersionUtil;
import org.apache.archiva.configuration.ArchivaConfiguration; import org.apache.archiva.configuration.ArchivaConfiguration;
import org.apache.archiva.configuration.RepositoryGroupConfiguration; import org.apache.archiva.configuration.RepositoryGroupConfiguration;
import org.apache.archiva.indexer.ArchivaIndexingContext;
import org.apache.archiva.indexer.merger.IndexMerger; import org.apache.archiva.indexer.merger.IndexMerger;
import org.apache.archiva.indexer.merger.IndexMergerException; import org.apache.archiva.indexer.merger.IndexMergerException;
import org.apache.archiva.indexer.merger.IndexMergerRequest; import org.apache.archiva.indexer.merger.IndexMergerRequest;
import org.apache.archiva.redback.users.User; import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.UserManager; import org.apache.archiva.redback.users.UserManager;
import org.apache.archiva.repository.*; import org.apache.archiva.repository.*;
import org.apache.archiva.repository.content.FilesystemAsset;
import org.apache.archiva.repository.content.maven2.MavenRepositoryRequestInfo; import org.apache.archiva.repository.content.maven2.MavenRepositoryRequestInfo;
import org.apache.archiva.repository.events.AuditListener; import org.apache.archiva.repository.events.AuditListener;
import org.apache.archiva.repository.features.IndexCreationFeature; import org.apache.archiva.repository.features.IndexCreationFeature;


final String sRepoId = archivaLocator.getRepositoryId(); final String sRepoId = archivaLocator.getRepositoryId();


RepositoryGroupConfiguration repoGroupConfig =
archivaConfiguration.getConfiguration().getRepositoryGroupsAsMap().get( sRepoId );
RepositoryGroup repoGroup = repositoryRegistry.getRepositoryGroup(sRepoId);


final boolean isGroupRepo = repoGroupConfig != null;
final boolean isGroupRepo = repoGroup != null;


String activePrincipal = getActivePrincipal( request ); String activePrincipal = getActivePrincipal( request );


"Write method not allowed for repository groups." ); "Write method not allowed for repository groups." );
} }


log.debug( "Repository group '{}' accessed by '{}", repoGroupConfig.getId(), activePrincipal );
log.debug( "Repository group '{}' accessed by '{}", repoGroup.getId(), activePrincipal );


// handle browse requests for virtual repos // handle browse requests for virtual repos
if ( getLogicalResource( archivaLocator, null, true ).endsWith( "/" ) ) if ( getLogicalResource( archivaLocator, null, true ).endsWith( "/" ) )
{ {
DavResource davResource = DavResource davResource =
getResourceFromGroup( request, repoGroupConfig.getRepositories(), archivaLocator,
repoGroupConfig );
getResourceFromGroup( request, archivaLocator,
repoGroup );


setHeaders( response, locator, davResource, true ); setHeaders( response, locator, davResource, true );


// make a copy to avoid potential concurrent modifications (eg. by configuration) // make a copy to avoid potential concurrent modifications (eg. by configuration)
// TODO: ultimately, locking might be more efficient than copying in this fashion since updates are // TODO: ultimately, locking might be more efficient than copying in this fashion since updates are
// infrequent // infrequent
List<String> repositories = new ArrayList<>( repoGroupConfig.getRepositories() );
resource = processRepositoryGroup( request, archivaLocator, repositories, activePrincipal,
resourcesInAbsolutePath, repoGroupConfig );
for (String repoId: repositories ) {
ManagedRepository repo = repositoryRegistry.getManagedRepository(repoId);
resource = processRepositoryGroup( request, archivaLocator, activePrincipal,
resourcesInAbsolutePath, repoGroup );
for (ManagedRepository repo : repoGroup.getRepositories() ) {
if (repo!=null) { if (repo!=null) {
repositoryRequestInfo = repo.getRequestInfo(); repositoryRequestInfo = repo.getRequestInfo();
break; break;
} }


private DavResource processRepositoryGroup( final DavServletRequest request, private DavResource processRepositoryGroup( final DavServletRequest request,
ArchivaDavResourceLocator archivaLocator, List<String> repositories,
ArchivaDavResourceLocator archivaLocator,
String activePrincipal, List<String> resourcesInAbsolutePath, String activePrincipal, List<String> resourcesInAbsolutePath,
RepositoryGroupConfiguration repoGroupConfig )
RepositoryGroup repoGroup )
throws DavException throws DavException
{ {
DavResource resource = null; DavResource resource = null;


String rootPath = StringUtils.substringBeforeLast( pathInfo, "/" ); String rootPath = StringUtils.substringBeforeLast( pathInfo, "/" );


if ( StringUtils.endsWith( rootPath, repoGroupConfig.getMergedIndexPath() ) )
if ( StringUtils.endsWith( rootPath, repoGroup.getMergedIndexPath().getPath() ) )
{ {
// we are in the case of index file request // we are in the case of index file request
String requestedFileName = StringUtils.substringAfterLast( pathInfo, "/" ); String requestedFileName = StringUtils.substringAfterLast( pathInfo, "/" );
Path temporaryIndexDirectory = Path temporaryIndexDirectory =
buildMergedIndexDirectory( repositories, activePrincipal, request, repoGroupConfig );
buildMergedIndexDirectory( activePrincipal, request, repoGroup );
asset = new FilesystemAsset()


Path resourceFile = temporaryIndexDirectory.resolve( requestedFileName ); Path resourceFile = temporaryIndexDirectory.resolve( requestedFileName );
resource = new ArchivaDavResource( resourceFile.toAbsolutePath().toString(), requestedFileName, null,
request.getRemoteAddr(), activePrincipal, request.getDavSession(),
archivaLocator, this, mimeTypes, auditListeners, scheduler,
fileLockManager );
try {
resource = new ArchivaDavResource( resourceFile.toAbsolutePath().toString(), requestedFileName, null,
request.getRemoteAddr(), activePrincipal, request.getDavSession(),
archivaLocator, this, mimeTypes, auditListeners, scheduler );
} catch (LayoutException e) {
log.error("Bad layout: {}", e.getMessage(), e);
throw new DavException(500, e);
}


} }
else else
} }
} }


private DavResource getResourceFromGroup( DavServletRequest request, List<String> repositories,
private DavResource getResourceFromGroup( DavServletRequest request,
ArchivaDavResourceLocator locator, ArchivaDavResourceLocator locator,
RepositoryGroupConfiguration repositoryGroupConfiguration )
RepositoryGroup repositoryGroup )
throws DavException throws DavException
{ {
if ( repositoryGroupConfiguration.getRepositories() == null
|| repositoryGroupConfiguration.getRepositories().isEmpty() )
final String id = repositoryGroup.getId();
final List<ManagedRepository> repositories = repositoryGroup.getRepositories();
if ( repositories == null
|| repositories.isEmpty() )
{ {
Path file =
Paths.get( System.getProperty( "appserver.base" ), "groups/" + repositoryGroupConfiguration.getId() );

return new ArchivaDavResource( file.toString(), "groups/" + repositoryGroupConfiguration.getId(), null,
request.getDavSession(), locator, this, mimeTypes, auditListeners, scheduler,
fileLockManager );
try {
return new ArchivaDavResource( repositoryGroup.getAsset("/"), "groups/" + id, null,
request.getDavSession(), locator, this, mimeTypes, auditListeners, scheduler);
} catch (LayoutException e) {
log.error("Bad repository layout: {}", e.getMessage(), e);
throw new DavException(500, e);
}
} }
List<Path> mergedRepositoryContents = new ArrayList<>(); List<Path> mergedRepositoryContents = new ArrayList<>();
// multiple repo types so we guess they are all the same type
// so use the first one
// FIXME add a method with group in the repository storage
String firstRepoId = repositoryGroupConfiguration.getRepositories().get( 0 );


String path = getLogicalResource( locator, repositoryRegistry.getManagedRepository( firstRepoId ), false );
ManagedRepository firstRepo = repositories.get( 0 );

String path = getLogicalResource( locator, firstRepo, false );
if ( path.startsWith( "/" ) ) if ( path.startsWith( "/" ) )
{ {
path = path.substring( 1 ); path = path.substring( 1 );
if ( allow ) if ( allow )
{ {


if ( StringUtils.endsWith( pathInfo, repositoryGroupConfiguration.getMergedIndexPath() ) )
if ( StringUtils.endsWith( pathInfo, repositoryGroup.getMergedIndexPath().getPath() ) )
{ {
Path mergedRepoDir = Path mergedRepoDir =
buildMergedIndexDirectory( repositories, activePrincipal, request, repositoryGroupConfiguration );
buildMergedIndexDirectory( activePrincipal, request, repositoryGroup );
mergedRepositoryContents.add( mergedRepoDir ); mergedRepositoryContents.add( mergedRepoDir );
} }
else else
{ {
if ( StringUtils.equalsIgnoreCase( pathInfo, "/" + repositoryGroupConfiguration.getId() ) )
if ( StringUtils.equalsIgnoreCase( pathInfo, "/" + id ) )
{ {
Path tmpDirectory = Paths.get( SystemUtils.getJavaIoTmpDir().toString(), Path tmpDirectory = Paths.get( SystemUtils.getJavaIoTmpDir().toString(),
repositoryGroupConfiguration.getId(),
repositoryGroupConfiguration.getMergedIndexPath() );
id,
repositoryGroup.getMergedIndexPath().getFilePath().toString() );
if ( !Files.exists(tmpDirectory) ) if ( !Files.exists(tmpDirectory) )
{ {
synchronized ( tmpDirectory.toAbsolutePath().toString() ) synchronized ( tmpDirectory.toAbsolutePath().toString() )
} }
mergedRepositoryContents.add( tmpDirectory.getParent() ); mergedRepositoryContents.add( tmpDirectory.getParent() );
} }
for ( String repository : repositories )
for ( ManagedRepository repo : repositories )
{ {
ManagedRepositoryContent managedRepository = null; ManagedRepositoryContent managedRepository = null;
ManagedRepository repo = repositoryRegistry.getManagedRepository( repository );
if (repo == null) { if (repo == null) {
throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"Invalid managed repository <" + repository + ">");
"Invalid managed repository <" + repo.getId() + ">");
} }
managedRepository = repo.getContent(); managedRepository = repo.getContent();
if (managedRepository==null) { if (managedRepository==null) {
log.error("Inconsistency detected. Repository content not found for '{}'",repository);
log.error("Inconsistency detected. Repository content not found for '{}'",repo.getId());
throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"Invalid managed repository <" + repository + ">");
"Invalid managed repository <" + repo.getId() + ">");
} }
Path resourceFile = Paths.get( managedRepository.getRepoRoot(), logicalResource.getPath() ); Path resourceFile = Paths.get( managedRepository.getRepoRoot(), logicalResource.getPath() );
if ( Files.exists(resourceFile) ) if ( Files.exists(resourceFile) )
{ {
try try
{ {
if ( isAuthorized( request, repository ) )
if ( isAuthorized( request, repo.getId() ) )
{ {
mergedRepositoryContents.add( resourceFile ); mergedRepositoryContents.add( resourceFile );
log.debug( "Repository '{}' accessed by '{}'", repository, activePrincipal );
log.debug( "Repository '{}' accessed by '{}'", repo.getId(), activePrincipal );
} }
} }
catch ( DavException e ) catch ( DavException e )
// for the current user logged in // for the current user logged in
try try
{ {
if ( servletAuth.isAuthorized( activePrincipal, repository,
if ( servletAuth.isAuthorized( activePrincipal, repo.getId(),
WebdavMethodUtil.getMethodPermission( WebdavMethodUtil.getMethodPermission(
request.getMethod() ) ) ) request.getMethod() ) ) )
{ {
mergedRepositoryContents.add( resourceFile ); mergedRepositoryContents.add( resourceFile );
log.debug( "Repository '{}' accessed by '{}'", repository, activePrincipal );
log.debug( "Repository '{}' accessed by '{}'", repo.getId(), activePrincipal );
} }
} }
catch ( UnauthorizedException e ) catch ( UnauthorizedException e )
* @param activePrincipal * @param activePrincipal
* @return * @return
*/ */
private boolean isAllowedToContinue( DavServletRequest request, List<String> repositories, String activePrincipal )
private boolean isAllowedToContinue( DavServletRequest request, List<ManagedRepository> repositories, String activePrincipal )
{ {
// when no repositories configured it's impossible to browse nothing ! // when no repositories configured it's impossible to browse nothing !
// at least make possible to see nothing :-) // at least make possible to see nothing :-)
// if securitySession != null, it means that the user was prompted for authentication // if securitySession != null, it means that the user was prompted for authentication
if ( httpAuth.getSecuritySession( request.getSession() ) != null ) if ( httpAuth.getSecuritySession( request.getSession() ) != null )
{ {
for ( String repository : repositories )
for ( ManagedRepository repository : repositories )
{ {
try try
{ {
if ( isAuthorized( request, repository ) )
if ( isAuthorized( request, repository.getId() ) )
{ {
allow = true; allow = true;
break; break;
} }
else else
{ {
for ( String repository : repositories )
for ( ManagedRepository repository : repositories )
{ {
try try
{ {
if ( servletAuth.isAuthorized( activePrincipal, repository,
if ( servletAuth.isAuthorized( activePrincipal, repository.getId(),
WebdavMethodUtil.getMethodPermission( request.getMethod() ) ) ) WebdavMethodUtil.getMethodPermission( request.getMethod() ) ) )
{ {
allow = true; allow = true;
} }
} }


protected Path buildMergedIndexDirectory( List<String> repositories, String activePrincipal,
protected Path buildMergedIndexDirectory( String activePrincipal,
DavServletRequest request, DavServletRequest request,
RepositoryGroupConfiguration repositoryGroupConfiguration )
RepositoryGroup repositoryGroup )
throws DavException throws DavException
{ {


try try
{ {
final List<ManagedRepository> repositories = repositoryGroup.getRepositories();
HttpSession session = request.getSession(); HttpSession session = request.getSession();


@SuppressWarnings( "unchecked" ) Map<String, TemporaryGroupIndex> temporaryGroupIndexMap = @SuppressWarnings( "unchecked" ) Map<String, TemporaryGroupIndex> temporaryGroupIndexMap =
temporaryGroupIndexMap = new HashMap<>(); temporaryGroupIndexMap = new HashMap<>();
} }


TemporaryGroupIndex tmp = temporaryGroupIndexMap.get( repositoryGroupConfiguration.getId() );
final String id = repositoryGroup.getId();
TemporaryGroupIndex tmp = temporaryGroupIndexMap.get(id);


if ( tmp != null && tmp.getDirectory() != null && Files.exists(tmp.getDirectory())) if ( tmp != null && tmp.getDirectory() != null && Files.exists(tmp.getDirectory()))
{ {
if ( System.currentTimeMillis() - tmp.getCreationTime() > ( if ( System.currentTimeMillis() - tmp.getCreationTime() > (
repositoryGroupConfiguration.getMergedIndexTtl() * 60 * 1000 ) )
repositoryGroup.getMergedIndexTTL() * 60 * 1000 ) )
{ {
log.debug( MarkerFactory.getMarker( "group.merged.index" ), log.debug( MarkerFactory.getMarker( "group.merged.index" ),
"tmp group index '{}' is too old so delete it", repositoryGroupConfiguration.getId() );
"tmp group index '{}' is too old so delete it", id);
indexMerger.cleanTemporaryGroupIndex( tmp ); indexMerger.cleanTemporaryGroupIndex( tmp );
} }
else else
{ {
log.debug( MarkerFactory.getMarker( "group.merged.index" ), log.debug( MarkerFactory.getMarker( "group.merged.index" ),
"merged index for group '{}' found in cache", repositoryGroupConfiguration.getId() );
"merged index for group '{}' found in cache", id);
return tmp.getDirectory(); return tmp.getDirectory();
} }
} }


String permission = WebdavMethodUtil.getMethodPermission( request.getMethod() ); String permission = WebdavMethodUtil.getMethodPermission( request.getMethod() );


for ( String repository : repositories )
for ( ManagedRepository repository : repositories )
{ {
try try
{ {
if ( servletAuth.isAuthorized( activePrincipal, repository, permission ) )
if ( servletAuth.isAuthorized( activePrincipal, repository.getId(), permission ) )
{ {
authzRepos.add( repository );
authzRepos.addAll( this.repositorySearch.getRemoteIndexingContextIds( repository ) );
authzRepos.add( repository.getId() );
authzRepos.addAll( this.repositorySearch.getRemoteIndexingContextIds( repository.getId() ) );
} }
} }
catch ( UnauthorizedException e ) catch ( UnauthorizedException e )


} }
log.info( "generate temporary merged index for repository group '{}' for repositories '{}'", log.info( "generate temporary merged index for repository group '{}' for repositories '{}'",
repositoryGroupConfiguration.getId(), authzRepos );
id, authzRepos );


Path tempRepoFile = Files.createTempDirectory( "temp" ); Path tempRepoFile = Files.createTempDirectory( "temp" );
tempRepoFile.toFile().deleteOnExit(); tempRepoFile.toFile().deleteOnExit();


IndexMergerRequest indexMergerRequest = IndexMergerRequest indexMergerRequest =
new IndexMergerRequest( authzRepos, true, repositoryGroupConfiguration.getId(),
repositoryGroupConfiguration.getMergedIndexPath(),
repositoryGroupConfiguration.getMergedIndexTtl() ).mergedIndexDirectory(
new IndexMergerRequest( authzRepos, true, id,
repositoryGroup.getMergedIndexPath().getFilePath().toString(),
repositoryGroup.getMergedIndexTTL() ).mergedIndexDirectory(
tempRepoFile ).temporary( true ); tempRepoFile ).temporary( true );


MergedRemoteIndexesTaskRequest taskRequest = MergedRemoteIndexesTaskRequest taskRequest =


MergedRemoteIndexesTask job = new MergedRemoteIndexesTask( taskRequest ); MergedRemoteIndexesTask job = new MergedRemoteIndexesTask( taskRequest );


IndexingContext indexingContext = job.execute().getIndexingContext();
ArchivaIndexingContext indexingContext = job.execute().getIndexingContext();


Path mergedRepoDir = indexingContext.getIndexDirectoryFile().toPath();
Path mergedRepoDir = Paths.get(indexingContext.getPath());
TemporaryGroupIndex temporaryGroupIndex = TemporaryGroupIndex temporaryGroupIndex =
new TemporaryGroupIndex( mergedRepoDir, indexingContext.getId(), repositoryGroupConfiguration.getId(),
repositoryGroupConfiguration.getMergedIndexTtl() ) //
new TemporaryGroupIndex( mergedRepoDir, indexingContext.getId(), id,
repositoryGroup.getMergedIndexTTL() ) //
.setCreationTime( new Date().getTime() ); .setCreationTime( new Date().getTime() );
temporaryGroupIndexMap.put( repositoryGroupConfiguration.getId(), temporaryGroupIndex );
temporaryGroupIndexMap.put( id, temporaryGroupIndex );
session.setAttribute( TemporaryGroupIndexSessionCleaner.TEMPORARY_INDEX_SESSION_KEY, session.setAttribute( TemporaryGroupIndexSessionCleaner.TEMPORARY_INDEX_SESSION_KEY,
temporaryGroupIndexMap ); temporaryGroupIndexMap );
return mergedRepoDir; return mergedRepoDir;

Loading…
Cancel
Save