Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ public void get(

SmartExecutor executor = getExecutor(true, safeArtifactDownloads.size() + safeMetadataDownloads.size());
RunnableErrorForwarder errorForwarder = new RunnableErrorForwarder();
List<ChecksumAlgorithmFactory> checksumAlgorithmFactories = layout.getChecksumAlgorithmFactories();
List<ChecksumAlgorithmFactory> checksumAlgorithmFactories = layout.getChecksumAlgorithmFactories(false);

boolean first = true;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;

import org.eclipse.aether.ConfigurationProperties;
Expand Down Expand Up @@ -57,7 +58,9 @@ public final class Maven2RepositoryLayoutFactory implements RepositoryLayoutFact
/**
* Comma-separated list of checksum algorithms with which checksums are validated (downloaded) and generated
* (uploaded) with this layout. Resolver by default supports following algorithms: MD5, SHA-1, SHA-256 and
* SHA-512. New algorithms can be added by implementing ChecksumAlgorithmFactory component.
* SHA-512. New algorithms can be added by implementing ChecksumAlgorithmFactory component. To configure separately
* checksums for download or upload, use {@link #CONFIG_PROP_DOWNLOAD_CHECKSUMS_ALGORITHMS} and
* {@link #CONFIG_PROP_UPLOAD_CHECKSUMS_ALGORITHMS} respectively.
*
* @since 1.8.0
* @configurationSource {@link RepositorySystemSession#getConfigProperties()}
Expand All @@ -69,6 +72,38 @@ public final class Maven2RepositoryLayoutFactory implements RepositoryLayoutFact

public static final String DEFAULT_CHECKSUMS_ALGORITHMS = "SHA-1,MD5";

/**
* Comma-separated list of checksum algorithms with which checksums are generated and uploaded
Comment thread
kwin marked this conversation as resolved.
* with this layout. Resolver by default supports following algorithms: MD5, SHA-1, SHA-256 and
* SHA-512. New algorithms can be added by implementing ChecksumAlgorithmFactory component.
* If this property is set, it <em>overrides</em> the value set in {@link #CONFIG_PROP_CHECKSUMS_ALGORITHMS} for
* uploads.
*
* @since 2.0.15
* @configurationSource {@link RepositorySystemSession#getConfigProperties()}
* @configurationType {@link java.lang.String}
* @configurationDefaultValue {@link #DEFAULT_CHECKSUMS_ALGORITHMS}
* @configurationRepoIdSuffix Yes
*/
public static final String CONFIG_PROP_UPLOAD_CHECKSUMS_ALGORITHMS =
CONFIG_PROPS_PREFIX + "uploadChecksumAlgorithms";

/**
* Comma-separated list of checksum algorithms with which checksums are validated (downloaded) with this layout.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please mention which one takes precedence if both CONFIG_PROP_CHECKSUMS_ALGORITHMS and this is set.

* Resolver by default supports following algorithms: MD5, SHA-1, SHA-256 and SHA-512.
* New algorithms can be added by implementing ChecksumAlgorithmFactory component.
* If this property is set, it <em>overrides</em> the value set in {@link #CONFIG_PROP_CHECKSUMS_ALGORITHMS} for
* downloads.
*
* @since 2.0.15
* @configurationSource {@link RepositorySystemSession#getConfigProperties()}
* @configurationType {@link java.lang.String}
* @configurationDefaultValue {@link #DEFAULT_CHECKSUMS_ALGORITHMS}
* @configurationRepoIdSuffix Yes
*/
public static final String CONFIG_PROP_DOWNLOAD_CHECKSUMS_ALGORITHMS =
CONFIG_PROPS_PREFIX + "downloadChecksumAlgorithms";

private float priority;

private final ChecksumAlgorithmFactorySelector checksumAlgorithmFactorySelector;
Expand Down Expand Up @@ -106,26 +141,48 @@ public RepositoryLayout newInstance(RepositorySystemSession session, RemoteRepos
throw new NoRepositoryLayoutException(repository);
}

List<ChecksumAlgorithmFactory> checksumsAlgorithms = checksumAlgorithmFactorySelector.selectList(
ConfigUtils.parseCommaSeparatedUniqueNames(ConfigUtils.getString(
session,
DEFAULT_CHECKSUMS_ALGORITHMS,
CONFIG_PROP_CHECKSUMS_ALGORITHMS + "." + repository.getId(),
CONFIG_PROP_CHECKSUMS_ALGORITHMS,
// MRESOLVER-701: support legacy properties for simpler transitioning
"aether.checksums.algorithms",
"aether.checksums.algorithms." + repository.getId())));

return new Maven2RepositoryLayout(checksumsAlgorithms, artifactPredicateFactory.newInstance(session));
// explicit property for download (will be empty if not configured)
List<String> downloadChecksumsAlgorithmNames = ConfigUtils.parseCommaSeparatedUniqueNames(ConfigUtils.getString(
session,
DEFAULT_CHECKSUMS_ALGORITHMS,
CONFIG_PROP_DOWNLOAD_CHECKSUMS_ALGORITHMS + "." + repository.getId(),
CONFIG_PROP_DOWNLOAD_CHECKSUMS_ALGORITHMS,
CONFIG_PROP_CHECKSUMS_ALGORITHMS + "." + repository.getId(),
CONFIG_PROP_CHECKSUMS_ALGORITHMS,
// MRESOLVER-701: support legacy properties for simpler transitioning
"aether.checksums.algorithms." + repository.getId(),
"aether.checksums.algorithms"));

// explicit property for upload (will be empty if not configured)
List<String> uploadChecksumsAlgorithmNames = ConfigUtils.parseCommaSeparatedUniqueNames(ConfigUtils.getString(
session,
DEFAULT_CHECKSUMS_ALGORITHMS,
CONFIG_PROP_UPLOAD_CHECKSUMS_ALGORITHMS + "." + repository.getId(),
CONFIG_PROP_UPLOAD_CHECKSUMS_ALGORITHMS,
CONFIG_PROP_CHECKSUMS_ALGORITHMS + "." + repository.getId(),
CONFIG_PROP_CHECKSUMS_ALGORITHMS,
// MRESOLVER-701: support legacy properties for simpler transitioning
"aether.checksums.algorithms." + repository.getId(),
"aether.checksums.algorithms"));

return new Maven2RepositoryLayout(
checksumAlgorithmFactorySelector.selectList(downloadChecksumsAlgorithmNames),
checksumAlgorithmFactorySelector.selectList(uploadChecksumsAlgorithmNames),
artifactPredicateFactory.newInstance(session));
}

private static class Maven2RepositoryLayout implements RepositoryLayout {
private final List<ChecksumAlgorithmFactory> configuredChecksumAlgorithms;
private final List<ChecksumAlgorithmFactory> configuredDownloadChecksumAlgorithms;
private final List<ChecksumAlgorithmFactory> configuredUploadChecksumAlgorithms;
private final ArtifactPredicate artifactPredicate;

private Maven2RepositoryLayout(
List<ChecksumAlgorithmFactory> configuredChecksumAlgorithms, ArtifactPredicate artifactPredicate) {
this.configuredChecksumAlgorithms = Collections.unmodifiableList(configuredChecksumAlgorithms);
List<ChecksumAlgorithmFactory> configuredDownloadChecksumAlgorithms,
List<ChecksumAlgorithmFactory> configuredUploadChecksumAlgorithms,
ArtifactPredicate artifactPredicate) {
this.configuredDownloadChecksumAlgorithms =
Collections.unmodifiableList(configuredDownloadChecksumAlgorithms);
this.configuredUploadChecksumAlgorithms = Collections.unmodifiableList(configuredUploadChecksumAlgorithms);
this.artifactPredicate = requireNonNull(artifactPredicate);
}

Expand All @@ -139,7 +196,19 @@ private URI toUri(String path) {

@Override
public List<ChecksumAlgorithmFactory> getChecksumAlgorithmFactories() {
return configuredChecksumAlgorithms;
LinkedHashMap<String, ChecksumAlgorithmFactory> factories = new LinkedHashMap<>();
configuredDownloadChecksumAlgorithms.forEach(f -> factories.putIfAbsent(f.getName(), f));
configuredUploadChecksumAlgorithms.forEach(f -> factories.putIfAbsent(f.getName(), f));
return Collections.unmodifiableList(new ArrayList<>(factories.values()));
}

@Override
public List<ChecksumAlgorithmFactory> getChecksumAlgorithmFactories(boolean upload) {
if (upload) {
return configuredUploadChecksumAlgorithms;
} else {
return configuredDownloadChecksumAlgorithms;
}
}

@Override
Expand Down Expand Up @@ -196,17 +265,19 @@ public List<ChecksumLocation> getChecksumLocations(Artifact artifact, boolean up
if (artifactPredicate.isWithoutChecksum(artifact) || artifactPredicate.isChecksum(artifact)) {
return Collections.emptyList();
}
return getChecksumLocations(location);
return getChecksumLocations(location, upload);
}

@Override
public List<ChecksumLocation> getChecksumLocations(Metadata metadata, boolean upload, URI location) {
return getChecksumLocations(location);
return getChecksumLocations(location, upload);
}

private List<ChecksumLocation> getChecksumLocations(URI location) {
List<ChecksumLocation> checksumLocations = new ArrayList<>(configuredChecksumAlgorithms.size());
for (ChecksumAlgorithmFactory checksumAlgorithmFactory : configuredChecksumAlgorithms) {
private List<ChecksumLocation> getChecksumLocations(URI location, boolean upload) {
List<ChecksumAlgorithmFactory> checksumAlgorithmFactories =
upload ? configuredUploadChecksumAlgorithms : configuredDownloadChecksumAlgorithms;
List<ChecksumLocation> checksumLocations = new ArrayList<>(checksumAlgorithmFactories.size());
for (ChecksumAlgorithmFactory checksumAlgorithmFactory : checksumAlgorithmFactories) {
checksumLocations.add(ChecksumLocation.forLocation(location, checksumAlgorithmFactory));
}
return checksumLocations;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ void testNotConfiguredButSupportedChecksumsHandledAsChecksums() throws Exception
}

@Test
void testCustomChecksumsIgnored_IllegalInout() throws Exception {
void testCustomChecksumsIgnored_IllegalInput() throws Exception {
session.setConfigProperty(
DefaultArtifactPredicateFactory.CONFIG_PROP_OMIT_CHECKSUMS_FOR_EXTENSIONS, ".asc,foo");
try {
Expand All @@ -332,4 +332,50 @@ void testCustomChecksumsIgnored_IllegalInout() throws Exception {
message);
}
}

@Test
void testUploadDownloadChecksumsConfigured() throws Exception {
session.setConfigProperty(
Maven2RepositoryLayoutFactory.CONFIG_PROP_DOWNLOAD_CHECKSUMS_ALGORITHMS, "SHA-256,SHA-1");
session.setConfigProperty(Maven2RepositoryLayoutFactory.CONFIG_PROP_UPLOAD_CHECKSUMS_ALGORITHMS, "SHA-512,MD5");
layout = factory.newInstance(session, newRepo("default"));
// as configured
assertEquals(Arrays.asList("SHA-256", "SHA-1"), toNames(layout.getChecksumAlgorithmFactories(false)));
// as configured
assertEquals(Arrays.asList("SHA-512", "MD5"), toNames(layout.getChecksumAlgorithmFactories(true)));
// in order with download ones added first
assertEquals(
Arrays.asList("SHA-256", "SHA-1", "SHA-512", "MD5"), toNames(layout.getChecksumAlgorithmFactories()));
}

@Test
void testDownloadChecksumsConfigured() throws Exception {
session.setConfigProperty(
Maven2RepositoryLayoutFactory.CONFIG_PROP_DOWNLOAD_CHECKSUMS_ALGORITHMS, "SHA-256,SHA-1");
layout = factory.newInstance(session, newRepo("default"));
// as configured
assertEquals(Arrays.asList("SHA-256", "SHA-1"), toNames(layout.getChecksumAlgorithmFactories(false)));
// defaults
assertEquals(Arrays.asList("SHA-1", "MD5"), toNames(layout.getChecksumAlgorithmFactories(true)));
// in order with download ones added first
assertEquals(Arrays.asList("SHA-256", "SHA-1", "MD5"), toNames(layout.getChecksumAlgorithmFactories()));
}

@Test
void testUploadChecksumsConfigured() throws Exception {
session.setConfigProperty(
Maven2RepositoryLayoutFactory.CONFIG_PROP_UPLOAD_CHECKSUMS_ALGORITHMS, "SHA-512,SHA-256,SHA-1");
layout = factory.newInstance(session, newRepo("default"));
// defaults
assertEquals(Arrays.asList("SHA-1", "MD5"), toNames(layout.getChecksumAlgorithmFactories(false)));
// as configured
assertEquals(Arrays.asList("SHA-512", "SHA-256", "SHA-1"), toNames(layout.getChecksumAlgorithmFactories(true)));
// in order with download ones added first
assertEquals(
Arrays.asList("SHA-1", "MD5", "SHA-512", "SHA-256"), toNames(layout.getChecksumAlgorithmFactories()));
}

private static List<String> toNames(List<ChecksumAlgorithmFactory> factories) {
return factories.stream().map(ChecksumAlgorithmFactory::getName).collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public interface ChecksumAlgorithmFactorySelector {
/**
* Returns immutable collection of all supported algorithms. This set represents ALL the algorithms supported by
* Resolver, and is NOT in any relation to given repository layout used checksums, returned by method {@link
* org.eclipse.aether.spi.connector.layout.RepositoryLayout#getChecksumAlgorithmFactories()} (in fact, is super set
* org.eclipse.aether.spi.connector.layout.RepositoryLayout#getChecksumAlgorithmFactories(boolean)} (in fact, is super set
* of it).
*/
Collection<ChecksumAlgorithmFactory> getChecksumAlgorithmFactories();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,31 @@ public String toString() {

/**
* Returns immutable list of {@link ChecksumAlgorithmFactory} this instance of layout uses, never {@code null}.
* The order also represents the order how remote external checksums are retrieved and validated.
* This (legacy, but not deprecated) method will return <em>all checksums this layout uses</em>, but
* these may be different in case upload or download checksums are explicitly configured. This method will
* reflect the checksum order used for download, but may have more elements than actually used in download
* validation, if the generated checksums for upload has extra elements.
*
* @see org.eclipse.aether.spi.connector.checksum.ChecksumPolicy.ChecksumKind
* @see #getChecksumAlgorithmFactories(boolean)
* @since 1.8.0
*/
List<ChecksumAlgorithmFactory> getChecksumAlgorithmFactories();

/**
* Returns immutable list of {@link ChecksumAlgorithmFactory} this instance of layout uses for download or upload,
* never {@code null}. The order also represents the order how remote external checksums are retrieved and
* validated (if for download).
*

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a missing @param here.

* @param upload {@code false} if the caller needs checksums used for download validation, or {@code true} if the
* caller needs checksums generated for upload.
* @see org.eclipse.aether.spi.connector.checksum.ChecksumPolicy.ChecksumKind
* @since 2.0.15
*/
default List<ChecksumAlgorithmFactory> getChecksumAlgorithmFactories(boolean upload) {
return getChecksumAlgorithmFactories();
}

/**
* Tells whether given artifact have remote external checksums according to current layout or not. If it returns
* {@code true}, then layout configured checksums will be expected: on upload they will be calculated and deployed
Expand All @@ -132,7 +150,7 @@ public String toString() {
*
* The result affects only layout provided checksums. See
* {@link org.eclipse.aether.spi.connector.checksum.ChecksumPolicy.ChecksumKind#REMOTE_EXTERNAL}.
* On download, the {@link org.eclipse.aether.spi.connector.layout.RepositoryLayout#getChecksumAlgorithmFactories()}
* On download, the {@link org.eclipse.aether.spi.connector.layout.RepositoryLayout#getChecksumAlgorithmFactories(boolean)}
* layout required checksums are calculated, and non layout-provided checksums are still utilized.
*
* Typical case to return {@code false} (to omit checksums) is for artifact signatures, that are already a
Expand Down
Loading