public void check(String addr) throws IOException { Configuration conf = new Configuration(); File fhdfs = new File("hdfs-site.xml"); InputStream inhdfs = new FileInputStream(fhdfs); File fcore = new File("core-site.xml"); InputStream incore = new FileInputStream(fcore); conf.addResource(inhdfs); conf.addResource(incore); InetSocketAddress inetSocketAddress = new InetSocketAddress(addr, 9000); DFSClient client = new DFSClient(inetSocketAddress, conf); if (client.getMissingBlocksCount() > 0) { System.out.println("[ERROR] missing block count > 0"); this.alert("[" + addr + "-HDFS检查]", "missing block个数大于0"); } else { System.out.println("[INFO] there is no missing block count in cluster."); } DatanodeInfo[] datanodeInfos = client.datanodeReport(HdfsConstants.DatanodeReportType.DEAD); if (datanodeInfos.length > 0) { String ips = ""; for (DatanodeInfo info : datanodeInfos) { ips += info.getIpAddr() + ";"; } System.out.println("[ERROR] dead node ips is : " + ips); this.alert("[" + addr + "-HDFS检查]", "DEAD node个数大于0"); } else { System.out.println("[INFO] dead node size is 0."); } org.apache.hadoop.fs.Path path = new Path(this.hdfsPath); FileSystem fs = null; FSDataOutputStream output = null; try { fs = path.getFileSystem(conf); if (fs.exists(path)) { System.out.println("[INFO] " + hdfsPath + " already exists."); fs.delete(path, false); } output = fs.create(path); for (String line : contents) { output.write(line.getBytes("UTF-8")); output.flush(); } } catch (IOException e) { e.printStackTrace(); System.out.println("[ERROR] write content failed."); this.alert("[" + addr + "-HDFS检查]", "HDFS可用性异常,删除写入文件失败"); } finally { try { output.close(); System.out.println("[INFO] delete and write file success."); } catch (IOException e) { e.printStackTrace(); } } client.close(); }
private void onGetFileChecksum(ChannelHandlerContext ctx) throws IOException { MD5MD5CRC32FileChecksum checksum = null; final String nnId = params.namenodeId(); DFSClient dfsclient = newDfsClient(nnId, conf); try { checksum = dfsclient.getFileChecksum(path, Long.MAX_VALUE); dfsclient.close(); dfsclient = null; } finally { IOUtils.cleanup(LOG, dfsclient); } final byte[] js = JsonUtil.toJsonString(checksum).getBytes(Charsets.UTF_8); DefaultFullHttpResponse resp = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(js)); resp.headers().set(CONTENT_TYPE, APPLICATION_JSON_UTF8); resp.headers().set(CONTENT_LENGTH, js.length); resp.headers().set(CONNECTION, CLOSE); ctx.writeAndFlush(resp).addListener(ChannelFutureListener.CLOSE); }
@SuppressWarnings("unchecked") public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { final String path = ServletUtil.getDecodedPath(request, "/streamFile"); final String rawPath = ServletUtil.getRawPath(request, "/streamFile"); final String filename = JspHelper.validatePath(path); final String rawFilename = JspHelper.validatePath(rawPath); if (filename == null) { response.setContentType("text/plain"); PrintWriter out = response.getWriter(); out.print("Invalid input"); return; } Enumeration<String> reqRanges = request.getHeaders("Range"); if (reqRanges != null && !reqRanges.hasMoreElements()) { reqRanges = null; } DFSClient dfs; try { dfs = getDFSClient(request); } catch (InterruptedException e) { response.sendError(400, e.getMessage()); return; } DFSInputStream in = null; OutputStream out = null; try { in = dfs.open(filename); out = response.getOutputStream(); final long fileLen = in.getFileLength(); if (reqRanges != null) { List<InclusiveByteRange> ranges = InclusiveByteRange.satisfiableRanges(reqRanges, fileLen); StreamFile.sendPartialData(in, out, response, fileLen, ranges); } else { // No ranges, so send entire file response.setHeader("Content-Disposition", "attachment; filename=\"" + rawFilename + "\""); response.setContentType("application/octet-stream"); response.setHeader(CONTENT_LENGTH, "" + fileLen); StreamFile.copyFromOffset(in, out, 0L, fileLen); } in.close(); in = null; out.close(); out = null; dfs.close(); dfs = null; } catch (IOException ioe) { if (LOG.isDebugEnabled()) { LOG.debug("response.isCommitted()=" + response.isCommitted(), ioe); } throw ioe; } finally { IOUtils.cleanup(LOG, in); IOUtils.cleanup(LOG, out); IOUtils.cleanup(LOG, dfs); } }
protected void doTestRead(Configuration conf, MiniDFSCluster cluster, boolean isStriped) throws Exception { final int numDataNodes = cluster.getDataNodes().size(); final NameNode nn = cluster.getNameNode(); final NamenodeProtocols nnProto = nn.getRpcServer(); final BlockManager bm = nn.getNamesystem().getBlockManager(); final BlockTokenSecretManager sm = bm.getBlockTokenSecretManager(); // set a short token lifetime (1 second) initially SecurityTestUtil.setBlockTokenLifetime(sm, 1000L); Path fileToRead = new Path(FILE_TO_READ); FileSystem fs = cluster.getFileSystem(); byte[] expected = generateBytes(FILE_SIZE); createFile(fs, fileToRead, expected); /* * setup for testing expiration handling of cached tokens */ // read using blockSeekTo(). Acquired tokens are cached in in1 FSDataInputStream in1 = fs.open(fileToRead); assertTrue(checkFile1(in1, expected)); // read using blockSeekTo(). Acquired tokens are cached in in2 FSDataInputStream in2 = fs.open(fileToRead); assertTrue(checkFile1(in2, expected)); // read using fetchBlockByteRange(). Acquired tokens are cached in in3 FSDataInputStream in3 = fs.open(fileToRead); assertTrue(checkFile2(in3, expected)); /* * testing READ interface on DN using a BlockReader */ DFSClient client = null; try { client = new DFSClient(new InetSocketAddress("localhost", cluster.getNameNodePort()), conf); } finally { if (client != null) client.close(); } List<LocatedBlock> locatedBlocks = nnProto.getBlockLocations(FILE_TO_READ, 0, FILE_SIZE).getLocatedBlocks(); LocatedBlock lblock = locatedBlocks.get(0); // first block // verify token is not expired assertFalse(isBlockTokenExpired(lblock)); // read with valid token, should succeed tryRead(conf, lblock, true); /* * wait till myToken and all cached tokens in in1, in2 and in3 expire */ while (!isBlockTokenExpired(lblock)) { try { Thread.sleep(10); } catch (InterruptedException ignored) { } } /* * continue testing READ interface on DN using a BlockReader */ // verify token is expired assertTrue(isBlockTokenExpired(lblock)); // read should fail tryRead(conf, lblock, false); // use a valid new token bm.setBlockToken(lblock, BlockTokenIdentifier.AccessMode.READ); // read should succeed tryRead(conf, lblock, true); // use a token with wrong blockID long rightId = lblock.getBlock().getBlockId(); long wrongId = rightId + 1; lblock.getBlock().setBlockId(wrongId); bm.setBlockToken(lblock, BlockTokenIdentifier.AccessMode.READ); lblock.getBlock().setBlockId(rightId); // read should fail tryRead(conf, lblock, false); // use a token with wrong access modes bm.setBlockToken(lblock, BlockTokenIdentifier.AccessMode.WRITE); // read should fail tryRead(conf, lblock, false); // set a long token lifetime for future tokens SecurityTestUtil.setBlockTokenLifetime(sm, 600 * 1000L); /* * testing that when cached tokens are expired, DFSClient will re-fetch * tokens transparently for READ. */ // confirm all tokens cached in in1 are expired by now List<LocatedBlock> lblocks = DFSTestUtil.getAllBlocks(in1); for (LocatedBlock blk : lblocks) { assertTrue(isBlockTokenExpired(blk)); } // verify blockSeekTo() is able to re-fetch token transparently in1.seek(0); assertTrue(checkFile1(in1, expected)); // confirm all tokens cached in in2 are expired by now List<LocatedBlock> lblocks2 = DFSTestUtil.getAllBlocks(in2); for (LocatedBlock blk : lblocks2) { assertTrue(isBlockTokenExpired(blk)); } // verify blockSeekTo() is able to re-fetch token transparently (testing // via another interface method) if (isStriped) { // striped block doesn't support seekToNewSource in2.seek(0); } else { assertTrue(in2.seekToNewSource(0)); } assertTrue(checkFile1(in2, expected)); // confirm all tokens cached in in3 are expired by now List<LocatedBlock> lblocks3 = DFSTestUtil.getAllBlocks(in3); for (LocatedBlock blk : lblocks3) { assertTrue(isBlockTokenExpired(blk)); } // verify fetchBlockByteRange() is able to re-fetch token transparently assertTrue(checkFile2(in3, expected)); /* * testing that after datanodes are restarted on the same ports, cached * tokens should still work and there is no need to fetch new tokens from * namenode. This test should run while namenode is down (to make sure no * new tokens can be fetched from namenode). */ // restart datanodes on the same ports that they currently use assertTrue(cluster.restartDataNodes(true)); cluster.waitActive(); assertEquals(numDataNodes, cluster.getDataNodes().size()); cluster.shutdownNameNode(0); // confirm tokens cached in in1 are still valid lblocks = DFSTestUtil.getAllBlocks(in1); for (LocatedBlock blk : lblocks) { assertFalse(isBlockTokenExpired(blk)); } // verify blockSeekTo() still works (forced to use cached tokens) in1.seek(0); assertTrue(checkFile1(in1, expected)); // confirm tokens cached in in2 are still valid lblocks2 = DFSTestUtil.getAllBlocks(in2); for (LocatedBlock blk : lblocks2) { assertFalse(isBlockTokenExpired(blk)); } // verify blockSeekTo() still works (forced to use cached tokens) if (isStriped) { in2.seek(0); } else { in2.seekToNewSource(0); } assertTrue(checkFile1(in2, expected)); // confirm tokens cached in in3 are still valid lblocks3 = DFSTestUtil.getAllBlocks(in3); for (LocatedBlock blk : lblocks3) { assertFalse(isBlockTokenExpired(blk)); } // verify fetchBlockByteRange() still works (forced to use cached tokens) assertTrue(checkFile2(in3, expected)); /* * testing that when namenode is restarted, cached tokens should still * work and there is no need to fetch new tokens from namenode. Like the * previous test, this test should also run while namenode is down. The * setup for this test depends on the previous test. */ // restart the namenode and then shut it down for test cluster.restartNameNode(0); cluster.shutdownNameNode(0); // verify blockSeekTo() still works (forced to use cached tokens) in1.seek(0); assertTrue(checkFile1(in1, expected)); // verify again blockSeekTo() still works (forced to use cached tokens) if (isStriped) { in2.seek(0); } else { in2.seekToNewSource(0); } assertTrue(checkFile1(in2, expected)); // verify fetchBlockByteRange() still works (forced to use cached tokens) assertTrue(checkFile2(in3, expected)); /* * testing that after both namenode and datanodes got restarted (namenode * first, followed by datanodes), DFSClient can't access DN without * re-fetching tokens and is able to re-fetch tokens transparently. The * setup of this test depends on the previous test. */ // restore the cluster and restart the datanodes for test cluster.restartNameNode(0); assertTrue(cluster.restartDataNodes(true)); cluster.waitActive(); assertEquals(numDataNodes, cluster.getDataNodes().size()); // shutdown namenode so that DFSClient can't get new tokens from namenode cluster.shutdownNameNode(0); // verify blockSeekTo() fails (cached tokens become invalid) in1.seek(0); assertFalse(checkFile1(in1, expected)); // verify fetchBlockByteRange() fails (cached tokens become invalid) assertFalse(checkFile2(in3, expected)); // restart the namenode to allow DFSClient to re-fetch tokens cluster.restartNameNode(0); // verify blockSeekTo() works again (by transparently re-fetching // tokens from namenode) in1.seek(0); assertTrue(checkFile1(in1, expected)); if (isStriped) { in2.seek(0); } else { in2.seekToNewSource(0); } assertTrue(checkFile1(in2, expected)); // verify fetchBlockByteRange() works again (by transparently // re-fetching tokens from namenode) assertTrue(checkFile2(in3, expected)); /* * testing that when datanodes are restarted on different ports, DFSClient * is able to re-fetch tokens transparently to connect to them */ // restart datanodes on newly assigned ports assertTrue(cluster.restartDataNodes(false)); cluster.waitActive(); assertEquals(numDataNodes, cluster.getDataNodes().size()); // verify blockSeekTo() is able to re-fetch token transparently in1.seek(0); assertTrue(checkFile1(in1, expected)); // verify blockSeekTo() is able to re-fetch token transparently if (isStriped) { in2.seek(0); } else { in2.seekToNewSource(0); } assertTrue(checkFile1(in2, expected)); // verify fetchBlockByteRange() is able to re-fetch token transparently assertTrue(checkFile2(in3, expected)); }
private void copyBlocksToLostFound(String parent, HdfsFileStatus file, LocatedBlocks blocks) throws IOException { final DFSClient dfs = new DFSClient(NameNode.getAddress(conf), conf); final String fullName = file.getFullName(parent); OutputStream fos = null; try { if (!lfInited) { lostFoundInit(dfs); } if (!lfInitedOk) { throw new IOException("failed to initialize lost+found"); } String target = lostFound + fullName; if (hdfsPathExists(target)) { LOG.warn( "Fsck: can't copy the remains of " + fullName + " to " + "lost+found, because " + target + " already exists."); return; } if (!namenode.getRpcServer().mkdirs(target, file.getPermission(), true)) { throw new IOException("failed to create directory " + target); } // create chains int chain = 0; boolean copyError = false; for (LocatedBlock lBlk : blocks.getLocatedBlocks()) { LocatedBlock lblock = lBlk; DatanodeInfo[] locs = lblock.getLocations(); if (locs == null || locs.length == 0) { if (fos != null) { fos.flush(); fos.close(); fos = null; } continue; } if (fos == null) { fos = dfs.create(target + "/" + chain, true); if (fos == null) { throw new IOException( "Failed to copy " + fullName + " to /lost+found: could not store chain " + chain); } chain++; } // copy the block. It's a pity it's not abstracted from DFSInputStream ... try { copyBlock(dfs, lblock, fos); } catch (Exception e) { LOG.error("Fsck: could not copy block " + lblock.getBlock() + " to " + target, e); fos.flush(); fos.close(); fos = null; internalError = true; copyError = true; } } if (copyError) { LOG.warn( "Fsck: there were errors copying the remains of the " + "corrupted file " + fullName + " to /lost+found"); } else { LOG.info("Fsck: copied the remains of the corrupted file " + fullName + " to /lost+found"); } } catch (Exception e) { LOG.error("copyBlocksToLostFound: error processing " + fullName, e); internalError = true; } finally { if (fos != null) fos.close(); dfs.close(); } }
static void generateDirectoryStructure( JspWriter out, HttpServletRequest req, HttpServletResponse resp, Configuration conf) throws IOException, InterruptedException { final String dir = JspHelper.validatePath(StringEscapeUtils.unescapeHtml(req.getParameter("dir"))); if (dir == null) { out.print("Invalid input"); return; } String tokenString = req.getParameter(JspHelper.DELEGATION_PARAMETER_NAME); UserGroupInformation ugi = JspHelper.getUGI(req, conf); String namenodeInfoPortStr = req.getParameter("namenodeInfoPort"); int namenodeInfoPort = -1; if (namenodeInfoPortStr != null) namenodeInfoPort = Integer.parseInt(namenodeInfoPortStr); final String nnAddr = req.getParameter(JspHelper.NAMENODE_ADDRESS); if (nnAddr == null) { out.print(JspHelper.NAMENODE_ADDRESS + " url param is null"); return; } DFSClient dfs = getDFSClient(ugi, nnAddr, conf); String target = dir; final HdfsFileStatus targetStatus = dfs.getFileInfo(target); if (targetStatus == null) { // not exists out.print("<h3>File or directory : " + target + " does not exist</h3>"); JspHelper.printGotoForm(out, namenodeInfoPort, tokenString, target, nnAddr); } else { if (!targetStatus.isDir()) { // a file List<LocatedBlock> blocks = dfs.getNamenode().getBlockLocations(dir, 0, 1).getLocatedBlocks(); LocatedBlock firstBlock = null; DatanodeInfo[] locations = null; if (blocks.size() > 0) { firstBlock = blocks.get(0); locations = firstBlock.getLocations(); } if (locations == null || locations.length == 0) { out.print("Empty file"); } else { DatanodeInfo chosenNode = JspHelper.bestNode(firstBlock, conf); String fqdn = canonicalize(chosenNode.getIpAddr()); int datanodePort = chosenNode.getXferPort(); String redirectLocation = "http://" + fqdn + ":" + chosenNode.getInfoPort() + "/browseBlock.jsp?blockId=" + firstBlock.getBlock().getBlockId() + "&blockSize=" + firstBlock.getBlock().getNumBytes() + "&genstamp=" + firstBlock.getBlock().getGenerationStamp() + "&filename=" + URLEncoder.encode(dir, "UTF-8") + "&datanodePort=" + datanodePort + "&namenodeInfoPort=" + namenodeInfoPort + JspHelper.getDelegationTokenUrlParam(tokenString) + JspHelper.getUrlParam(JspHelper.NAMENODE_ADDRESS, nnAddr); resp.sendRedirect(redirectLocation); } return; } // directory // generate a table and dump the info String[] headings = { "Name", "Type", "Size", "Replication", "Block Size", "Modification Time", "Permission", "Owner", "Group" }; out.print("<h3>Contents of directory "); JspHelper.printPathWithLinks(dir, out, namenodeInfoPort, tokenString, nnAddr); out.print("</h3><hr>"); JspHelper.printGotoForm(out, namenodeInfoPort, tokenString, dir, nnAddr); out.print("<hr>"); File f = new File(dir); String parent; if ((parent = f.getParent()) != null) out.print( "<a href=\"" + req.getRequestURL() + "?dir=" + parent + "&namenodeInfoPort=" + namenodeInfoPort + JspHelper.getDelegationTokenUrlParam(tokenString) + JspHelper.getUrlParam(JspHelper.NAMENODE_ADDRESS, nnAddr) + "\">Go to parent directory</a><br>"); DirectoryListing thisListing = dfs.listPaths(target, HdfsFileStatus.EMPTY_NAME); if (thisListing == null || thisListing.getPartialListing().length == 0) { out.print("Empty directory"); } else { JspHelper.addTableHeader(out); int row = 0; JspHelper.addTableRow(out, headings, row++); String cols[] = new String[headings.length]; do { HdfsFileStatus[] files = thisListing.getPartialListing(); for (int i = 0; i < files.length; i++) { String localFileName = files[i].getLocalName(); // Get the location of the first block of the file if (!files[i].isDir()) { cols[1] = "file"; cols[2] = StringUtils.byteDesc(files[i].getLen()); cols[3] = Short.toString(files[i].getReplication()); cols[4] = StringUtils.byteDesc(files[i].getBlockSize()); } else { cols[1] = "dir"; cols[2] = ""; cols[3] = ""; cols[4] = ""; } String datanodeUrl = req.getRequestURL() + "?dir=" + URLEncoder.encode(files[i].getFullName(target), "UTF-8") + "&namenodeInfoPort=" + namenodeInfoPort + JspHelper.getDelegationTokenUrlParam(tokenString) + JspHelper.getUrlParam(JspHelper.NAMENODE_ADDRESS, nnAddr); cols[0] = "<a href=\"" + datanodeUrl + "\">" + localFileName + "</a>"; cols[5] = lsDateFormat.format(new Date((files[i].getModificationTime()))); cols[6] = files[i].getPermission().toString(); cols[7] = files[i].getOwner(); cols[8] = files[i].getGroup(); JspHelper.addTableRow(out, cols, row++); } if (!thisListing.hasMore()) { break; } thisListing = dfs.listPaths(target, thisListing.getLastName()); } while (thisListing != null); JspHelper.addTableFooter(out); } } out.print( "<br><a href=\"http://" + canonicalize(nnAddr) + ":" + namenodeInfoPort + "/dfshealth.jsp\">Go back to DFS home</a>"); dfs.close(); }
static void generateFileChunksForTail(JspWriter out, HttpServletRequest req, Configuration conf) throws IOException, InterruptedException { String referrer = null; boolean noLink = false; try { referrer = new URL(req.getParameter("referrer")).toString(); } catch (IOException e) { referrer = null; noLink = true; } final String filename = JspHelper.validatePath(StringEscapeUtils.unescapeHtml(req.getParameter("filename"))); if (filename == null) { out.print("Invalid input (file name absent)"); return; } String tokenString = req.getParameter(JspHelper.DELEGATION_PARAMETER_NAME); UserGroupInformation ugi = JspHelper.getUGI(req, conf); String namenodeInfoPortStr = req.getParameter("namenodeInfoPort"); String nnAddr = req.getParameter(JspHelper.NAMENODE_ADDRESS); int namenodeInfoPort = -1; if (namenodeInfoPortStr != null) namenodeInfoPort = Integer.parseInt(namenodeInfoPortStr); final int chunkSizeToView = JspHelper.string2ChunkSizeToView( req.getParameter("chunkSizeToView"), getDefaultChunkSize(conf)); if (!noLink) { out.print("<h3>Tail of File: "); JspHelper.printPathWithLinks(filename, out, namenodeInfoPort, tokenString, nnAddr); out.print("</h3><hr>"); out.print("<a href=\"" + referrer + "\">Go Back to File View</a><hr>"); } else { out.print("<h3>" + filename + "</h3>"); } out.print("<b>Chunk size to view (in bytes, up to file's DFS block size): </b>"); out.print( "<input type=\"text\" name=\"chunkSizeToView\" value=" + chunkSizeToView + " size=10 maxlength=10>"); out.print(" <input type=\"submit\" name=\"submit\" value=\"Refresh\"><hr>"); out.print("<input type=\"hidden\" name=\"filename\" value=\"" + filename + "\">"); out.print( "<input type=\"hidden\" name=\"namenodeInfoPort\" value=\"" + namenodeInfoPort + "\">"); out.print( "<input type=\"hidden\" name=\"" + JspHelper.NAMENODE_ADDRESS + "\" value=\"" + nnAddr + "\">"); if (!noLink) out.print("<input type=\"hidden\" name=\"referrer\" value=\"" + referrer + "\">"); // fetch the block from the datanode that has the last block for this file final DFSClient dfs = getDFSClient(ugi, nnAddr, conf); List<LocatedBlock> blocks = dfs.getNamenode().getBlockLocations(filename, 0, Long.MAX_VALUE).getLocatedBlocks(); if (blocks == null || blocks.size() == 0) { out.print("No datanodes contain blocks of file " + filename); dfs.close(); return; } LocatedBlock lastBlk = blocks.get(blocks.size() - 1); String poolId = lastBlk.getBlock().getBlockPoolId(); long blockSize = lastBlk.getBlock().getNumBytes(); long blockId = lastBlk.getBlock().getBlockId(); Token<BlockTokenIdentifier> accessToken = lastBlk.getBlockToken(); long genStamp = lastBlk.getBlock().getGenerationStamp(); DatanodeInfo chosenNode; try { chosenNode = JspHelper.bestNode(lastBlk, conf); } catch (IOException e) { out.print(e.toString()); dfs.close(); return; } InetSocketAddress addr = NetUtils.createSocketAddr(chosenNode.getXferAddr()); // view the last chunkSizeToView bytes while Tailing final long startOffset = blockSize >= chunkSizeToView ? blockSize - chunkSizeToView : 0; out.print("<textarea cols=\"100\" rows=\"25\" wrap=\"virtual\" style=\"width:100%\" READONLY>"); JspHelper.streamBlockInAscii( addr, poolId, blockId, accessToken, genStamp, blockSize, startOffset, chunkSizeToView, out, conf); out.print("</textarea>"); dfs.close(); }
static void generateFileChunks(JspWriter out, HttpServletRequest req, Configuration conf) throws IOException, InterruptedException { long startOffset = 0; int datanodePort = 0; final String namenodeInfoPortStr = req.getParameter("namenodeInfoPort"); final String nnAddr = req.getParameter(JspHelper.NAMENODE_ADDRESS); if (nnAddr == null) { out.print(JspHelper.NAMENODE_ADDRESS + " url param is null"); return; } final String tokenString = req.getParameter(JspHelper.DELEGATION_PARAMETER_NAME); UserGroupInformation ugi = JspHelper.getUGI(req, conf); int namenodeInfoPort = -1; if (namenodeInfoPortStr != null) namenodeInfoPort = Integer.parseInt(namenodeInfoPortStr); final String filename = JspHelper.validatePath(StringEscapeUtils.unescapeHtml(req.getParameter("filename"))); if (filename == null) { out.print("Invalid input (filename absent)"); return; } final Long blockId = JspHelper.validateLong(req.getParameter("blockId")); if (blockId == null) { out.print("Invalid input (blockId absent)"); return; } final DFSClient dfs = getDFSClient(ugi, nnAddr, conf); String bpid = null; Token<BlockTokenIdentifier> blockToken = BlockTokenSecretManager.DUMMY_TOKEN; List<LocatedBlock> blks = dfs.getNamenode().getBlockLocations(filename, 0, Long.MAX_VALUE).getLocatedBlocks(); if (blks == null || blks.size() == 0) { out.print("Can't locate file blocks"); dfs.close(); return; } boolean needBlockToken = conf.getBoolean( DFSConfigKeys.DFS_BLOCK_ACCESS_TOKEN_ENABLE_KEY, DFSConfigKeys.DFS_BLOCK_ACCESS_TOKEN_ENABLE_DEFAULT); for (int i = 0; i < blks.size(); i++) { if (blks.get(i).getBlock().getBlockId() == blockId) { bpid = blks.get(i).getBlock().getBlockPoolId(); if (needBlockToken) { blockToken = blks.get(i).getBlockToken(); } break; } } final Long genStamp = JspHelper.validateLong(req.getParameter("genstamp")); if (genStamp == null) { out.print("Invalid input (genstamp absent)"); return; } long blockSize = 0; final String blockSizeStr = req.getParameter("blockSize"); if (blockSizeStr == null) { out.print("Invalid input (blockSize absent)"); return; } blockSize = Long.parseLong(blockSizeStr); final int chunkSizeToView = JspHelper.string2ChunkSizeToView( req.getParameter("chunkSizeToView"), getDefaultChunkSize(conf)); String startOffsetStr = req.getParameter("startOffset"); if (startOffsetStr == null || Long.parseLong(startOffsetStr) < 0) startOffset = 0; else startOffset = Long.parseLong(startOffsetStr); String datanodePortStr = req.getParameter("datanodePort"); if (datanodePortStr == null) { out.print("Invalid input (datanodePort absent)"); return; } datanodePort = Integer.parseInt(datanodePortStr); out.print("<h3>File: "); JspHelper.printPathWithLinks(filename, out, namenodeInfoPort, tokenString, nnAddr); out.print("</h3><hr>"); String parent = new File(filename).getParent(); JspHelper.printGotoForm(out, namenodeInfoPort, tokenString, parent, nnAddr); out.print("<hr>"); out.print( "<a href=\"http://" + req.getServerName() + ":" + req.getServerPort() + "/browseDirectory.jsp?dir=" + URLEncoder.encode(parent, "UTF-8") + "&namenodeInfoPort=" + namenodeInfoPort + JspHelper.getDelegationTokenUrlParam(tokenString) + JspHelper.getUrlParam(JspHelper.NAMENODE_ADDRESS, nnAddr) + "\"><i>Go back to dir listing</i></a><br>"); out.print("<a href=\"#viewOptions\">Advanced view/download options</a><br>"); out.print("<hr>"); // Determine the prev & next blocks long nextStartOffset = 0; long nextBlockSize = 0; String nextBlockIdStr = null; String nextGenStamp = null; String nextHost = req.getServerName(); int nextPort = req.getServerPort(); int nextDatanodePort = datanodePort; // determine data for the next link if (startOffset + chunkSizeToView >= blockSize) { // we have to go to the next block from this point onwards List<LocatedBlock> blocks = dfs.getNamenode().getBlockLocations(filename, 0, Long.MAX_VALUE).getLocatedBlocks(); for (int i = 0; i < blocks.size(); i++) { if (blocks.get(i).getBlock().getBlockId() == blockId) { if (i != blocks.size() - 1) { LocatedBlock nextBlock = blocks.get(i + 1); nextBlockIdStr = Long.toString(nextBlock.getBlock().getBlockId()); nextGenStamp = Long.toString(nextBlock.getBlock().getGenerationStamp()); nextStartOffset = 0; nextBlockSize = nextBlock.getBlock().getNumBytes(); DatanodeInfo d = JspHelper.bestNode(nextBlock, conf); nextDatanodePort = d.getXferPort(); nextHost = d.getIpAddr(); nextPort = d.getInfoPort(); } } } } else { // we are in the same block nextBlockIdStr = blockId.toString(); nextStartOffset = startOffset + chunkSizeToView; nextBlockSize = blockSize; nextGenStamp = genStamp.toString(); } String nextUrl = null; if (nextBlockIdStr != null) { nextUrl = "http://" + canonicalize(nextHost) + ":" + nextPort + "/browseBlock.jsp?blockId=" + nextBlockIdStr + "&blockSize=" + nextBlockSize + "&startOffset=" + nextStartOffset + "&genstamp=" + nextGenStamp + "&filename=" + URLEncoder.encode(filename, "UTF-8") + "&chunkSizeToView=" + chunkSizeToView + "&datanodePort=" + nextDatanodePort + "&namenodeInfoPort=" + namenodeInfoPort + JspHelper.getDelegationTokenUrlParam(tokenString) + JspHelper.getUrlParam(JspHelper.NAMENODE_ADDRESS, nnAddr); out.print("<a href=\"" + nextUrl + "\">View Next chunk</a> "); } // determine data for the prev link String prevBlockIdStr = null; String prevGenStamp = null; long prevStartOffset = 0; long prevBlockSize = 0; String prevHost = req.getServerName(); int prevPort = req.getServerPort(); int prevDatanodePort = datanodePort; if (startOffset == 0) { List<LocatedBlock> blocks = dfs.getNamenode().getBlockLocations(filename, 0, Long.MAX_VALUE).getLocatedBlocks(); for (int i = 0; i < blocks.size(); i++) { if (blocks.get(i).getBlock().getBlockId() == blockId) { if (i != 0) { LocatedBlock prevBlock = blocks.get(i - 1); prevBlockIdStr = Long.toString(prevBlock.getBlock().getBlockId()); prevGenStamp = Long.toString(prevBlock.getBlock().getGenerationStamp()); prevStartOffset = prevBlock.getBlock().getNumBytes() - chunkSizeToView; if (prevStartOffset < 0) prevStartOffset = 0; prevBlockSize = prevBlock.getBlock().getNumBytes(); DatanodeInfo d = JspHelper.bestNode(prevBlock, conf); prevDatanodePort = d.getXferPort(); prevHost = d.getIpAddr(); prevPort = d.getInfoPort(); } } } } else { // we are in the same block prevBlockIdStr = blockId.toString(); prevStartOffset = startOffset - chunkSizeToView; if (prevStartOffset < 0) prevStartOffset = 0; prevBlockSize = blockSize; prevGenStamp = genStamp.toString(); } String prevUrl = null; if (prevBlockIdStr != null) { prevUrl = "http://" + canonicalize(prevHost) + ":" + prevPort + "/browseBlock.jsp?blockId=" + prevBlockIdStr + "&blockSize=" + prevBlockSize + "&startOffset=" + prevStartOffset + "&filename=" + URLEncoder.encode(filename, "UTF-8") + "&chunkSizeToView=" + chunkSizeToView + "&genstamp=" + prevGenStamp + "&datanodePort=" + prevDatanodePort + "&namenodeInfoPort=" + namenodeInfoPort + JspHelper.getDelegationTokenUrlParam(tokenString) + JspHelper.getUrlParam(JspHelper.NAMENODE_ADDRESS, nnAddr); out.print("<a href=\"" + prevUrl + "\">View Prev chunk</a> "); } out.print("<hr>"); out.print("<textarea cols=\"100\" rows=\"25\" wrap=\"virtual\" style=\"width:100%\" READONLY>"); try { JspHelper.streamBlockInAscii( new InetSocketAddress(req.getServerName(), datanodePort), bpid, blockId, blockToken, genStamp, blockSize, startOffset, chunkSizeToView, out, conf); } catch (Exception e) { out.print(e); } out.print("</textarea>"); dfs.close(); }
static void generateFileDetails(JspWriter out, HttpServletRequest req, Configuration conf) throws IOException, InterruptedException { long startOffset = 0; int datanodePort; final Long blockId = JspHelper.validateLong(req.getParameter("blockId")); if (blockId == null) { out.print("Invalid input (blockId absent)"); return; } String tokenString = req.getParameter(JspHelper.DELEGATION_PARAMETER_NAME); UserGroupInformation ugi = JspHelper.getUGI(req, conf); String datanodePortStr = req.getParameter("datanodePort"); if (datanodePortStr == null) { out.print("Invalid input (datanodePort absent)"); return; } datanodePort = Integer.parseInt(datanodePortStr); final Long genStamp = JspHelper.validateLong(req.getParameter("genstamp")); if (genStamp == null) { out.print("Invalid input (genstamp absent)"); return; } String namenodeInfoPortStr = req.getParameter("namenodeInfoPort"); int namenodeInfoPort = -1; if (namenodeInfoPortStr != null) namenodeInfoPort = Integer.parseInt(namenodeInfoPortStr); final String nnAddr = req.getParameter(JspHelper.NAMENODE_ADDRESS); if (nnAddr == null) { out.print(JspHelper.NAMENODE_ADDRESS + " url param is null"); return; } final int chunkSizeToView = JspHelper.string2ChunkSizeToView( req.getParameter("chunkSizeToView"), getDefaultChunkSize(conf)); String startOffsetStr = req.getParameter("startOffset"); if (startOffsetStr == null || Long.parseLong(startOffsetStr) < 0) startOffset = 0; else startOffset = Long.parseLong(startOffsetStr); String path = StringEscapeUtils.unescapeHtml(req.getParameter("filename")); if (path == null) { path = req.getPathInfo() == null ? "/" : req.getPathInfo(); } final String filename = JspHelper.validatePath(path); if (filename == null) { out.print("Invalid input"); return; } final String blockSizeStr = req.getParameter("blockSize"); if (blockSizeStr == null || blockSizeStr.length() == 0) { out.print("Invalid input"); return; } long blockSize = Long.parseLong(blockSizeStr); final DFSClient dfs = getDFSClient(ugi, nnAddr, conf); List<LocatedBlock> blocks = dfs.getNamenode().getBlockLocations(filename, 0, Long.MAX_VALUE).getLocatedBlocks(); // Add the various links for looking at the file contents // URL for downloading the full file String downloadUrl = "http://" + req.getServerName() + ":" + req.getServerPort() + "/streamFile" + ServletUtil.encodePath(filename) + JspHelper.getUrlParam(JspHelper.NAMENODE_ADDRESS, nnAddr, true) + JspHelper.getDelegationTokenUrlParam(tokenString); out.print("<a name=\"viewOptions\"></a>"); out.print("<a href=\"" + downloadUrl + "\">Download this file</a><br>"); DatanodeInfo chosenNode; // URL for TAIL LocatedBlock lastBlk = blocks.get(blocks.size() - 1); try { chosenNode = JspHelper.bestNode(lastBlk, conf); } catch (IOException e) { out.print(e.toString()); dfs.close(); return; } String fqdn = canonicalize(chosenNode.getIpAddr()); String tailUrl = "http://" + fqdn + ":" + chosenNode.getInfoPort() + "/tail.jsp?filename=" + URLEncoder.encode(filename, "UTF-8") + "&namenodeInfoPort=" + namenodeInfoPort + "&chunkSizeToView=" + chunkSizeToView + JspHelper.getDelegationTokenUrlParam(tokenString) + JspHelper.getUrlParam(JspHelper.NAMENODE_ADDRESS, nnAddr) + "&referrer=" + URLEncoder.encode(req.getRequestURL() + "?" + req.getQueryString(), "UTF-8"); out.print("<a href=\"" + tailUrl + "\">Tail this file</a><br>"); out.print("<form action=\"/browseBlock.jsp\" method=GET>"); out.print("<b>Chunk size to view (in bytes, up to file's DFS block size): </b>"); out.print("<input type=\"hidden\" name=\"blockId\" value=\"" + blockId + "\">"); out.print("<input type=\"hidden\" name=\"blockSize\" value=\"" + blockSize + "\">"); out.print("<input type=\"hidden\" name=\"startOffset\" value=\"" + startOffset + "\">"); out.print("<input type=\"hidden\" name=\"filename\" value=\"" + filename + "\">"); out.print("<input type=\"hidden\" name=\"genstamp\" value=\"" + genStamp + "\">"); out.print("<input type=\"hidden\" name=\"datanodePort\" value=\"" + datanodePort + "\">"); out.print( "<input type=\"hidden\" name=\"namenodeInfoPort\" value=\"" + namenodeInfoPort + "\">"); out.print( "<input type=\"hidden\" name=\"" + JspHelper.NAMENODE_ADDRESS + "\" value=\"" + nnAddr + "\">"); out.print( "<input type=\"text\" name=\"chunkSizeToView\" value=" + chunkSizeToView + " size=10 maxlength=10>"); out.print(" <input type=\"submit\" name=\"submit\" value=\"Refresh\">"); out.print("</form>"); out.print("<hr>"); out.print("<a name=\"blockDetails\"></a>"); out.print("<B>Total number of blocks: " + blocks.size() + "</B><br>"); // generate a table and dump the info out.println("\n<table>"); String nnCanonicalName = canonicalize(nnAddr); for (LocatedBlock cur : blocks) { out.print("<tr>"); final String blockidstring = Long.toString(cur.getBlock().getBlockId()); blockSize = cur.getBlock().getNumBytes(); out.print("<td>" + blockidstring + ":</td>"); DatanodeInfo[] locs = cur.getLocations(); for (int j = 0; j < locs.length; j++) { String datanodeAddr = locs[j].getXferAddr(); datanodePort = locs[j].getXferPort(); fqdn = canonicalize(locs[j].getIpAddr()); String blockUrl = "http://" + fqdn + ":" + locs[j].getInfoPort() + "/browseBlock.jsp?blockId=" + blockidstring + "&blockSize=" + blockSize + "&filename=" + URLEncoder.encode(filename, "UTF-8") + "&datanodePort=" + datanodePort + "&genstamp=" + cur.getBlock().getGenerationStamp() + "&namenodeInfoPort=" + namenodeInfoPort + "&chunkSizeToView=" + chunkSizeToView + JspHelper.getDelegationTokenUrlParam(tokenString) + JspHelper.getUrlParam(JspHelper.NAMENODE_ADDRESS, nnAddr); String blockInfoUrl = "http://" + nnCanonicalName + ":" + namenodeInfoPort + "/block_info_xml.jsp?blockId=" + blockidstring; out.print( "<td> </td><td><a href=\"" + blockUrl + "\">" + datanodeAddr + "</a></td><td>" + "<a href=\"" + blockInfoUrl + "\">View Block Info</a></td>"); } out.println("</tr>"); } out.println("</table>"); out.print("<hr>"); out.print( "<br><a href=\"http://" + nnCanonicalName + ":" + namenodeInfoPort + "/dfshealth.jsp\">Go back to DFS home</a>"); dfs.close(); }
private void lostFoundMove(FileStatus file, LocatedBlocks blocks) throws IOException { final DFSClient dfs = new DFSClient(NameNode.getAddress(conf), conf); try { if (!lfInited) { lostFoundInit(dfs); } if (!lfInitedOk) { return; } String target = lostFound + file.getPath(); String errmsg = "Failed to move " + file.getPath() + " to /lost+found"; try { PermissionStatus ps = new PermissionStatus(file.getOwner(), file.getGroup(), file.getPermission()); if (!nn.namesystem.dir.mkdirs(target, ps, false, FSNamesystem.now())) { LOG.warn(errmsg); return; } // create chains int chain = 0; OutputStream fos = null; for (LocatedBlock lBlk : blocks.getLocatedBlocks()) { LocatedBlock lblock = lBlk; DatanodeInfo[] locs = lblock.getLocations(); if (locs == null || locs.length == 0) { if (fos != null) { fos.flush(); fos.close(); fos = null; } continue; } if (fos == null) { fos = dfs.create(target + "/" + chain, true); if (fos != null) chain++; else { LOG.warn(errmsg + ": could not store chain " + chain); // perhaps we should bail out here... // return; continue; } } // copy the block. It's a pity it's not abstracted from DFSInputStream ... try { copyBlock(dfs, lblock, fos); } catch (Exception e) { e.printStackTrace(); // something went wrong copying this block... LOG.warn(" - could not copy block " + lblock.getBlock() + " to " + target); fos.flush(); fos.close(); fos = null; } } if (fos != null) fos.close(); LOG.warn("\n - moved corrupted file " + file.getPath() + " to /lost+found"); dfs.delete(file.getPath().toString(), true); } catch (Exception e) { e.printStackTrace(); LOG.warn(errmsg + ": " + e.getMessage()); } } finally { dfs.close(); } }
public void generateFileDetails(JspWriter out, HttpServletRequest req, Configuration conf) throws IOException, InterruptedException { int chunkSizeToView = 0; long startOffset = 0; int datanodePort; String blockIdStr = null; long currBlockId = 0; blockIdStr = req.getParameter("blockId"); if (blockIdStr == null) { out.print("Invalid input (blockId absent)"); return; } currBlockId = Long.parseLong(blockIdStr); String datanodePortStr = req.getParameter("datanodePort"); if (datanodePortStr == null) { out.print("Invalid input (datanodePort absent)"); return; } datanodePort = Integer.parseInt(datanodePortStr); String namenodeInfoPortStr = req.getParameter("namenodeInfoPort"); int namenodeInfoPort = -1; if (namenodeInfoPortStr != null) namenodeInfoPort = Integer.parseInt(namenodeInfoPortStr); String chunkSizeToViewStr = req.getParameter("chunkSizeToView"); if (chunkSizeToViewStr != null && Integer.parseInt(chunkSizeToViewStr) > 0) { chunkSizeToView = Integer.parseInt(chunkSizeToViewStr); } else { chunkSizeToView = JspHelper.getDefaultChunkSize(conf); } String startOffsetStr = req.getParameter("startOffset"); if (startOffsetStr == null || Long.parseLong(startOffsetStr) < 0) startOffset = 0; else startOffset = Long.parseLong(startOffsetStr); String filename = HtmlQuoting.unquoteHtmlChars(req.getParameter("filename")); if (filename == null || filename.length() == 0) { out.print("Invalid input"); return; } String blockSizeStr = req.getParameter("blockSize"); long blockSize = 0; if (blockSizeStr == null || blockSizeStr.length() == 0) { out.print("Invalid input"); return; } blockSize = Long.parseLong(blockSizeStr); String tokenString = req.getParameter(JspHelper.DELEGATION_PARAMETER_NAME); UserGroupInformation ugi = JspHelper.getUGI(req, conf); DFSClient dfs = JspHelper.getDFSClient(ugi, jspHelper.nameNodeAddr, conf); List<LocatedBlock> blocks = dfs.namenode.getBlockLocations(filename, 0, Long.MAX_VALUE).getLocatedBlocks(); // Add the various links for looking at the file contents // URL for downloading the full file String downloadUrl = "http://" + req.getServerName() + ":" + +req.getServerPort() + "/streamFile" + URLEncoder.encode(filename, "UTF-8") + "?" + JspHelper.DELEGATION_PARAMETER_NAME + "=" + tokenString; out.print("<a name=\"viewOptions\"></a>"); out.print("<a href=\"" + downloadUrl + "\">Download this file</a><br>"); DatanodeInfo chosenNode; // URL for TAIL LocatedBlock lastBlk = blocks.get(blocks.size() - 1); long blockId = lastBlk.getBlock().getBlockId(); try { chosenNode = jspHelper.bestNode(lastBlk); } catch (IOException e) { out.print(e.toString()); dfs.close(); return; } String fqdn = InetAddress.getByName(chosenNode.getHost()).getCanonicalHostName(); String tailUrl = "http://" + fqdn + ":" + chosenNode.getInfoPort() + "/tail.jsp?filename=" + URLEncoder.encode(filename, "UTF-8") + "&namenodeInfoPort=" + namenodeInfoPort + "&chunkSizeToView=" + chunkSizeToView + "&referrer=" + URLEncoder.encode(req.getRequestURL() + "?" + req.getQueryString(), "UTF-8") + JspHelper.getDelegationTokenUrlParam(tokenString); out.print("<a href=\"" + tailUrl + "\">Tail this file</a><br>"); out.print("<form action=\"/browseBlock.jsp\" method=GET>"); out.print("<b>Chunk size to view (in bytes, up to file's DFS block size): </b>"); out.print("<input type=\"hidden\" name=\"blockId\" value=\"" + currBlockId + "\">"); out.print("<input type=\"hidden\" name=\"blockSize\" value=\"" + blockSize + "\">"); out.print("<input type=\"hidden\" name=\"startOffset\" value=\"" + startOffset + "\">"); out.print("<input type=\"hidden\" name=\"filename\" value=\"" + filename + "\">"); out.print("<input type=\"hidden\" name=\"datanodePort\" value=\"" + datanodePort + "\">"); out.print( "<input type=\"hidden\" name=\"namenodeInfoPort\" value=\"" + namenodeInfoPort + "\">"); out.print( "<input type=\"text\" name=\"chunkSizeToView\" value=" + chunkSizeToView + " size=10 maxlength=10>"); out.print(" <input type=\"submit\" name=\"submit\" value=\"Refresh\">"); out.print("</form>"); out.print("<hr>"); out.print("<a name=\"blockDetails\"></a>"); out.print("<B>Total number of blocks: " + blocks.size() + "</B><br>"); // generate a table and dump the info out.println("\n<table>"); for (LocatedBlock cur : blocks) { out.print("<tr>"); blockId = cur.getBlock().getBlockId(); blockSize = cur.getBlock().getNumBytes(); String blk = "blk_" + Long.toString(blockId); out.print("<td>" + Long.toString(blockId) + ":</td>"); DatanodeInfo[] locs = cur.getLocations(); for (int j = 0; j < locs.length; j++) { String datanodeAddr = locs[j].getName(); datanodePort = Integer.parseInt( datanodeAddr.substring(datanodeAddr.indexOf(':') + 1, datanodeAddr.length())); fqdn = InetAddress.getByName(locs[j].getHost()).getCanonicalHostName(); String blockUrl = "http://" + fqdn + ":" + locs[j].getInfoPort() + "/browseBlock.jsp?blockId=" + Long.toString(blockId) + "&blockSize=" + blockSize + "&filename=" + URLEncoder.encode(filename, "UTF-8") + "&datanodePort=" + datanodePort + "&genstamp=" + cur.getBlock().getGenerationStamp() + "&namenodeInfoPort=" + namenodeInfoPort + "&chunkSizeToView=" + chunkSizeToView; out.print( "<td> </td>" + "<td><a href=\"" + blockUrl + "\">" + datanodeAddr + "</a></td>"); } out.println("</tr>"); } out.println("</table>"); out.print("<hr>"); String namenodeHost = jspHelper.nameNodeAddr.getHostName(); out.print( "<br><a href=\"http://" + InetAddress.getByName(namenodeHost).getCanonicalHostName() + ":" + namenodeInfoPort + "/dfshealth.jsp\">Go back to DFS home</a>"); dfs.close(); }