|
@@ -44,7 +44,10 @@ import javax.ws.rs.WebApplicationException;
|
|
|
import javax.ws.rs.core.GenericEntity;
|
|
|
import javax.ws.rs.core.Response;
|
|
|
import javax.ws.rs.core.Response.Status;
|
|
|
+import javax.ws.rs.core.StreamingOutput;
|
|
|
+import java.nio.charset.Charset;
|
|
|
import java.util.ArrayList;
|
|
|
+import java.util.Collections;
|
|
|
import java.util.List;
|
|
|
|
|
|
/**
|
|
@@ -52,6 +55,7 @@ import java.util.List;
|
|
|
* Used by various WebServices (AHS, ATS).
|
|
|
*/
|
|
|
public class LogServlet extends Configured {
|
|
|
+
|
|
|
private static final Logger LOG = LoggerFactory
|
|
|
.getLogger(LogServlet.class);
|
|
|
|
|
@@ -164,7 +168,7 @@ public class LogServlet extends Configured {
|
|
|
|
|
|
public Response getLogsInfo(HttpServletRequest hsr, String appIdStr,
|
|
|
String appAttemptIdStr, String containerIdStr, String nmId,
|
|
|
- boolean redirectedFromNode) {
|
|
|
+ boolean redirectedFromNode, boolean manualRedirection) {
|
|
|
ApplicationId appId = null;
|
|
|
if (appIdStr != null) {
|
|
|
try {
|
|
@@ -201,9 +205,10 @@ public class LogServlet extends Configured {
|
|
|
.setContainerId(containerIdStr);
|
|
|
|
|
|
return getContainerLogsInfo(hsr, logMetaRequestBuilder, nmId,
|
|
|
- redirectedFromNode, null);
|
|
|
+ redirectedFromNode, null, manualRedirection);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/**
|
|
|
* Returns information about the logs for a specific container.
|
|
|
*
|
|
@@ -212,12 +217,14 @@ public class LogServlet extends Configured {
|
|
|
* @param nmId NodeManager id
|
|
|
* @param redirectedFromNode whether the request was redirected
|
|
|
* @param clusterId the id of the cluster
|
|
|
+ * @param manualRedirection whether to return a response with a Location
|
|
|
+ * instead of an automatic redirection
|
|
|
* @return {@link Response} object containing information about the logs
|
|
|
*/
|
|
|
public Response getContainerLogsInfo(HttpServletRequest req,
|
|
|
WrappedLogMetaRequest.Builder builder,
|
|
|
String nmId, boolean redirectedFromNode,
|
|
|
- String clusterId) {
|
|
|
+ String clusterId, boolean manualRedirection) {
|
|
|
|
|
|
builder.setFactory(factory);
|
|
|
|
|
@@ -287,6 +294,10 @@ public class LogServlet extends Configured {
|
|
|
if (query != null && !query.isEmpty()) {
|
|
|
resURI += "?" + query;
|
|
|
}
|
|
|
+ if (manualRedirection) {
|
|
|
+ return createLocationResponse(resURI, createEmptyLogsInfo());
|
|
|
+ }
|
|
|
+
|
|
|
Response.ResponseBuilder response = Response.status(
|
|
|
HttpServletResponse.SC_TEMPORARY_REDIRECT);
|
|
|
response.header("Location", resURI);
|
|
@@ -297,6 +308,32 @@ public class LogServlet extends Configured {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Creates a response with empty payload and a location header to preserve
|
|
|
+ * API compatibility.
|
|
|
+ *
|
|
|
+ * @param uri redirection url
|
|
|
+ * @param emptyPayload a payload that is discarded
|
|
|
+ * @return a response with empty payload
|
|
|
+ */
|
|
|
+ private static <T> Response createLocationResponse(
|
|
|
+ String uri, T emptyPayload) {
|
|
|
+ Response.ResponseBuilder response = Response.status(
|
|
|
+ HttpServletResponse.SC_OK).entity(emptyPayload);
|
|
|
+ response.header("Location", uri);
|
|
|
+ response.header("Access-Control-Expose-Headers", "Location");
|
|
|
+ return response.build();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static GenericEntity<List<ContainerLogsInfo>> createEmptyLogsInfo() {
|
|
|
+ return new GenericEntity<List<ContainerLogsInfo>>(
|
|
|
+ Collections.EMPTY_LIST, List.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static StreamingOutput createEmptyStream() {
|
|
|
+ return outputStream -> outputStream.write(
|
|
|
+ "".getBytes(Charset.defaultCharset()));
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* Returns an aggregated log file belonging to a container.
|
|
@@ -309,11 +346,13 @@ public class LogServlet extends Configured {
|
|
|
* @param nmId NodeManager id
|
|
|
* @param redirectedFromNode whether the request was redirected
|
|
|
* @param clusterId the id of the cluster
|
|
|
+ * @param manualRedirection whether to return a response with a Location
|
|
|
+ * instead of an automatic redirection
|
|
|
* @return {@link Response} object containing information about the logs
|
|
|
*/
|
|
|
public Response getLogFile(HttpServletRequest req, String containerIdStr,
|
|
|
String filename, String format, String size, String nmId,
|
|
|
- boolean redirectedFromNode, String clusterId) {
|
|
|
+ boolean redirectedFromNode, String clusterId, boolean manualRedirection) {
|
|
|
ContainerId containerId;
|
|
|
try {
|
|
|
containerId = ContainerId.fromString(containerIdStr);
|
|
@@ -388,6 +427,12 @@ public class LogServlet extends Configured {
|
|
|
if (query != null && !query.isEmpty()) {
|
|
|
resURI += "?" + query;
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+ if (manualRedirection) {
|
|
|
+ return createLocationResponse(resURI, createEmptyStream());
|
|
|
+ }
|
|
|
+
|
|
|
Response.ResponseBuilder response = Response.status(
|
|
|
HttpServletResponse.SC_TEMPORARY_REDIRECT);
|
|
|
response.header("Location", resURI);
|