ResumingBGTDownloadInputStream.java
/*
* Copyright (C) 2021 B3Partners B.V.
*
* SPDX-License-Identifier: MIT
*/
package nl.b3p.brmo.bgt.loader;
import static nl.b3p.brmo.bgt.loader.Utils.getMessageFormattedString;
import static nl.b3p.brmo.bgt.loader.Utils.getUserAgent;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import nl.b3p.brmo.bgt.loader.cli.ConsoleProgressReporter;
import nl.b3p.brmo.bgt.schema.BGTObjectTableWriter;
import nl.b3p.brmo.util.ResumingInputStream;
import nl.b3p.brmo.util.http.HttpResponseWrapper;
import nl.b3p.brmo.util.http.HttpStartRangeInputStreamProvider;
import nl.b3p.brmo.util.http.wrapper.Java11HttpClientWrapper;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class ResumingBGTDownloadInputStream extends ResumingInputStream {
private static final Log log = LogFactory.getLog(ResumingBGTDownloadInputStream.class);
public ResumingBGTDownloadInputStream(URI uri, BGTObjectTableWriter writer) {
this(uri, writer, false);
}
public ResumingBGTDownloadInputStream(URI uri, BGTObjectTableWriter writer, boolean logRetries) {
super(
new HttpStartRangeInputStreamProvider(
uri,
new Java11HttpClientWrapper() {
@Override
public void beforeRequest(HttpRequest.Builder requestBuilder) {
requestBuilder.headers("User-Agent", getUserAgent());
}
@Override
public HttpResponseWrapper wrapResponse(HttpResponse<InputStream> response) {
HttpResponseWrapper wrapper = super.wrapResponse(response);
// The direct download
// https://api.pdok.nl/lv/bgt/download/v1_0/full/predefined/bgt-citygml-nl-nopbp.zip
// does not support the HEAD method to read the Content-Length -- it
// first sends a redirect. Read the
// Content-Length later:
// Only read Content-Length from the first response starting at
// position 0, not a response from a
// retried request starting at a later position (we could parse the
// Content-Range response though).
if (wrapper.getHeader("Content-Range") == null) {
String contentLength = wrapper.getHeader("Content-Range");
if (contentLength != null) {
((ProgressReporter) writer.getProgressUpdater())
.setTotalBytes(Long.parseLong(contentLength));
}
}
return wrapper;
}
}) {
@Override
public InputStream get(long position, int totalRetries, Exception causeForRetry)
throws IOException {
if (causeForRetry != null && logRetries) {
String msg =
getMessageFormattedString(
"download.retry",
totalRetries,
position,
ExceptionUtils.getRootCause(causeForRetry).getMessage());
if (writer.getProgressUpdater() instanceof ConsoleProgressReporter) {
System.out.println("\r" + msg);
} else {
log.warn(msg);
log.trace(causeForRetry);
}
}
return super.get(position, totalRetries, causeForRetry);
}
});
}
}