private void testDataNodeRedirect(Path path) throws IOException {
    // Create the file
    if (hdfs.exists(path)) {
      hdfs.delete(path, true);
    }
    FSDataOutputStream out = hdfs.create(path, (short) 1);
    out.writeBytes("0123456789");
    out.close();

    // Get the path's block location so we can determine
    // if we were redirected to the right DN.
    FileStatus status = hdfs.getFileStatus(path);
    BlockLocation[] locations = hdfs.getFileBlockLocations(status, 0, 10);
    String locationName = locations[0].getNames()[0];

    // Connect to the NN to get redirected
    URL u =
        hftpFs.getNamenodeURL(
            "/data" + ServletUtil.encodePath(path.toUri().getPath()), "ugi=userx,groupy");
    HttpURLConnection conn = (HttpURLConnection) u.openConnection();
    HttpURLConnection.setFollowRedirects(true);
    conn.connect();
    conn.getInputStream();

    boolean checked = false;
    // Find the datanode that has the block according to locations
    // and check that the URL was redirected to this DN's info port
    for (DataNode node : cluster.getDataNodes()) {
      DatanodeRegistration dnR = node.dnRegistration;
      if (dnR.getName().equals(locationName)) {
        checked = true;
        assertEquals(dnR.getInfoPort(), conn.getURL().getPort());
      }
    }
    assertTrue(
        "The test never checked that location of " + "the block and hftp desitnation are the same",
        checked);
  }
  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("&nbsp;&nbsp;<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>&nbsp</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();
  }