This is an automated email from the ASF dual-hosted git repository.
bchapuis pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-baremaps.git
The following commit(s) were added to refs/heads/main by this push:
new c4445c33 Support FTP downloads and extend IRR whois source files (#698)
c4445c33 is described below
commit c4445c33f0f3a4a41455d7c7925cecbff1f12ba1
Author: Perdjesk <[email protected]>
AuthorDate: Mon Jun 12 18:54:25 2023 +0200
Support FTP downloads and extend IRR whois source files (#698)
* Support FTP downloads. Extend IRR whois source files
* Disable test reliying on third party resource
* Use IllegalArgumentException instead of IOException for unsupported URL
protocols
---
.../baremaps/workflow/tasks/DownloadUrl.java | 56 ++++++++++++++++------
.../baremaps/workflow/tasks/DownloadUrlTest.java | 31 +++++++++++-
examples/ip-to-location/workflow.js | 14 ++++++
3 files changed, 86 insertions(+), 15 deletions(-)
diff --git
a/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/DownloadUrl.java
b/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/DownloadUrl.java
index 274d0b08..f22bb3a8 100644
---
a/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/DownloadUrl.java
+++
b/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/DownloadUrl.java
@@ -12,8 +12,10 @@
package org.apache.baremaps.workflow.tasks;
+import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
+import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
@@ -24,6 +26,10 @@ import org.slf4j.LoggerFactory;
public record DownloadUrl(String url, Path path, boolean replaceExisting)
implements Task {
+ private static final String PROTOCOL_FTP = "ftp";
+ private static final String PROTOCOL_HTTP = "http";
+ private static final String PROTOCOL_HTTPS = "https";
+
public DownloadUrl(String url, Path path) {
this(url, path, false);
}
@@ -35,26 +41,48 @@ public record DownloadUrl(String url, Path path, boolean
replaceExisting) implem
var targetUrl = new URL(url);
var targetPath = path.toAbsolutePath();
- if (Files.exists(targetPath) && !replaceExisting) {
- var head = (HttpURLConnection) targetUrl.openConnection();
- head.setFollowRedirects(true);
- head.setRequestMethod("HEAD");
- var contentLength = head.getContentLengthLong();
- head.disconnect();
- if (Files.size(targetPath) == contentLength) {
+ if (isHttp(targetUrl)) {
+ if (Files.exists(targetPath) && !replaceExisting) {
+ var head = (HttpURLConnection) targetUrl.openConnection();
+ head.setInstanceFollowRedirects(true);
+ head.setRequestMethod("HEAD");
+ var contentLength = head.getContentLengthLong();
+ head.disconnect();
+ if (Files.size(targetPath) == contentLength) {
+ logger.info("Skipping download of {} to {}", url, path);
+ return;
+ }
+ }
+
+ var get = (HttpURLConnection) targetUrl.openConnection();
+ get.setInstanceFollowRedirects(true);
+ get.setRequestMethod("GET");
+ urlDownloadToFile(get, targetPath);
+ get.disconnect();
+ } else if (isFtp(targetUrl)) {
+ if (Files.exists(targetPath) && !replaceExisting) {
logger.info("Skipping download of {} to {}", url, path);
return;
}
+ urlDownloadToFile(targetUrl.openConnection(), targetPath);
+ } else {
+ throw new IllegalArgumentException("Unsupported URL protocol (supported:
http(s)/ftp)");
}
+ }
+
+ private static boolean isHttp(URL url) {
+ return url.getProtocol().equalsIgnoreCase(PROTOCOL_HTTP) ||
+ url.getProtocol().equalsIgnoreCase(PROTOCOL_HTTPS);
+ }
+
+ private static boolean isFtp(URL url) {
+ return url.getProtocol().equalsIgnoreCase(PROTOCOL_FTP);
+ }
- var get = (HttpURLConnection) targetUrl.openConnection();
- get.setFollowRedirects(true);
- get.setRequestMethod("GET");
- try (var inputStream = get.getInputStream()) {
- var downloadFile = targetPath.toAbsolutePath();
- Files.createDirectories(downloadFile.getParent());
+ private static void urlDownloadToFile(URLConnection url, Path targetPath)
throws IOException {
+ try (var inputStream = url.getInputStream()) {
+ Files.createDirectories(targetPath.toAbsolutePath().getParent());
Files.copy(inputStream, targetPath, StandardCopyOption.REPLACE_EXISTING);
}
- get.disconnect();
}
}
diff --git
a/baremaps-core/src/test/java/org/apache/baremaps/workflow/tasks/DownloadUrlTest.java
b/baremaps-core/src/test/java/org/apache/baremaps/workflow/tasks/DownloadUrlTest.java
index 05d73881..00b78c35 100644
---
a/baremaps-core/src/test/java/org/apache/baremaps/workflow/tasks/DownloadUrlTest.java
+++
b/baremaps-core/src/test/java/org/apache/baremaps/workflow/tasks/DownloadUrlTest.java
@@ -12,12 +12,14 @@
package org.apache.baremaps.workflow.tasks;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.File;
import java.nio.file.Files;
import org.apache.baremaps.utils.FileUtils;
import org.apache.baremaps.workflow.WorkflowContext;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
@@ -34,6 +36,33 @@ class DownloadUrlTest {
assertTrue(Files.readString(file.toPath()).contains("Baremaps"));
}
+ @Disabled("Test relies on third party resource, see TODO comment.")
+ @Test
+ @Tag("integration")
+ void testDownloadFtp() throws Exception {
+ var directory = Files.createTempDirectory("tmp_");
+ var file = directory.resolve("file");
+ // TODO: do not use a 3rd party server, replaces test URL to a baremaps
owned test resource.
+ var task = new DownloadUrl("ftp://whois.in.bell.ca/bell.db.gz",
+ file);
+ task.execute(new WorkflowContext());
+ assertTrue(file.toFile().length() > 50, "file is less than 50 bytes");
+ FileUtils.deleteRecursively(directory);
+ }
+
+ @Test
+ @Tag("integration")
+ void testDownloadUnsupportedProtocol() throws Exception {
+ var directory = Files.createTempDirectory("tmp_");
+ var file = directory.resolve("file");
+ assertThrows(IllegalArgumentException.class, () -> {
+ var task = new DownloadUrl("file://not-existing-file-243jhks",
+ file);
+ task.execute(new WorkflowContext());
+ }, "Unsupported protocol throws IOException");
+ FileUtils.deleteRecursively(directory);
+ }
+
@Test
@Tag("integration")
void executeFileThatDoesntExist() throws Exception {
diff --git a/examples/ip-to-location/workflow.js
b/examples/ip-to-location/workflow.js
index 92c55fee..5c1f9650 100644
--- a/examples/ip-to-location/workflow.js
+++ b/examples/ip-to-location/workflow.js
@@ -9,6 +9,7 @@
or implied. See the License for the specific language governing permissions
and limitations under
the License.
**/
+// Based on https://www.irr.net/docs/list.html
const nics = [
{url: "https://ftp.afrinic.net/pub/dbase/afrinic.db.gz", filename:
"afrinic.db"},
{url: "https://ftp.apnic.net/apnic/whois/apnic.db.as-block.gz", filename:
"apnic.db.as-block.db"},
@@ -32,6 +33,19 @@ const nics = [
{url: "https://ftp.arin.net/pub/rr/arin.db.gz", filename: "arin.db"},
{url: "https://ftp.lacnic.net/lacnic/dbase/lacnic.db.gz", filename:
"lacnic.db"},
{url: "https://ftp.ripe.net/ripe/dbase/ripe.db.gz", filename: "ripe.db"},
+ {url: "ftp://ftp.altdb.net/pub/altdb/altdb.db.gz", filename: "altdb.db"},
+ {url: "ftp://whois.in.bell.ca/bell.db.gz", filename: "bell.db"},
+ {url: "ftp://irr.bboi.net/bboi.db.gz", filename: "bboi.db"},
+ {url: "https://whois.canarie.ca/dbase/canarie.db.gz", filename:
"canarie.db"},
+ {url: "ftp://irr-mirror.idnic.net/idnic.db.gz", filename: "idnic.db"},
+ {url: "ftp://ftp.nic.ad.jp/jpirr/jpirr.db.gz", filename: "jpirr.db"},
+ {url: "ftp://rr.Level3.net/level3.db.gz", filename: "level3.db"},
+ {url: "ftp://ftp.nestegg.net/irr/nestegg.db.gz", filename: "nestegg.db"},
+ {url: "ftp://rr1.ntt.net/nttcomRR/nttcom.db.gz", filename: "nttcom.db"},
+ {url: "ftp://ftp.panix.com/pub/rrdb/panix.db.gz", filename: "panix.db"},
+ {url: "ftp://ftp.radb.net/radb/dbase/radb.db.gz", filename: "radb.db"},
+ {url: "ftp://ftp.radb.net/radb/dbase/reach.db.gz", filename: "reach.db"},
+ {url: "ftp://ftp.bgp.net.br/tc.db.gz", filename: "tc.db"}
];
export default {"steps": [