use of javax.ws.rs.core.Response.ResponseBuilder in project hadoop by apache.
the class NMWebServices method createRedirectResponse.
private Response createRedirectResponse(HttpServletRequest httpRequest, String redirectWSUrlPrefix, String uri) {
// redirect the request to the configured log server
StringBuilder redirectPath = new StringBuilder();
if (redirectWSUrlPrefix.endsWith("/")) {
redirectWSUrlPrefix = redirectWSUrlPrefix.substring(0, redirectWSUrlPrefix.length() - 1);
}
redirectPath.append(redirectWSUrlPrefix + uri);
// append all the request query parameters except nodeId parameter
String requestParams = WebAppUtils.removeQueryParams(httpRequest, YarnWebServiceParams.NM_ID);
if (requestParams != null && !requestParams.isEmpty()) {
redirectPath.append("?" + requestParams + "&" + YarnWebServiceParams.REDIRECTED_FROM_NODE + "=true");
} else {
redirectPath.append("?" + YarnWebServiceParams.REDIRECTED_FROM_NODE + "=true");
}
ResponseBuilder res = Response.status(HttpServletResponse.SC_TEMPORARY_REDIRECT);
res.header("Location", redirectPath.toString());
return res.build();
}
use of javax.ws.rs.core.Response.ResponseBuilder in project hadoop by apache.
the class NMWebServices method getLogs.
/**
* Returns the contents of a container's log file in plain text.
*
* Only works for containers that are still in the NodeManager's memory, so
* logs are no longer available after the corresponding application is no
* longer running.
*
* @param containerIdStr
* The container ID
* @param filename
* The name of the log file
* @param format
* The content type
* @param size
* the size of the log file
* @return
* The contents of the container's log file
*/
@GET
@Path("/containerlogs/{containerid}/{filename}")
@Produces({ MediaType.TEXT_PLAIN + "; " + JettyUtils.UTF_8 })
@Public
@Unstable
public Response getLogs(@PathParam(YarnWebServiceParams.CONTAINER_ID) final String containerIdStr, @PathParam(YarnWebServiceParams.CONTAINER_LOG_FILE_NAME) String filename, @QueryParam(YarnWebServiceParams.RESPONSE_CONTENT_FORMAT) String format, @QueryParam(YarnWebServiceParams.RESPONSE_CONTENT_SIZE) String size) {
ContainerId tempContainerId;
try {
tempContainerId = ContainerId.fromString(containerIdStr);
} catch (IllegalArgumentException ex) {
return Response.status(Status.BAD_REQUEST).build();
}
final ContainerId containerId = tempContainerId;
boolean tempIsRunning = false;
// check what is the status for container
try {
Container container = nmContext.getContainers().get(containerId);
tempIsRunning = (container.getContainerState() == ContainerState.RUNNING);
} catch (Exception ex) {
// assume the container has already finished.
if (LOG.isDebugEnabled()) {
LOG.debug("Can not find the container:" + containerId + " in this node.");
}
}
final boolean isRunning = tempIsRunning;
File logFile = null;
try {
logFile = ContainerLogsUtils.getContainerLogFile(containerId, filename, request.getRemoteUser(), nmContext);
} catch (NotFoundException ex) {
if (redirectWSUrl == null || redirectWSUrl.isEmpty()) {
return Response.status(Status.NOT_FOUND).entity(ex.getMessage()).build();
}
// redirect the request to the configured log server
String redirectURI = "/containers/" + containerIdStr + "/logs/" + filename;
return createRedirectResponse(request, redirectWSUrl, redirectURI);
} catch (YarnException ex) {
return Response.serverError().entity(ex.getMessage()).build();
}
final long bytes = parseLongParam(size);
final String lastModifiedTime = Times.format(logFile.lastModified());
final String outputFileName = filename;
String contentType = WebAppUtils.getDefaultLogContentType();
if (format != null && !format.isEmpty()) {
contentType = WebAppUtils.getSupportedLogContentType(format);
if (contentType == null) {
String errorMessage = "The valid values for the parameter : format " + "are " + WebAppUtils.listSupportedLogContentType();
return Response.status(Status.BAD_REQUEST).entity(errorMessage).build();
}
}
try {
final FileInputStream fis = ContainerLogsUtils.openLogFileForRead(containerIdStr, logFile, nmContext);
final long fileLength = logFile.length();
StreamingOutput stream = new StreamingOutput() {
@Override
public void write(OutputStream os) throws IOException, WebApplicationException {
try {
int bufferSize = 65536;
byte[] buf = new byte[bufferSize];
LogToolUtils.outputContainerLog(containerId.toString(), nmContext.getNodeId().toString(), outputFileName, fileLength, bytes, lastModifiedTime, fis, os, buf, ContainerLogAggregationType.LOCAL);
StringBuilder sb = new StringBuilder();
String endOfFile = "End of LogType:" + outputFileName;
sb.append(endOfFile + ".");
if (isRunning) {
sb.append("This log file belongs to a running container (" + containerIdStr + ") and so may not be complete." + "\n");
} else {
sb.append("\n");
}
sb.append(StringUtils.repeat("*", endOfFile.length() + 50) + "\n\n");
os.write(sb.toString().getBytes(Charset.forName("UTF-8")));
// If we have aggregated logs for this container,
// output the aggregation logs as well.
ApplicationId appId = containerId.getApplicationAttemptId().getApplicationId();
Application app = nmContext.getApplications().get(appId);
String appOwner = app == null ? null : app.getUser();
try {
LogToolUtils.outputAggregatedContainerLog(nmContext.getConf(), appId, appOwner, containerId.toString(), nmContext.getNodeId().toString(), outputFileName, bytes, os, buf);
} catch (Exception ex) {
// Something wrong when we try to access the aggregated log.
if (LOG.isDebugEnabled()) {
LOG.debug("Can not access the aggregated log for " + "the container:" + containerId);
LOG.debug(ex.getMessage());
}
}
} finally {
IOUtils.closeQuietly(fis);
}
}
};
ResponseBuilder resp = Response.ok(stream);
resp.header("Content-Type", contentType + "; " + JettyUtils.UTF_8);
// Sending the X-Content-Type-Options response header with the value
// nosniff will prevent Internet Explorer from MIME-sniffing a response
// away from the declared content-type.
resp.header("X-Content-Type-Options", "nosniff");
return resp.build();
} catch (IOException ex) {
return Response.serverError().entity(ex.getMessage()).build();
}
}
use of javax.ws.rs.core.Response.ResponseBuilder in project hadoop by apache.
the class NMWebServices method getContainerLogsInfo.
/**
* Returns log file's name as well as current file size for a container.
*
* @param hsr
* HttpServletRequest
* @param res
* HttpServletResponse
* @param containerIdStr
* The container ID
* @return
* The log file's name and current file size
*/
@GET
@Path("/containers/{containerid}/logs")
@Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
public Response getContainerLogsInfo(@javax.ws.rs.core.Context HttpServletRequest hsr, @javax.ws.rs.core.Context HttpServletResponse res, @PathParam(YarnWebServiceParams.CONTAINER_ID) String containerIdStr) {
ContainerId containerId = null;
init();
try {
containerId = ContainerId.fromString(containerIdStr);
} catch (IllegalArgumentException ex) {
throw new BadRequestException("invalid container id, " + containerIdStr);
}
try {
List<ContainerLogsInfo> containersLogsInfo = new ArrayList<>();
containersLogsInfo.add(new NMContainerLogsInfo(this.nmContext, containerId, hsr.getRemoteUser(), ContainerLogAggregationType.LOCAL));
// check whether we have aggregated logs in RemoteFS. If exists, show the
// the log meta for the aggregated logs as well.
ApplicationId appId = containerId.getApplicationAttemptId().getApplicationId();
Application app = this.nmContext.getApplications().get(appId);
String appOwner = app == null ? null : app.getUser();
try {
List<ContainerLogMeta> containerLogMeta = LogToolUtils.getContainerLogMetaFromRemoteFS(this.nmContext.getConf(), appId, containerIdStr, this.nmContext.getNodeId().toString(), appOwner);
if (!containerLogMeta.isEmpty()) {
for (ContainerLogMeta logMeta : containerLogMeta) {
containersLogsInfo.add(new ContainerLogsInfo(logMeta, ContainerLogAggregationType.AGGREGATED));
}
}
} catch (IOException ex) {
// Skip it and do nothing
if (LOG.isDebugEnabled()) {
LOG.debug(ex.getMessage());
}
}
GenericEntity<List<ContainerLogsInfo>> meta = new GenericEntity<List<ContainerLogsInfo>>(containersLogsInfo) {
};
ResponseBuilder resp = Response.ok(meta);
// Sending the X-Content-Type-Options response header with the value
// nosniff will prevent Internet Explorer from MIME-sniffing a response
// away from the declared content-type.
resp.header("X-Content-Type-Options", "nosniff");
return resp.build();
} catch (Exception ex) {
if (redirectWSUrl == null || redirectWSUrl.isEmpty()) {
throw new WebApplicationException(ex);
}
// redirect the request to the configured log server
String redirectURI = "/containers/" + containerIdStr + "/logs";
return createRedirectResponse(hsr, redirectWSUrl, redirectURI);
}
}
use of javax.ws.rs.core.Response.ResponseBuilder in project hadoop by apache.
the class AHSWebServices method getLogs.
//TODO: YARN-4993: Refactory ContainersLogsBlock, AggregatedLogsBlock and
// container log webservice introduced in AHS to minimize
// the duplication.
@GET
@Path("/containerlogs/{containerid}/{filename}")
@Produces({ MediaType.TEXT_PLAIN + "; " + JettyUtils.UTF_8 })
@Public
@Unstable
public Response getLogs(@Context HttpServletRequest req, @Context HttpServletResponse res, @PathParam(YarnWebServiceParams.CONTAINER_ID) String containerIdStr, @PathParam(YarnWebServiceParams.CONTAINER_LOG_FILE_NAME) String filename, @QueryParam(YarnWebServiceParams.RESPONSE_CONTENT_FORMAT) String format, @QueryParam(YarnWebServiceParams.RESPONSE_CONTENT_SIZE) String size, @QueryParam(YarnWebServiceParams.NM_ID) String nmId, @QueryParam(YarnWebServiceParams.REDIRECTED_FROM_NODE) @DefaultValue("false") boolean redirected_from_node) {
init(res);
ContainerId containerId;
try {
containerId = ContainerId.fromString(containerIdStr);
} catch (IllegalArgumentException ex) {
return createBadResponse(Status.NOT_FOUND, "Invalid ContainerId: " + containerIdStr);
}
final long length = parseLongParam(size);
ApplicationId appId = containerId.getApplicationAttemptId().getApplicationId();
AppInfo appInfo;
try {
appInfo = super.getApp(req, res, appId.toString());
} catch (Exception ex) {
// directly find logs from HDFS.
return sendStreamOutputResponse(appId, null, null, containerIdStr, filename, format, length, false);
}
String appOwner = appInfo.getUser();
if (isFinishedState(appInfo.getAppState())) {
// directly find logs from HDFS.
return sendStreamOutputResponse(appId, appOwner, null, containerIdStr, filename, format, length, false);
}
if (isRunningState(appInfo.getAppState())) {
String nodeHttpAddress = null;
if (nmId != null && !nmId.isEmpty()) {
try {
nodeHttpAddress = getNMWebAddressFromRM(conf, nmId);
} catch (Exception ex) {
if (LOG.isDebugEnabled()) {
LOG.debug(ex.getMessage());
}
}
}
if (nodeHttpAddress == null || nodeHttpAddress.isEmpty()) {
ContainerInfo containerInfo;
try {
containerInfo = super.getContainer(req, res, appId.toString(), containerId.getApplicationAttemptId().toString(), containerId.toString());
} catch (Exception ex) {
// output the aggregated logs
return sendStreamOutputResponse(appId, appOwner, null, containerIdStr, filename, format, length, true);
}
nodeHttpAddress = containerInfo.getNodeHttpAddress();
// request back. Simply output the aggregated logs.
if (nodeHttpAddress == null || nodeHttpAddress.isEmpty() || redirected_from_node) {
// output the aggregated logs
return sendStreamOutputResponse(appId, appOwner, null, containerIdStr, filename, format, length, true);
}
}
String uri = "/" + containerId.toString() + "/logs/" + filename;
String resURI = JOINER.join(getAbsoluteNMWebAddress(nodeHttpAddress), NM_DOWNLOAD_URI_STR, uri);
String query = req.getQueryString();
if (query != null && !query.isEmpty()) {
resURI += "?" + query;
}
ResponseBuilder response = Response.status(HttpServletResponse.SC_TEMPORARY_REDIRECT);
response.header("Location", resURI);
return response.build();
} else {
return createBadResponse(Status.NOT_FOUND, "The application is not at Running or Finished State.");
}
}
use of javax.ws.rs.core.Response.ResponseBuilder in project hbase by apache.
the class RowResource method checkAndDelete.
/**
* Validates the input request parameters, parses columns from CellSetModel,
* and invokes checkAndDelete on HTable.
*
* @param model instance of CellSetModel
* @return Response 200 OK, 304 Not modified, 400 Bad request
*/
Response checkAndDelete(final CellSetModel model) {
Table table = null;
Delete delete = null;
try {
table = servlet.getTable(tableResource.getName());
if (model.getRows().size() != 1) {
servlet.getMetrics().incrementFailedDeleteRequests(1);
return Response.status(Response.Status.BAD_REQUEST).type(MIMETYPE_TEXT).entity("Bad request" + CRLF).build();
}
RowModel rowModel = model.getRows().get(0);
byte[] key = rowModel.getKey();
if (key == null) {
key = rowspec.getRow();
}
if (key == null) {
servlet.getMetrics().incrementFailedDeleteRequests(1);
return Response.status(Response.Status.BAD_REQUEST).type(MIMETYPE_TEXT).entity("Bad request: Row key found to be null." + CRLF).build();
}
List<CellModel> cellModels = rowModel.getCells();
int cellModelCount = cellModels.size();
delete = new Delete(key);
boolean retValue;
CellModel valueToDeleteCell = rowModel.getCells().get(cellModelCount - 1);
byte[] valueToDeleteColumn = valueToDeleteCell.getColumn();
if (valueToDeleteColumn == null) {
try {
valueToDeleteColumn = rowspec.getColumns()[0];
} catch (final ArrayIndexOutOfBoundsException e) {
servlet.getMetrics().incrementFailedDeleteRequests(1);
return Response.status(Response.Status.BAD_REQUEST).type(MIMETYPE_TEXT).entity("Bad request: Column not specified for check." + CRLF).build();
}
}
byte[][] parts;
// Copy all the cells to the Delete request if extra cells are sent
if (cellModelCount > 1) {
for (int i = 0, n = cellModelCount - 1; i < n; i++) {
CellModel cell = cellModels.get(i);
byte[] col = cell.getColumn();
if (col == null) {
servlet.getMetrics().incrementFailedPutRequests(1);
return Response.status(Response.Status.BAD_REQUEST).type(MIMETYPE_TEXT).entity("Bad request: Column found to be null." + CRLF).build();
}
parts = KeyValue.parseColumn(col);
if (parts.length == 1) {
// Only Column Family is specified
delete.addFamily(parts[0], cell.getTimestamp());
} else if (parts.length == 2) {
delete.addColumn(parts[0], parts[1], cell.getTimestamp());
} else {
servlet.getMetrics().incrementFailedDeleteRequests(1);
return Response.status(Response.Status.BAD_REQUEST).type(MIMETYPE_TEXT).entity("Bad request: Column to delete incorrectly specified." + CRLF).build();
}
}
}
parts = KeyValue.parseColumn(valueToDeleteColumn);
if (parts.length == 2) {
if (parts[1].length != 0) {
// if that is the only cell passed to the rest api
if (cellModelCount == 1) {
delete.addColumns(parts[0], parts[1]);
}
retValue = table.checkAndDelete(key, parts[0], parts[1], valueToDeleteCell.getValue(), delete);
} else {
// The case of empty qualifier.
if (cellModelCount == 1) {
delete.addColumns(parts[0], Bytes.toBytes(StringUtils.EMPTY));
}
retValue = table.checkAndDelete(key, parts[0], Bytes.toBytes(StringUtils.EMPTY), valueToDeleteCell.getValue(), delete);
}
} else {
servlet.getMetrics().incrementFailedDeleteRequests(1);
return Response.status(Response.Status.BAD_REQUEST).type(MIMETYPE_TEXT).entity("Bad request: Column to check incorrectly specified." + CRLF).build();
}
if (LOG.isTraceEnabled()) {
LOG.trace("CHECK-AND-DELETE " + delete.toString() + ", returns " + retValue);
}
if (!retValue) {
servlet.getMetrics().incrementFailedDeleteRequests(1);
return Response.status(Response.Status.NOT_MODIFIED).type(MIMETYPE_TEXT).entity(" Delete check failed." + CRLF).build();
}
ResponseBuilder response = Response.ok();
servlet.getMetrics().incrementSucessfulDeleteRequests(1);
return response.build();
} catch (Exception e) {
servlet.getMetrics().incrementFailedDeleteRequests(1);
return processException(e);
} finally {
if (table != null)
try {
table.close();
} catch (IOException ioe) {
LOG.debug("Exception received while closing the table", ioe);
}
}
}
Aggregations