com.metaeffekt.mirror.plugin.InternalDataPreprocessingMojo Maven / Gradle / Ivy
/*
* Copyright 2021-2024 the original author or authors.
*
* Licensed 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.
*/
package com.metaeffekt.mirror.plugin;
import com.metaeffekt.artifact.analysis.utils.FileUtils;
import com.metaeffekt.artifact.analysis.utils.StringUtils;
import com.metaeffekt.mirror.download.Download;
import com.metaeffekt.mirror.download.advisor.CertFrDownload;
import com.metaeffekt.mirror.index.Index;
import com.metaeffekt.mirror.initializer.DownloadInitializer;
import com.metaeffekt.mirror.initializer.MirrorInitializer;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import java.io.File;
import java.util.*;
@Mojo(name = "internal-data-mirror", defaultPhase = LifecyclePhase.PROCESS_RESOURCES)
public class InternalDataPreprocessingMojo extends AbstractMojo {
@Parameter(required = true)
private File mirrorDirectory;
@Parameter
private String proxyScheme, proxyHost, proxyUsername, proxyPassword;
@Parameter
private Integer proxyPort;
@Parameter
private DownloadInitializer certFrDownload;
@Parameter(required = true)
private File moveTargetFilesTo;
@Parameter(defaultValue = "${project}", required = true, readonly = true)
private MavenProject project;
public MavenProject getProject() {
return project;
}
@Override
public void execute() throws MojoFailureException {
getLog().info("Starting INTERNAL mirroring process");
final Map downloadResults = processDownload();
final Map indexResults = Collections.emptyMap();
logResults(downloadResults, indexResults);
if (hasProcessFailed(downloadResults, indexResults)) {
throw new MojoFailureException("INTERNAL Mirroring process completed with errors - see log for details");
}
getLog().info("INTERNAL Mirroring process completed successfully");
}
private Map processDownload() {
final Map mirrorResults = new LinkedHashMap<>();
final List downloads = buildDownloaders();
if (!moveTargetFilesTo.getParentFile().exists()) {
moveTargetFilesTo.mkdirs();
}
for (Download download : downloads) {
// getLog().info("");
// getLog().info("Downloading [" + Download.getDirectoryIdentifier(download.getClass()) + "]");
final MirrorResult result = mirrorResults.computeIfAbsent(download, d -> new MirrorResult());
try {
final File internalMirrorTargetDir = new File(download.getDownloadIntoDirectory(), "internal-mirror");
if (internalMirrorTargetDir.exists()) {
try {
FileUtils.forceDelete(internalMirrorTargetDir);
} catch (Exception e) {
getLog().error("Failed to delete existing internal mirror directory " + internalMirrorTargetDir.getAbsolutePath(), e);
result.exception = e;
continue;
}
}
download.performInternalDownload();
if (!internalMirrorTargetDir.exists()) {
throw new RuntimeException("INTERNAL download failed - target directory was not provided by downloader, expected to exist: " + internalMirrorTargetDir.getAbsolutePath());
}
// move directory as the downloader name to the new target directory
final File moveTarget = new File(moveTargetFilesTo, Download.getDirectoryIdentifier(download.getClass()));
if (moveTarget.exists()) {
try {
FileUtils.forceDelete(moveTarget);
} catch (Exception e) {
getLog().error("Failed to delete existing move target directory " + moveTarget.getAbsolutePath(), e);
result.exception = e;
continue;
}
}
FileUtils.moveDirectory(internalMirrorTargetDir, moveTarget);
// getLog().info("Completed download [" + Download.getDirectoryIdentifier(download.getClass()) + "]");
} catch (Exception e) {
result.exception = e;
getLog().error("Failed on download " + download.getDownloadIntoDirectory().getName(), e);
} finally {
result.stop();
getLog().info("");
}
}
getLog().info("Moved all internal mirror files to " + moveTargetFilesTo.getAbsolutePath());
getLog().info("This directory can now be uploaded to a sever to be made available to other downloaders");
return mirrorResults;
}
private List buildDownloaders() {
final List downloads = new ArrayList<>();
if (isActive(certFrDownload)) {
applyProxySettings(certFrDownload);
final CertFrDownload download = new CertFrDownload(mirrorDirectory);
certFrDownload.apply(download);
downloads.add(download);
}
if (!downloads.isEmpty()) {
getLog().info("Downloads:");
for (Download download : downloads) {
getLog().info(" - " + Download.getDirectoryIdentifier(download.getClass()));
}
getLog().info("");
}
return downloads;
}
/**
* Applies the global proxy settings to a specified {@link DownloadInitializer} instance.
* The settings are applied only if none of the fields in the initializer are already set;
* if any of the fields in the initializer are set, no changes are made.
*
* @param initializer the {@link DownloadInitializer} instance to which the proxy settings should be applied
*/
private void applyProxySettings(DownloadInitializer initializer) {
if (initializer.scheme != null || initializer.host != null || initializer.port != null
|| initializer.username != null || initializer.password != null) {
getLog().info("Downloader using initializer [" + initializer.getClass().getSimpleName() + "] already has proxy settings specified, ignoring global proxy settings");
return;
}
if (isValidProxySetting(proxyScheme)) initializer.scheme = proxyScheme;
if (isValidProxySetting(proxyHost)) initializer.host = proxyHost;
if (isValidProxySetting(proxyPort)) initializer.port = proxyPort;
if (isValidProxySetting(proxyUsername)) initializer.username = proxyUsername;
if (isValidProxySetting(proxyPassword)) initializer.password = proxyPassword;
}
/**
* Determines whether the specified value is a valid proxy setting.
*
* To be considered a valid proxy setting, the following conditions must be met:
*
* - The value should not be null.
* - If the value is a string, it must not be:
*
* - an empty string,
* - "null" (ignoring case),
* - "none" (ignoring case).
*
*
* - If the value is an integer, it must not be -1.
*
* If the value is of any other datatype, then it is always considered as invalid proxy setting.
*
* @param value the value to be checked.
* @return true if the value is a valid proxy setting according to the rules defined above, false otherwise.
*/
private boolean isValidProxySetting(Object value) {
if (value == null) return false;
if (value instanceof String) {
final String str = (String) value;
if (StringUtils.isEmpty(str)) return false;
if (str.equalsIgnoreCase("null")) return false;
if (str.equalsIgnoreCase("none")) return false;
} else if (value instanceof Integer) {
final Integer i = (Integer) value;
if (i == -1) return false;
} else {
return false;
}
return true;
}
private boolean isActive(MirrorInitializer> initializer) {
return initializer != null && initializer.active;
}
private boolean hasProcessFailed(Map downloadResults, Map indexResults) {
for (MirrorResult result : downloadResults.values()) {
if (result.hasFailed()) {
return true;
}
}
for (MirrorResult result : indexResults.values()) {
if (result.hasFailed()) {
return true;
}
}
return false;
}
private void logResults(Map downloadResults, Map indexResults) {
getLog().info("Mirror results:");
if (!downloadResults.isEmpty()) {
getLog().info("Download:");
for (Map.Entry entry : downloadResults.entrySet()) {
entry.getValue().logSummary(Download.getDirectoryIdentifier(entry.getKey().getClass()));
}
getLog().info("");
}
if (!indexResults.isEmpty()) {
getLog().info("Index:");
for (Map.Entry entry : indexResults.entrySet()) {
entry.getValue().logSummary(Index.getDirectoryIdentifier(entry.getKey().getClass()));
}
getLog().info("");
}
if (!downloadResults.isEmpty()) {
for (Map.Entry entry : downloadResults.entrySet()) {
if (entry.getValue().hasFailed()) {
getLog().error(entry.getValue().exception);
getLog().error("");
}
}
}
if (!indexResults.isEmpty()) {
for (Map.Entry entry : indexResults.entrySet()) {
if (entry.getValue().hasFailed()) {
getLog().error(entry.getValue().exception);
getLog().error("");
}
}
}
}
private class MirrorResult {
public Exception exception;
private final long start = System.currentTimeMillis();
private long duration = -1;
public void stop() {
duration = System.currentTimeMillis() - start;
}
public String getDuration() {
if (duration >= 0) {
if (duration < 1000) {
return String.format("%4s ms", duration);
} else if (duration < 100000) {
return String.format("%5.1f s", duration / 1000.0);
} else {
return String.format("%5.0f s", duration / 1000.0);
}
} else {
return "unknown";
}
}
public boolean hasFailed() {
return exception != null;
}
public void logSummary(String name) {
if (hasFailed()) {
getLog().error("- FAILED: [" + getDuration() + "] " + name + ": " + exception.getMessage());
} else {
getLog().info("- SUCCESS: [" + getDuration() + "] " + name);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy