1 | <%@ page |
---|
2 | contentType="text/html; charset=UTF-8" |
---|
3 | import="javax.servlet.*" |
---|
4 | import="javax.servlet.http.*" |
---|
5 | import="java.io.*" |
---|
6 | import="java.util.*" |
---|
7 | import="java.net.*" |
---|
8 | import="org.apache.hadoop.hdfs.*" |
---|
9 | import="org.apache.hadoop.hdfs.server.namenode.*" |
---|
10 | import="org.apache.hadoop.hdfs.server.datanode.*" |
---|
11 | import="org.apache.hadoop.hdfs.protocol.*" |
---|
12 | import="org.apache.hadoop.io.*" |
---|
13 | import="org.apache.hadoop.conf.*" |
---|
14 | import="org.apache.hadoop.net.DNS" |
---|
15 | import="org.apache.hadoop.util.*" |
---|
16 | import="java.text.DateFormat" |
---|
17 | %> |
---|
18 | |
---|
19 | <%! |
---|
20 | static JspHelper jspHelper = new JspHelper(); |
---|
21 | |
---|
22 | public void generateFileDetails(JspWriter out, HttpServletRequest req) |
---|
23 | throws IOException { |
---|
24 | |
---|
25 | int chunkSizeToView = 0; |
---|
26 | long startOffset = 0; |
---|
27 | int datanodePort; |
---|
28 | |
---|
29 | String blockIdStr = null; |
---|
30 | long currBlockId = 0; |
---|
31 | blockIdStr = req.getParameter("blockId"); |
---|
32 | if (blockIdStr == null) { |
---|
33 | out.print("Invalid input (blockId absent)"); |
---|
34 | return; |
---|
35 | } |
---|
36 | currBlockId = Long.parseLong(blockIdStr); |
---|
37 | |
---|
38 | String datanodePortStr = req.getParameter("datanodePort"); |
---|
39 | if (datanodePortStr == null) { |
---|
40 | out.print("Invalid input (datanodePort absent)"); |
---|
41 | return; |
---|
42 | } |
---|
43 | datanodePort = Integer.parseInt(datanodePortStr); |
---|
44 | |
---|
45 | String namenodeInfoPortStr = req.getParameter("namenodeInfoPort"); |
---|
46 | int namenodeInfoPort = -1; |
---|
47 | if (namenodeInfoPortStr != null) |
---|
48 | namenodeInfoPort = Integer.parseInt(namenodeInfoPortStr); |
---|
49 | |
---|
50 | String chunkSizeToViewStr = req.getParameter("chunkSizeToView"); |
---|
51 | if (chunkSizeToViewStr != null && Integer.parseInt(chunkSizeToViewStr) > 0) |
---|
52 | chunkSizeToView = Integer.parseInt(chunkSizeToViewStr); |
---|
53 | else chunkSizeToView = jspHelper.defaultChunkSizeToView; |
---|
54 | |
---|
55 | String startOffsetStr = req.getParameter("startOffset"); |
---|
56 | if (startOffsetStr == null || Long.parseLong(startOffsetStr) < 0) |
---|
57 | startOffset = 0; |
---|
58 | else startOffset = Long.parseLong(startOffsetStr); |
---|
59 | |
---|
60 | String filename = req.getParameter("filename"); |
---|
61 | if (filename == null || filename.length() == 0) { |
---|
62 | out.print("Invalid input"); |
---|
63 | return; |
---|
64 | } |
---|
65 | |
---|
66 | String blockSizeStr = req.getParameter("blockSize"); |
---|
67 | long blockSize = 0; |
---|
68 | if (blockSizeStr == null || blockSizeStr.length() == 0) { |
---|
69 | out.print("Invalid input"); |
---|
70 | return; |
---|
71 | } |
---|
72 | blockSize = Long.parseLong(blockSizeStr); |
---|
73 | |
---|
74 | DFSClient dfs = new DFSClient(jspHelper.nameNodeAddr, jspHelper.conf); |
---|
75 | List<LocatedBlock> blocks = |
---|
76 | dfs.namenode.getBlockLocations(filename, 0, Long.MAX_VALUE).getLocatedBlocks(); |
---|
77 | //Add the various links for looking at the file contents |
---|
78 | //URL for downloading the full file |
---|
79 | String downloadUrl = "http://" + req.getServerName() + ":" + |
---|
80 | + req.getServerPort() + "/streamFile?" + "filename=" + |
---|
81 | URLEncoder.encode(filename, "UTF-8"); |
---|
82 | out.print("<a name=\"viewOptions\"></a>"); |
---|
83 | out.print("<a href=\"" + downloadUrl + "\">Download this file</a><br>"); |
---|
84 | |
---|
85 | DatanodeInfo chosenNode; |
---|
86 | //URL for TAIL |
---|
87 | LocatedBlock lastBlk = blocks.get(blocks.size() - 1); |
---|
88 | long blockId = lastBlk.getBlock().getBlockId(); |
---|
89 | try { |
---|
90 | chosenNode = jspHelper.bestNode(lastBlk); |
---|
91 | } catch (IOException e) { |
---|
92 | out.print(e.toString()); |
---|
93 | dfs.close(); |
---|
94 | return; |
---|
95 | } |
---|
96 | String fqdn = |
---|
97 | InetAddress.getByName(chosenNode.getHost()).getCanonicalHostName(); |
---|
98 | String tailUrl = "http://" + fqdn + ":" + |
---|
99 | chosenNode.getInfoPort() + |
---|
100 | "/tail.jsp?filename=" + URLEncoder.encode(filename, "UTF-8") + |
---|
101 | "&namenodeInfoPort=" + namenodeInfoPort + |
---|
102 | "&chunkSizeToView=" + chunkSizeToView + |
---|
103 | "&referrer=" + |
---|
104 | URLEncoder.encode(req.getRequestURL() + "?" + req.getQueryString(), |
---|
105 | "UTF-8"); |
---|
106 | out.print("<a href=\"" + tailUrl + "\">Tail this file</a><br>"); |
---|
107 | |
---|
108 | out.print("<form action=\"/browseBlock.jsp\" method=GET>"); |
---|
109 | out.print("<b>Chunk size to view (in bytes, up to file's DFS block size): </b>"); |
---|
110 | out.print("<input type=\"hidden\" name=\"blockId\" value=\"" + currBlockId + |
---|
111 | "\">"); |
---|
112 | out.print("<input type=\"hidden\" name=\"blockSize\" value=\"" + |
---|
113 | blockSize + "\">"); |
---|
114 | out.print("<input type=\"hidden\" name=\"startOffset\" value=\"" + |
---|
115 | startOffset + "\">"); |
---|
116 | out.print("<input type=\"hidden\" name=\"filename\" value=\"" + filename + |
---|
117 | "\">"); |
---|
118 | out.print("<input type=\"hidden\" name=\"datanodePort\" value=\"" + |
---|
119 | datanodePort+ "\">"); |
---|
120 | out.print("<input type=\"hidden\" name=\"namenodeInfoPort\" value=\"" + |
---|
121 | namenodeInfoPort + "\">"); |
---|
122 | out.print("<input type=\"text\" name=\"chunkSizeToView\" value=" + |
---|
123 | chunkSizeToView + " size=10 maxlength=10>"); |
---|
124 | out.print(" <input type=\"submit\" name=\"submit\" value=\"Refresh\">"); |
---|
125 | out.print("</form>"); |
---|
126 | out.print("<hr>"); |
---|
127 | out.print("<a name=\"blockDetails\"></a>"); |
---|
128 | out.print("<B>Total number of blocks: "+blocks.size()+"</B><br>"); |
---|
129 | //generate a table and dump the info |
---|
130 | out.println("\n<table>"); |
---|
131 | for (LocatedBlock cur : blocks) { |
---|
132 | out.print("<tr>"); |
---|
133 | blockId = cur.getBlock().getBlockId(); |
---|
134 | blockSize = cur.getBlock().getNumBytes(); |
---|
135 | String blk = "blk_" + Long.toString(blockId); |
---|
136 | out.print("<td>"+Long.toString(blockId)+":</td>"); |
---|
137 | DatanodeInfo[] locs = cur.getLocations(); |
---|
138 | for(int j=0; j<locs.length; j++) { |
---|
139 | String datanodeAddr = locs[j].getName(); |
---|
140 | datanodePort = Integer.parseInt(datanodeAddr.substring( |
---|
141 | datanodeAddr.indexOf(':') + 1, |
---|
142 | datanodeAddr.length())); |
---|
143 | fqdn = InetAddress.getByName(locs[j].getHost()).getCanonicalHostName(); |
---|
144 | String blockUrl = "http://"+ fqdn + ":" + |
---|
145 | locs[j].getInfoPort() + |
---|
146 | "/browseBlock.jsp?blockId=" + Long.toString(blockId) + |
---|
147 | "&blockSize=" + blockSize + |
---|
148 | "&filename=" + URLEncoder.encode(filename, "UTF-8")+ |
---|
149 | "&datanodePort=" + datanodePort + |
---|
150 | "&genstamp=" + cur.getBlock().getGenerationStamp() + |
---|
151 | "&namenodeInfoPort=" + namenodeInfoPort + |
---|
152 | "&chunkSizeToView=" + chunkSizeToView; |
---|
153 | out.print("<td> </td>" |
---|
154 | + "<td><a href=\"" + blockUrl + "\">" + datanodeAddr + "</a></td>"); |
---|
155 | } |
---|
156 | out.println("</tr>"); |
---|
157 | } |
---|
158 | out.println("</table>"); |
---|
159 | out.print("<hr>"); |
---|
160 | String namenodeHost = jspHelper.nameNodeAddr.getHostName(); |
---|
161 | out.print("<br><a href=\"http://" + |
---|
162 | InetAddress.getByName(namenodeHost).getCanonicalHostName() + ":" + |
---|
163 | namenodeInfoPort + "/dfshealth.jsp\">Go back to DFS home</a>"); |
---|
164 | dfs.close(); |
---|
165 | } |
---|
166 | |
---|
167 | public void generateFileChunks(JspWriter out, HttpServletRequest req) |
---|
168 | throws IOException { |
---|
169 | long startOffset = 0; |
---|
170 | int datanodePort = 0; |
---|
171 | int chunkSizeToView = 0; |
---|
172 | |
---|
173 | String namenodeInfoPortStr = req.getParameter("namenodeInfoPort"); |
---|
174 | int namenodeInfoPort = -1; |
---|
175 | if (namenodeInfoPortStr != null) |
---|
176 | namenodeInfoPort = Integer.parseInt(namenodeInfoPortStr); |
---|
177 | |
---|
178 | String filename = req.getParameter("filename"); |
---|
179 | if (filename == null) { |
---|
180 | out.print("Invalid input (filename absent)"); |
---|
181 | return; |
---|
182 | } |
---|
183 | |
---|
184 | String blockIdStr = null; |
---|
185 | long blockId = 0; |
---|
186 | blockIdStr = req.getParameter("blockId"); |
---|
187 | if (blockIdStr == null) { |
---|
188 | out.print("Invalid input (blockId absent)"); |
---|
189 | return; |
---|
190 | } |
---|
191 | blockId = Long.parseLong(blockIdStr); |
---|
192 | |
---|
193 | String blockGenStamp = null; |
---|
194 | long genStamp = 0; |
---|
195 | blockGenStamp = req.getParameter("genstamp"); |
---|
196 | if (blockGenStamp == null) { |
---|
197 | out.print("Invalid input (genstamp absent)"); |
---|
198 | return; |
---|
199 | } |
---|
200 | genStamp = Long.parseLong(blockGenStamp); |
---|
201 | |
---|
202 | String blockSizeStr; |
---|
203 | long blockSize = 0; |
---|
204 | blockSizeStr = req.getParameter("blockSize"); |
---|
205 | if (blockSizeStr == null) { |
---|
206 | out.print("Invalid input (blockSize absent)"); |
---|
207 | return; |
---|
208 | } |
---|
209 | blockSize = Long.parseLong(blockSizeStr); |
---|
210 | |
---|
211 | String chunkSizeToViewStr = req.getParameter("chunkSizeToView"); |
---|
212 | if (chunkSizeToViewStr != null && Integer.parseInt(chunkSizeToViewStr) > 0) |
---|
213 | chunkSizeToView = Integer.parseInt(chunkSizeToViewStr); |
---|
214 | else chunkSizeToView = jspHelper.defaultChunkSizeToView; |
---|
215 | |
---|
216 | String startOffsetStr = req.getParameter("startOffset"); |
---|
217 | if (startOffsetStr == null || Long.parseLong(startOffsetStr) < 0) |
---|
218 | startOffset = 0; |
---|
219 | else startOffset = Long.parseLong(startOffsetStr); |
---|
220 | |
---|
221 | String datanodePortStr = req.getParameter("datanodePort"); |
---|
222 | if (datanodePortStr == null) { |
---|
223 | out.print("Invalid input (datanodePort absent)"); |
---|
224 | return; |
---|
225 | } |
---|
226 | datanodePort = Integer.parseInt(datanodePortStr); |
---|
227 | out.print("<h3>File: "); |
---|
228 | JspHelper.printPathWithLinks(filename, out, namenodeInfoPort); |
---|
229 | out.print("</h3><hr>"); |
---|
230 | String parent = new File(filename).getParent(); |
---|
231 | JspHelper.printGotoForm(out, namenodeInfoPort, parent); |
---|
232 | out.print("<hr>"); |
---|
233 | out.print("<a href=\"http://" + req.getServerName() + ":" + |
---|
234 | req.getServerPort() + |
---|
235 | "/browseDirectory.jsp?dir=" + |
---|
236 | URLEncoder.encode(parent, "UTF-8") + |
---|
237 | "&namenodeInfoPort=" + namenodeInfoPort + |
---|
238 | "\"><i>Go back to dir listing</i></a><br>"); |
---|
239 | out.print("<a href=\"#viewOptions\">Advanced view/download options</a><br>"); |
---|
240 | out.print("<hr>"); |
---|
241 | |
---|
242 | //Determine the prev & next blocks |
---|
243 | DFSClient dfs = new DFSClient(jspHelper.nameNodeAddr, jspHelper.conf); |
---|
244 | long nextStartOffset = 0; |
---|
245 | long nextBlockSize = 0; |
---|
246 | String nextBlockIdStr = null; |
---|
247 | String nextGenStamp = null; |
---|
248 | String nextHost = req.getServerName(); |
---|
249 | int nextPort = req.getServerPort(); |
---|
250 | int nextDatanodePort = datanodePort; |
---|
251 | //determine data for the next link |
---|
252 | if (startOffset + chunkSizeToView >= blockSize) { |
---|
253 | //we have to go to the next block from this point onwards |
---|
254 | List<LocatedBlock> blocks = |
---|
255 | dfs.namenode.getBlockLocations(filename, 0, Long.MAX_VALUE).getLocatedBlocks(); |
---|
256 | for (int i = 0; i < blocks.size(); i++) { |
---|
257 | if (blocks.get(i).getBlock().getBlockId() == blockId) { |
---|
258 | if (i != blocks.size() - 1) { |
---|
259 | LocatedBlock nextBlock = blocks.get(i+1); |
---|
260 | nextBlockIdStr = Long.toString(nextBlock.getBlock().getBlockId()); |
---|
261 | nextGenStamp = Long.toString(nextBlock.getBlock().getGenerationStamp()); |
---|
262 | nextStartOffset = 0; |
---|
263 | nextBlockSize = nextBlock.getBlock().getNumBytes(); |
---|
264 | DatanodeInfo d = jspHelper.bestNode(nextBlock); |
---|
265 | String datanodeAddr = d.getName(); |
---|
266 | nextDatanodePort = Integer.parseInt( |
---|
267 | datanodeAddr.substring( |
---|
268 | datanodeAddr.indexOf(':') + 1, |
---|
269 | datanodeAddr.length())); |
---|
270 | nextHost = InetAddress.getByName(d.getHost()).getCanonicalHostName(); |
---|
271 | nextPort = d.getInfoPort(); |
---|
272 | } |
---|
273 | } |
---|
274 | } |
---|
275 | } |
---|
276 | else { |
---|
277 | //we are in the same block |
---|
278 | nextBlockIdStr = blockIdStr; |
---|
279 | nextStartOffset = startOffset + chunkSizeToView; |
---|
280 | nextBlockSize = blockSize; |
---|
281 | nextGenStamp = blockGenStamp; |
---|
282 | } |
---|
283 | String nextUrl = null; |
---|
284 | if (nextBlockIdStr != null) { |
---|
285 | nextUrl = "http://" + nextHost + ":" + |
---|
286 | nextPort + |
---|
287 | "/browseBlock.jsp?blockId=" + nextBlockIdStr + |
---|
288 | "&blockSize=" + nextBlockSize + "&startOffset=" + |
---|
289 | nextStartOffset + |
---|
290 | "&genstamp=" + nextGenStamp + |
---|
291 | "&filename=" + URLEncoder.encode(filename, "UTF-8") + |
---|
292 | "&chunkSizeToView=" + chunkSizeToView + |
---|
293 | "&datanodePort=" + nextDatanodePort + |
---|
294 | "&namenodeInfoPort=" + namenodeInfoPort; |
---|
295 | out.print("<a href=\"" + nextUrl + "\">View Next chunk</a> "); |
---|
296 | } |
---|
297 | //determine data for the prev link |
---|
298 | String prevBlockIdStr = null; |
---|
299 | String prevGenStamp = null; |
---|
300 | long prevStartOffset = 0; |
---|
301 | long prevBlockSize = 0; |
---|
302 | String prevHost = req.getServerName(); |
---|
303 | int prevPort = req.getServerPort(); |
---|
304 | int prevDatanodePort = datanodePort; |
---|
305 | if (startOffset == 0) { |
---|
306 | List<LocatedBlock> blocks = |
---|
307 | dfs.namenode.getBlockLocations(filename, 0, Long.MAX_VALUE).getLocatedBlocks(); |
---|
308 | for (int i = 0; i < blocks.size(); i++) { |
---|
309 | if (blocks.get(i).getBlock().getBlockId() == blockId) { |
---|
310 | if (i != 0) { |
---|
311 | LocatedBlock prevBlock = blocks.get(i-1); |
---|
312 | prevBlockIdStr = Long.toString(prevBlock.getBlock().getBlockId()); |
---|
313 | prevGenStamp = Long.toString(prevBlock.getBlock().getGenerationStamp()); |
---|
314 | prevStartOffset = prevBlock.getBlock().getNumBytes() - chunkSizeToView; |
---|
315 | if (prevStartOffset < 0) |
---|
316 | prevStartOffset = 0; |
---|
317 | prevBlockSize = prevBlock.getBlock().getNumBytes(); |
---|
318 | DatanodeInfo d = jspHelper.bestNode(prevBlock); |
---|
319 | String datanodeAddr = d.getName(); |
---|
320 | prevDatanodePort = Integer.parseInt( |
---|
321 | datanodeAddr.substring( |
---|
322 | datanodeAddr.indexOf(':') + 1, |
---|
323 | datanodeAddr.length())); |
---|
324 | prevHost = InetAddress.getByName(d.getHost()).getCanonicalHostName(); |
---|
325 | prevPort = d.getInfoPort(); |
---|
326 | } |
---|
327 | } |
---|
328 | } |
---|
329 | } |
---|
330 | else { |
---|
331 | //we are in the same block |
---|
332 | prevBlockIdStr = blockIdStr; |
---|
333 | prevStartOffset = startOffset - chunkSizeToView; |
---|
334 | if (prevStartOffset < 0) prevStartOffset = 0; |
---|
335 | prevBlockSize = blockSize; |
---|
336 | prevGenStamp = blockGenStamp; |
---|
337 | } |
---|
338 | |
---|
339 | String prevUrl = null; |
---|
340 | if (prevBlockIdStr != null) { |
---|
341 | prevUrl = "http://" + prevHost + ":" + |
---|
342 | prevPort + |
---|
343 | "/browseBlock.jsp?blockId=" + prevBlockIdStr + |
---|
344 | "&blockSize=" + prevBlockSize + "&startOffset=" + |
---|
345 | prevStartOffset + |
---|
346 | "&filename=" + URLEncoder.encode(filename, "UTF-8") + |
---|
347 | "&chunkSizeToView=" + chunkSizeToView + |
---|
348 | "&genstamp=" + prevGenStamp + |
---|
349 | "&datanodePort=" + prevDatanodePort + |
---|
350 | "&namenodeInfoPort=" + namenodeInfoPort; |
---|
351 | out.print("<a href=\"" + prevUrl + "\">View Prev chunk</a> "); |
---|
352 | } |
---|
353 | out.print("<hr>"); |
---|
354 | out.print("<textarea cols=\"100\" rows=\"25\" wrap=\"virtual\" style=\"width:100%\" READONLY>"); |
---|
355 | try { |
---|
356 | jspHelper.streamBlockInAscii( |
---|
357 | new InetSocketAddress(req.getServerName(), datanodePort), blockId, |
---|
358 | genStamp, blockSize, startOffset, chunkSizeToView, out); |
---|
359 | } catch (Exception e){ |
---|
360 | out.print(e); |
---|
361 | } |
---|
362 | out.print("</textarea>"); |
---|
363 | dfs.close(); |
---|
364 | } |
---|
365 | |
---|
366 | %> |
---|
367 | <html> |
---|
368 | <head> |
---|
369 | <%JspHelper.createTitle(out, request, request.getParameter("filename")); %> |
---|
370 | </head> |
---|
371 | <body onload="document.goto.dir.focus()"> |
---|
372 | <% |
---|
373 | generateFileChunks(out,request); |
---|
374 | %> |
---|
375 | <hr> |
---|
376 | <% |
---|
377 | generateFileDetails(out,request); |
---|
378 | %> |
---|
379 | |
---|
380 | <h2>Local logs</h2> |
---|
381 | <a href="/logs/">Log</a> directory |
---|
382 | |
---|
383 | <% |
---|
384 | out.println(ServletUtil.htmlFooter()); |
---|
385 | %> |
---|