From: Martin Stockhammer Date: Wed, 10 Jul 2019 20:07:35 +0000 (+0200) Subject: Fixing test failures after refactoring X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=7eb0f48b5ad907dd9e0136e234865cf08a8cbdab;p=archiva.git Fixing test failures after refactoring --- diff --git a/archiva-modules/archiva-base/archiva-converter/src/main/java/org/apache/archiva/converter/legacy/DefaultLegacyRepositoryConverter.java b/archiva-modules/archiva-base/archiva-converter/src/main/java/org/apache/archiva/converter/legacy/DefaultLegacyRepositoryConverter.java index d5a108804..209fa8f99 100644 --- a/archiva-modules/archiva-base/archiva-converter/src/main/java/org/apache/archiva/converter/legacy/DefaultLegacyRepositoryConverter.java +++ b/archiva-modules/archiva-base/archiva-converter/src/main/java/org/apache/archiva/converter/legacy/DefaultLegacyRepositoryConverter.java @@ -19,13 +19,17 @@ package org.apache.archiva.converter.legacy; * under the License. */ +import org.apache.archiva.common.filelock.DefaultFileLockManager; import org.apache.archiva.common.plexusbridge.PlexusSisuBridge; import org.apache.archiva.common.plexusbridge.PlexusSisuBridgeException; import org.apache.archiva.common.utils.PathUtil; +import org.apache.archiva.configuration.FileTypes; import org.apache.archiva.consumers.InvalidRepositoryContentConsumer; import org.apache.archiva.consumers.KnownRepositoryContentConsumer; import org.apache.archiva.converter.RepositoryConversionException; import org.apache.archiva.repository.BasicManagedRepository; +import org.apache.archiva.repository.content.FilesystemStorage; +import org.apache.archiva.repository.content.maven2.ManagedDefaultRepositoryContent; import org.apache.archiva.repository.scanner.RepositoryScanner; import org.apache.archiva.repository.scanner.RepositoryScannerException; import org.apache.maven.artifact.repository.ArtifactRepository; @@ -36,6 +40,7 @@ import org.springframework.stereotype.Service; import javax.inject.Inject; import javax.inject.Named; +import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; @@ -61,6 +66,9 @@ public class DefaultLegacyRepositoryConverter */ private ArtifactRepositoryLayout defaultLayout; + @Inject + FileTypes fileTypes; + /** * */ @@ -94,6 +102,9 @@ public class DefaultLegacyRepositoryConverter BasicManagedRepository legacyRepository = new BasicManagedRepository( "legacy", "Legacy Repository", repositoryDirectory.getParent()); legacyRepository.setLocation( legacyRepositoryDirectory.toAbsolutePath().toUri() ); legacyRepository.setLayout( "legacy" ); + DefaultFileLockManager lockManager = new DefaultFileLockManager(); + FilesystemStorage storage = new FilesystemStorage(legacyRepositoryDirectory, lockManager); + legacyRepository.setContent(new ManagedDefaultRepositoryContent(legacyRepository, fileTypes, lockManager)); ArtifactRepository repository = new MavenArtifactRepository("default", defaultRepositoryUrl, defaultLayout, null, null); @@ -110,7 +121,7 @@ public class DefaultLegacyRepositoryConverter repoScanner.scan( legacyRepository, knownConsumers, invalidConsumers, ignoredContent, RepositoryScanner.FRESH_SCAN ); } - catch ( RepositoryScannerException e ) + catch (RepositoryScannerException | IOException e ) { throw new RepositoryConversionException( "Error convering legacy repository.", e ); } diff --git a/archiva-modules/archiva-base/archiva-repository-scanner/src/main/java/org/apache/archiva/repository/scanner/DefaultRepositoryScanner.java b/archiva-modules/archiva-base/archiva-repository-scanner/src/main/java/org/apache/archiva/repository/scanner/DefaultRepositoryScanner.java index 8df894ee6..d09863eee 100644 --- a/archiva-modules/archiva-base/archiva-repository-scanner/src/main/java/org/apache/archiva/repository/scanner/DefaultRepositoryScanner.java +++ b/archiva-modules/archiva-base/archiva-repository-scanner/src/main/java/org/apache/archiva/repository/scanner/DefaultRepositoryScanner.java @@ -25,6 +25,7 @@ import org.apache.archiva.consumers.InvalidRepositoryContentConsumer; import org.apache.archiva.consumers.KnownRepositoryContentConsumer; import org.apache.archiva.consumers.RepositoryContentConsumer; import org.apache.archiva.repository.ManagedRepository; +import org.apache.archiva.repository.content.StorageAsset; import org.apache.commons.collections4.CollectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -96,20 +97,20 @@ public class DefaultRepositoryScanner throw new IllegalArgumentException( "Unable to operate on a null repository." ); } - Path repositoryBase = Paths.get( repository.getLocation() ); + StorageAsset repositoryBase = repository.getContent().getAsset(""); //MRM-1342 Repository statistics report doesn't appear to be working correctly //create the repo if not existing to have an empty stats - if ( !Files.exists(repositoryBase)) + if ( !repositoryBase.exists()) { try { - Files.createDirectories(repositoryBase); + repositoryBase.create(); } catch (IOException e) { throw new UnsupportedOperationException("Unable to scan a repository, directory " + repositoryBase + " does not exist." ); } } - if ( !Files.isDirectory(repositoryBase) ) + if ( !repositoryBase.isContainer()) { throw new UnsupportedOperationException( "Unable to scan a repository, path " + repositoryBase+ " is not a directory." ); @@ -139,7 +140,7 @@ public class DefaultRepositoryScanner RepositoryScanStatistics stats = null; try { - Files.walkFileTree(repositoryBase, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, scannerInstance); + Files.walkFileTree(repositoryBase.getFilePath(), EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, scannerInstance); stats = scannerInstance.getStatistics(); diff --git a/archiva-modules/archiva-base/archiva-repository-scanner/src/test/java/org/apache/archiva/repository/scanner/RepositoryScannerTest.java b/archiva-modules/archiva-base/archiva-repository-scanner/src/test/java/org/apache/archiva/repository/scanner/RepositoryScannerTest.java index ac867089b..9e08f64a0 100644 --- a/archiva-modules/archiva-base/archiva-repository-scanner/src/test/java/org/apache/archiva/repository/scanner/RepositoryScannerTest.java +++ b/archiva-modules/archiva-base/archiva-repository-scanner/src/test/java/org/apache/archiva/repository/scanner/RepositoryScannerTest.java @@ -20,6 +20,8 @@ package org.apache.archiva.repository.scanner; */ import junit.framework.TestCase; +import org.apache.archiva.common.filelock.DefaultFileLockManager; +import org.apache.archiva.common.filelock.FileLockManager; import org.apache.archiva.consumers.InvalidRepositoryContentConsumer; import org.apache.archiva.consumers.KnownRepositoryContentConsumer; import org.apache.archiva.repository.BasicManagedRepository; @@ -27,6 +29,8 @@ import org.apache.archiva.repository.BasicRemoteRepository; import org.apache.archiva.repository.EditableManagedRepository; import org.apache.archiva.repository.EditableRemoteRepository; import org.apache.archiva.repository.ManagedRepository; +import org.apache.archiva.repository.content.FilesystemStorage; +import org.apache.archiva.repository.scanner.mock.ManagedRepositoryContentMock; import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner; import org.apache.commons.io.FileUtils; import org.junit.Test; @@ -62,10 +66,12 @@ public class RepositoryScannerTest @Inject ApplicationContext applicationContext; - protected EditableManagedRepository createRepository( String id, String name, Path location ) - { + protected EditableManagedRepository createRepository( String id, String name, Path location ) throws IOException { BasicManagedRepository repo = new BasicManagedRepository(id, name, location.getParent()); repo.setLocation( location.toAbsolutePath().toUri()); + FileLockManager lockManager = new DefaultFileLockManager(); + FilesystemStorage storage = new FilesystemStorage(location.toAbsolutePath(), lockManager); + repo.setContent(new ManagedRepositoryContentMock(repo, storage)); return repo; } @@ -79,8 +85,7 @@ public class RepositoryScannerTest private static final String[] ARTIFACT_PATTERNS = new String[]{ "**/*.jar", "**/*.pom", "**/*.rar", "**/*.zip", "**/*.war", "**/*.tar.gz" }; - private ManagedRepository createDefaultRepository() - { + private ManagedRepository createDefaultRepository() throws IOException { Path repoDir = Paths.get( System.getProperty( "basedir" ), "src/test/repositories/default-repository" ); @@ -117,8 +122,7 @@ public class RepositoryScannerTest return fmt.parse( timestamp ).getTime(); } - private ManagedRepository createLegacyRepository() - { + private ManagedRepository createLegacyRepository() throws IOException { Path repoDir = Paths.get( System.getProperty( "basedir" ), "src/test/repositories/legacy-repository" ); assertTrue( "Legacy Test Repository should exist.", Files.exists(repoDir) && Files.isDirectory(repoDir) ); diff --git a/archiva-modules/archiva-base/archiva-repository-scanner/src/test/java/org/apache/archiva/repository/scanner/mock/ManagedRepositoryContentMock.java b/archiva-modules/archiva-base/archiva-repository-scanner/src/test/java/org/apache/archiva/repository/scanner/mock/ManagedRepositoryContentMock.java new file mode 100644 index 000000000..6cac73d51 --- /dev/null +++ b/archiva-modules/archiva-base/archiva-repository-scanner/src/test/java/org/apache/archiva/repository/scanner/mock/ManagedRepositoryContentMock.java @@ -0,0 +1,423 @@ +package org.apache.archiva.repository.scanner.mock; + +/* + * 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.archiva.common.utils.VersionUtil; +import org.apache.archiva.metadata.model.ArtifactMetadata; +import org.apache.archiva.metadata.model.maven2.MavenArtifactFacet; +import org.apache.archiva.model.ArchivaArtifact; +import org.apache.archiva.model.ArtifactReference; +import org.apache.archiva.model.ProjectReference; +import org.apache.archiva.model.VersionedReference; +import org.apache.archiva.repository.*; +import org.apache.archiva.repository.content.FilesystemAsset; +import org.apache.archiva.repository.content.FilesystemStorage; +import org.apache.archiva.repository.content.StorageAsset; +import org.apache.commons.lang.StringUtils; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author Martin Stockhammer + */ +public class ManagedRepositoryContentMock implements ManagedRepositoryContent +{ + private static final String PATH_SEPARATOR = "/"; + private static final String GROUP_SEPARATOR = "."; + public static final String MAVEN_METADATA = "maven-metadata.xml"; + + + private ManagedRepository repository; + private FilesystemStorage storage; + + public ManagedRepositoryContentMock(ManagedRepository repo, FilesystemStorage storage) { + this.repository = repo; + this.storage = storage; + } + + @Override + public void deleteVersion( VersionedReference reference ) throws ContentNotFoundException + { + + } + + @Override + public void deleteArtifact( ArtifactReference artifactReference ) throws ContentNotFoundException + { + + } + + @Override + public void deleteGroupId( String groupId ) throws ContentNotFoundException + { + + } + + @Override + public void deleteProject( String namespace, String projectId ) throws RepositoryException + { + + } + + @Override + public String getId( ) + { + return repository.getId(); + } + + @Override + public Set getRelatedArtifacts( ArtifactReference reference ) throws ContentNotFoundException + { + return null; + } + + @Override + public String getRepoRoot( ) + { + return Paths.get("", "target", "test-repository", "managed").toString(); + } + + @Override + public ManagedRepository getRepository( ) + { + return repository; + } + + @Override + public Set getVersions( ProjectReference reference ) throws ContentNotFoundException, LayoutException + { + return null; + } + + @Override + public Set getVersions( VersionedReference reference ) throws ContentNotFoundException + { + return null; + } + + @Override + public boolean hasContent( ArtifactReference reference ) + { + return false; + } + + @Override + public boolean hasContent( ProjectReference reference ) + { + return false; + } + + @Override + public boolean hasContent( VersionedReference reference ) + { + return false; + } + + @Override + public void setRepository( ManagedRepository repo ) + { + this.repository = repo; + } + + private Map refs = new HashMap<>(); + + @Override + public ArtifactReference toArtifactReference( String path ) throws LayoutException + { + if ( StringUtils.isBlank( path ) ) + { + throw new LayoutException( "Unable to convert blank path." ); + } + + ArtifactMetadata metadata = getArtifactForPath("test-repository", path); + + ArtifactReference artifact = new ArtifactReference(); + artifact.setGroupId( metadata.getNamespace() ); + artifact.setArtifactId( metadata.getProject() ); + artifact.setVersion( metadata.getVersion() ); + MavenArtifactFacet facet = (MavenArtifactFacet) metadata.getFacet( MavenArtifactFacet.FACET_ID ); + if ( facet != null ) + { + artifact.setClassifier( facet.getClassifier() ); + artifact.setType( facet.getType() ); + } + refs.put(artifact, path); + return artifact; + } + + public ArtifactMetadata getArtifactForPath( String repoId, String relativePath ) + { + String[] parts = relativePath.replace( '\\', '/' ).split( "/" ); + + int len = parts.length; + if ( len < 4 ) + { + throw new IllegalArgumentException( + "Not a valid artifact path in a Maven 2 repository, not enough directories: " + relativePath ); + } + + String id = parts[--len]; + String baseVersion = parts[--len]; + String artifactId = parts[--len]; + StringBuilder groupIdBuilder = new StringBuilder(); + for ( int i = 0; i < len - 1; i++ ) + { + groupIdBuilder.append( parts[i] ); + groupIdBuilder.append( '.' ); + } + groupIdBuilder.append( parts[len - 1] ); + + return getArtifactFromId( repoId, groupIdBuilder.toString(), artifactId, baseVersion, id ); + } + + private static final Pattern TIMESTAMP_PATTERN = Pattern.compile( "([0-9]{8}.[0-9]{6})-([0-9]+).*" ); + + + + public ArtifactMetadata getArtifactFromId( String repoId, String namespace, String projectId, String projectVersion, + String id ) + { + if ( !id.startsWith( projectId + "-" ) ) + { + throw new IllegalArgumentException( "Not a valid artifact path in a Maven 2 repository, filename '" + id + + "' doesn't start with artifact ID '" + projectId + "'" ); + } + + MavenArtifactFacet facet = new MavenArtifactFacet(); + + int index = projectId.length() + 1; + String version; + String idSubStrFromVersion = id.substring( index ); + if ( idSubStrFromVersion.startsWith( projectVersion ) && !VersionUtil.isUniqueSnapshot( projectVersion ) ) + { + // non-snapshot versions, or non-timestamped snapshot versions + version = projectVersion; + } + else if ( VersionUtil.isGenericSnapshot( projectVersion ) ) + { + // timestamped snapshots + try + { + int mainVersionLength = projectVersion.length() - 8; // 8 is length of "SNAPSHOT" + if ( mainVersionLength == 0 ) + { + throw new IllegalArgumentException( + "Timestamped snapshots must contain the main version, filename was '" + id + "'" ); + } + + Matcher m = TIMESTAMP_PATTERN.matcher( idSubStrFromVersion.substring( mainVersionLength ) ); + m.matches(); + String timestamp = m.group( 1 ); + String buildNumber = m.group( 2 ); + facet.setTimestamp( timestamp ); + facet.setBuildNumber( Integer.parseInt( buildNumber ) ); + version = idSubStrFromVersion.substring( 0, mainVersionLength ) + timestamp + "-" + buildNumber; + } + catch ( IllegalStateException e ) + { + throw new IllegalArgumentException( "Not a valid artifact path in a Maven 2 repository, filename '" + id + + "' doesn't contain a timestamped version matching snapshot '" + + projectVersion + "'", e); + } + } + else + { + // invalid + throw new IllegalArgumentException( + "Not a valid artifact path in a Maven 2 repository, filename '" + id + "' doesn't contain version '" + + projectVersion + "'" ); + } + + String classifier; + String ext; + index += version.length(); + if ( index == id.length() ) + { + // no classifier or extension + classifier = null; + ext = null; + } + else + { + char c = id.charAt( index ); + if ( c == '-' ) + { + // classifier up until '.' + int extIndex = id.indexOf( '.', index ); + if ( extIndex >= 0 ) + { + classifier = id.substring( index + 1, extIndex ); + ext = id.substring( extIndex + 1 ); + } + else + { + classifier = id.substring( index + 1 ); + ext = null; + } + } + else if ( c == '.' ) + { + // rest is the extension + classifier = null; + ext = id.substring( index + 1 ); + } + else + { + throw new IllegalArgumentException( "Not a valid artifact path in a Maven 2 repository, filename '" + id + + "' expected classifier or extension but got '" + + id.substring( index ) + "'" ); + } + } + + ArtifactMetadata metadata = new ArtifactMetadata(); + metadata.setId( id ); + metadata.setNamespace( namespace ); + metadata.setProject( projectId ); + metadata.setRepositoryId( repoId ); + metadata.setProjectVersion( projectVersion ); + metadata.setVersion( version ); + + facet.setClassifier( classifier ); + + // we use our own provider here instead of directly accessing Maven's artifact handlers as it has no way + // to select the correct order to apply multiple extensions mappings to a preferred type + // TODO: this won't allow the user to decide order to apply them if there are conflicts or desired changes - + // perhaps the plugins could register missing entries in configuration, then we just use configuration + // here? + + String type = null; + + + // use extension as default + if ( type == null ) + { + type = ext; + } + + // TODO: should we allow this instead? + if ( type == null ) + { + throw new IllegalArgumentException( + "Not a valid artifact path in a Maven 2 repository, filename '" + id + "' does not have a type" ); + } + + facet.setType( type ); + metadata.addFacet( facet ); + + return metadata; + } + + + @Override + public Path toFile( ArtifactReference reference ) + { + return Paths.get(getRepoRoot(), refs.get(reference)); + } + + @Override + public Path toFile( ArchivaArtifact reference ) + { + return null; + } + + private String formatAsDirectory( String directory ) + { + return directory.replace( GROUP_SEPARATOR, PATH_SEPARATOR ); + } + + public String toMetadataPath( ProjectReference reference ) + { + StringBuilder path = new StringBuilder(); + + path.append( formatAsDirectory( reference.getGroupId() ) ).append( PATH_SEPARATOR ); + path.append( reference.getArtifactId() ).append( PATH_SEPARATOR ); + path.append( MAVEN_METADATA ); + + return path.toString(); + } + + public String toMetadataPath( VersionedReference reference ) + { + StringBuilder path = new StringBuilder(); + + path.append( formatAsDirectory( reference.getGroupId() ) ).append( PATH_SEPARATOR ); + path.append( reference.getArtifactId() ).append( PATH_SEPARATOR ); + if ( reference.getVersion() != null ) + { + // add the version only if it is present + path.append( VersionUtil.getBaseVersion( reference.getVersion() ) ).append( PATH_SEPARATOR ); + } + path.append( MAVEN_METADATA ); + + return path.toString(); + } + + @Override + public String toPath( ArtifactReference reference ) + { + return null; + } + + @Override + public String toPath( ArchivaArtifact reference ) + { + return null; + } + + @Override + public StorageAsset getAsset(String path) { + return storage.getAsset(path); + } + + @Override + public void consumeData(StorageAsset asset, Consumer consumerFunction, boolean readLock) throws IOException { + storage.consumeData(asset, consumerFunction, readLock); + } + + @Override + public StorageAsset addAsset(String path, boolean container) { + return storage.addAsset(path, container); + } + + @Override + public void removeAsset(StorageAsset asset) throws IOException { + storage.removeAsset(asset); + } + + @Override + public StorageAsset moveAsset(StorageAsset origin, String destination) throws IOException { + return storage.moveAsset(origin, destination); + } + + @Override + public StorageAsset copyAsset(StorageAsset origin, String destination) throws IOException { + return storage.copyAsset(origin, destination); + } +} diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/ArchivaDavResourceFactory.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/ArchivaDavResourceFactory.java index e8602caaa..62fc14922 100644 --- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/ArchivaDavResourceFactory.java +++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/ArchivaDavResourceFactory.java @@ -437,7 +437,7 @@ public class ArchivaDavResourceFactory Path resourceFile = temporaryIndexDirectory.resolve( requestedFileName ); try { - resource = new ArchivaDavResource( asset, requestedFileName, null, + resource = new ArchivaDavResource( asset, requestedFileName, repoGroup, request.getRemoteAddr(), activePrincipal, request.getDavSession(), archivaLocator, this, mimeTypes, auditListeners, scheduler ); } catch (LayoutException e) { diff --git a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/RepositoryServlet.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/RepositoryServlet.java index 5ca41715f..b9d05aa89 100644 --- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/RepositoryServlet.java +++ b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/archiva/webdav/RepositoryServlet.java @@ -26,6 +26,7 @@ import org.apache.archiva.configuration.ConfigurationListener; import org.apache.archiva.redback.integration.filter.authentication.HttpAuthenticator; import org.apache.archiva.repository.ManagedRepository; import org.apache.archiva.repository.RepositoryRegistry; +import org.apache.archiva.repository.content.StorageAsset; import org.apache.archiva.security.ServletAuthenticator; import org.apache.jackrabbit.webdav.DavException; import org.apache.jackrabbit.webdav.DavLocatorFactory; @@ -183,11 +184,11 @@ public class RepositoryServlet fillRepositoryMap(); for (ManagedRepository repo : repositoryMap.values()) { - Path repoDir = Paths.get(repo.getLocation()); + StorageAsset repoDir = repo.getContent().getAsset(""); - if (!Files.exists(repoDir)) { + if (!repoDir.exists()) { try { - Files.createDirectories(repoDir); + repoDir.create(); } catch (IOException e) { log.info("Unable to create missing directory for {}", repo.getLocation()); continue;