STORM-3472: Add tests missing for STORM-3411, make the download file name generat… (#3091)
* STORM-3472: Add tests missing for STORM-3411, make the download file name generation code less error prone
diff --git a/storm-webapp/src/main/java/org/apache/storm/daemon/logviewer/handler/LogviewerProfileHandler.java b/storm-webapp/src/main/java/org/apache/storm/daemon/logviewer/handler/LogviewerProfileHandler.java
index 58b883a..c68ab3c 100644
--- a/storm-webapp/src/main/java/org/apache/storm/daemon/logviewer/handler/LogviewerProfileHandler.java
+++ b/storm-webapp/src/main/java/org/apache/storm/daemon/logviewer/handler/LogviewerProfileHandler.java
@@ -102,7 +102,6 @@
/**
* Download a dump file.
*
- * @param host host address
* @param topologyId topology ID
* @param hostPort host and port of worker
* @param fileName dump file name
@@ -110,8 +109,10 @@
* @return a Response which lets browsers download that file.
* @see {@link org.apache.storm.daemon.logviewer.utils.LogFileDownloader#downloadFile(String, String, String, boolean)}
*/
- public Response downloadDumpFile(String host, String topologyId, String hostPort, String fileName, String user) throws IOException {
- String portStr = hostPort.split(":")[1];
+ public Response downloadDumpFile(String topologyId, String hostPort, String fileName, String user) throws IOException {
+ String[] hostPortSplit = hostPort.split(":");
+ String host = hostPortSplit[0];
+ String portStr = hostPortSplit[1];
Path rawFile = logRoot.resolve(topologyId).resolve(portStr).resolve(fileName);
Path absFile = rawFile.toAbsolutePath().normalize();
if (!absFile.startsWith(logRoot) || !rawFile.normalize().toString().equals(rawFile.toString())) {
@@ -122,7 +123,8 @@
if (absFile.toFile().exists()) {
String workerFileRelativePath = String.join(File.separator, topologyId, portStr, WORKER_LOG_FILENAME);
if (resourceAuthorizer.isUserAllowedToAccessFile(user, workerFileRelativePath)) {
- return LogviewerResponseBuilder.buildDownloadFile(host, absFile.toFile(), numFileDownloadExceptions);
+ String downloadedFileName = host + "-" + topologyId + "-" + portStr + "-" + absFile.getFileName();
+ return LogviewerResponseBuilder.buildDownloadFile(downloadedFileName, absFile.toFile(), numFileDownloadExceptions);
} else {
return LogviewerResponseBuilder.buildResponseUnauthorizedUser(user);
}
diff --git a/storm-webapp/src/main/java/org/apache/storm/daemon/logviewer/utils/LogFileDownloader.java b/storm-webapp/src/main/java/org/apache/storm/daemon/logviewer/utils/LogFileDownloader.java
index 17eb10f..22ce298 100644
--- a/storm-webapp/src/main/java/org/apache/storm/daemon/logviewer/utils/LogFileDownloader.java
+++ b/storm-webapp/src/main/java/org/apache/storm/daemon/logviewer/utils/LogFileDownloader.java
@@ -80,7 +80,18 @@
if (file.toFile().exists()) {
if (isDaemon || resourceAuthorizer.isUserAllowedToAccessFile(user, fileName)) {
fileDownloadSizeDistMb.update(Math.round((double) file.toFile().length() / FileUtils.ONE_MB));
- return LogviewerResponseBuilder.buildDownloadFile(host, file.toFile(), numFileDownloadExceptions);
+ String downloadedFileName;
+ Path pathRelativeToRootDir = rootDir.relativize(file);
+ if (isDaemon || pathRelativeToRootDir.getNameCount() != 3) {
+ downloadedFileName = host + "-" + rawFile.getFileName();
+ } else {
+ //host-topoId-port-fileName
+ downloadedFileName = host + "-"
+ + pathRelativeToRootDir.getName(0) + "-"
+ + pathRelativeToRootDir.getName(1) + "-"
+ + pathRelativeToRootDir.getName(2);
+ }
+ return LogviewerResponseBuilder.buildDownloadFile(downloadedFileName, file.toFile(), numFileDownloadExceptions);
} else {
return LogviewerResponseBuilder.buildResponseUnauthorizedUser(user);
}
diff --git a/storm-webapp/src/main/java/org/apache/storm/daemon/logviewer/utils/LogviewerResponseBuilder.java b/storm-webapp/src/main/java/org/apache/storm/daemon/logviewer/utils/LogviewerResponseBuilder.java
index a53be71..a44c825 100644
--- a/storm-webapp/src/main/java/org/apache/storm/daemon/logviewer/utils/LogviewerResponseBuilder.java
+++ b/storm-webapp/src/main/java/org/apache/storm/daemon/logviewer/utils/LogviewerResponseBuilder.java
@@ -75,25 +75,18 @@
/**
* Build a Response object representing download a file.
*
- * @param host host address
+ * @param contentDispositionName The name to set in the Content-Disposition header
* @param file file to download
*/
- public static Response buildDownloadFile(String host, File file, Meter numFileDownloadExceptions) throws IOException {
- String fname;
- try {
- String topoInfo = file.getParentFile().getParentFile().getName();
- String port = file.getParentFile().getName();
- fname = String.format("%s-%s-%s-%s", host, port, topoInfo, file.getName());
- } catch (NullPointerException e) {
- fname = file.getName();
- }
+ public static Response buildDownloadFile(String contentDispositionName,
+ File file, Meter numFileDownloadExceptions) throws IOException {
try {
// do not close this InputStream in method: it will be used from jetty server
InputStream is = Files.newInputStream(file.toPath());
return Response.status(OK)
.entity(wrapWithStreamingOutput(is))
.type(MediaType.APPLICATION_OCTET_STREAM_TYPE)
- .header("Content-Disposition", "attachment; filename=\"" + fname + "\"")
+ .header("Content-Disposition", "attachment; filename=\"" + contentDispositionName + "\"")
.build();
} catch (IOException e) {
numFileDownloadExceptions.mark();
diff --git a/storm-webapp/src/main/java/org/apache/storm/daemon/logviewer/webapp/LogviewerResource.java b/storm-webapp/src/main/java/org/apache/storm/daemon/logviewer/webapp/LogviewerResource.java
index fb85911..d5a42ac 100644
--- a/storm-webapp/src/main/java/org/apache/storm/daemon/logviewer/webapp/LogviewerResource.java
+++ b/storm-webapp/src/main/java/org/apache/storm/daemon/logviewer/webapp/LogviewerResource.java
@@ -233,8 +233,7 @@
String user = httpCredsHandler.getUserName(request);
try {
- String host = InetAddress.getLocalHost().getCanonicalHostName();
- return profileHandler.downloadDumpFile(host, topologyId, hostPort, fileName, user);
+ return profileHandler.downloadDumpFile(topologyId, hostPort, fileName, user);
} catch (IOException e) {
numDownloadDumpExceptions.mark();
throw e;
@@ -252,7 +251,7 @@
String file = request.getParameter("file");
String decodedFileName = Utils.urlDecodeUtf8(file);
try {
- String host = InetAddress.getLocalHost().getCanonicalHostName();
+ String host = Utils.hostname();
return logDownloadHandler.downloadLogFile(host, decodedFileName, user);
} catch (IOException e) {
numDownloadLogExceptions.mark();
@@ -271,7 +270,7 @@
String file = request.getParameter("file");
String decodedFileName = Utils.urlDecodeUtf8(file);
try {
- String host = InetAddress.getLocalHost().getCanonicalHostName();
+ String host = Utils.hostname();
return logDownloadHandler.downloadDaemonLogFile(host, decodedFileName, user);
} catch (IOException e) {
numDownloadDaemonLogExceptions.mark();
diff --git a/storm-webapp/src/test/java/org/apache/storm/daemon/logviewer/handler/LogviewerLogDownloadHandlerTest.java b/storm-webapp/src/test/java/org/apache/storm/daemon/logviewer/handler/LogviewerLogDownloadHandlerTest.java
index a21ab5a..b09501f 100644
--- a/storm-webapp/src/test/java/org/apache/storm/daemon/logviewer/handler/LogviewerLogDownloadHandlerTest.java
+++ b/storm-webapp/src/test/java/org/apache/storm/daemon/logviewer/handler/LogviewerLogDownloadHandlerTest.java
@@ -19,13 +19,14 @@
package org.apache.storm.daemon.logviewer.handler;
+import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertThat;
+import com.google.common.net.HttpHeaders;
import java.io.IOException;
-import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
@@ -52,8 +53,12 @@
assertThat(topoAResponse.getStatus(), is(Response.Status.OK.getStatusCode()));
assertThat(topoAResponse.getEntity(), not(nullValue()));
+ String topoAContentDisposition = topoAResponse.getHeaderString(HttpHeaders.CONTENT_DISPOSITION);
+ assertThat(topoAContentDisposition, containsString("host-topoA-1111-worker.log"));
assertThat(topoBResponse.getStatus(), is(Response.Status.OK.getStatusCode()));
assertThat(topoBResponse.getEntity(), not(nullValue()));
+ String topoBContentDisposition = topoBResponse.getHeaderString(HttpHeaders.CONTENT_DISPOSITION);
+ assertThat(topoBContentDisposition, containsString("host-topoB-1111-worker.log"));
}
}
@@ -83,6 +88,8 @@
assertThat(response.getStatus(), is(Response.Status.OK.getStatusCode()));
assertThat(response.getEntity(), not(nullValue()));
+ String contentDisposition = response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION);
+ assertThat(contentDisposition, containsString("host-nimbus.log"));
}
}
diff --git a/storm-webapp/src/test/java/org/apache/storm/daemon/logviewer/handler/LogviewerProfileHandlerTest.java b/storm-webapp/src/test/java/org/apache/storm/daemon/logviewer/handler/LogviewerProfileHandlerTest.java
index 02744ac..0318268 100644
--- a/storm-webapp/src/test/java/org/apache/storm/daemon/logviewer/handler/LogviewerProfileHandlerTest.java
+++ b/storm-webapp/src/test/java/org/apache/storm/daemon/logviewer/handler/LogviewerProfileHandlerTest.java
@@ -25,14 +25,13 @@
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertThat;
+import com.google.common.net.HttpHeaders;
import java.io.IOException;
-import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import javax.ws.rs.core.Response;
-import org.apache.commons.io.IOUtils;
import org.apache.storm.daemon.logviewer.utils.ResourceAuthorizer;
import org.apache.storm.metric.StormMetricsRegistry;
import org.apache.storm.testing.TmpPath;
@@ -98,15 +97,19 @@
LogviewerProfileHandler handler = createHandlerTraversalTests(rootPath.getFile().toPath());
- Response topoAResponse = handler.downloadDumpFile("host","topoA", "localhost:1111", "worker.jfr", "user");
- Response topoBResponse = handler.downloadDumpFile("host","topoB", "localhost:1111", "worker.txt", "user");
+ Response topoAResponse = handler.downloadDumpFile("topoA", "localhost:1111", "worker.jfr", "user");
+ Response topoBResponse = handler.downloadDumpFile("topoB", "localhost:1111", "worker.txt", "user");
Utils.forceDelete(rootPath.toString());
assertThat(topoAResponse.getStatus(), is(Response.Status.OK.getStatusCode()));
assertThat(topoAResponse.getEntity(), not(nullValue()));
+ String topoAContentDisposition = topoAResponse.getHeaderString(HttpHeaders.CONTENT_DISPOSITION);
+ assertThat(topoAContentDisposition, containsString("localhost-topoA-1111-worker.jfr"));
assertThat(topoBResponse.getStatus(), is(Response.Status.OK.getStatusCode()));
assertThat(topoBResponse.getEntity(), not(nullValue()));
+ String topoBContentDisposition = topoBResponse.getHeaderString(HttpHeaders.CONTENT_DISPOSITION);
+ assertThat(topoBContentDisposition, containsString("localhost-topoB-1111-worker.txt"));
}
}
@@ -116,7 +119,7 @@
LogviewerProfileHandler handler = createHandlerTraversalTests(rootPath.getFile().toPath());
- Response topoAResponse = handler.downloadDumpFile("host","../../", "localhost:logs", "daemon-dump.bin", "user");
+ Response topoAResponse = handler.downloadDumpFile("../../", "localhost:logs", "daemon-dump.bin", "user");
Utils.forceDelete(rootPath.toString());
@@ -130,7 +133,7 @@
LogviewerProfileHandler handler = createHandlerTraversalTests(rootPath.getFile().toPath());
- Response topoAResponse = handler.downloadDumpFile("host","../", "localhost:../logs", "daemon-dump.bin", "user");
+ Response topoAResponse = handler.downloadDumpFile("../", "localhost:../logs", "daemon-dump.bin", "user");
Utils.forceDelete(rootPath.toString());