PageRenderTime 37ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/src/java/org/hypertable/DfsBroker/hadoop/HdfsBroker.java

http://hypertable.googlecode.com/
Java | 546 lines | 350 code | 130 blank | 66 comment | 75 complexity | ceb220ea45223eb3855f507194539fb5 MD5 | raw file
Possible License(s): GPL-2.0, Apache-2.0, CPL-1.0
  1. /**
  2. * Copyright (C) 2007 Doug Judd (Zvents, Inc.)
  3. *
  4. * This file is part of Hypertable.
  5. *
  6. * Hypertable is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or any later version.
  10. *
  11. * Hypertable is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.hypertable.DfsBroker.hadoop;
  21. import java.io.EOFException;
  22. import java.io.FileNotFoundException;
  23. import java.io.IOException;
  24. import java.net.InetSocketAddress;
  25. import java.nio.BufferUnderflowException;
  26. import java.util.Properties;
  27. import java.util.concurrent.atomic.AtomicInteger;
  28. import java.util.logging.Level;
  29. import java.util.logging.Logger;
  30. import org.apache.hadoop.conf.Configuration;
  31. import org.apache.hadoop.fs.FileSystem;
  32. import org.apache.hadoop.fs.Path;
  33. import org.hypertable.AsyncComm.Comm;
  34. import org.hypertable.AsyncComm.ResponseCallback;
  35. import org.hypertable.Common.Error;
  36. /**
  37. * This is the actual HdfsBroker object that contains all of the application
  38. * logic. It has a method for each of the request types (e.g. Open, Close,
  39. * Read, Write, etc.) There is only one of these objects for each server
  40. * instance which carries out all of the requests from all connections.
  41. */
  42. public class HdfsBroker {
  43. static final Logger log = Logger.getLogger("org.hypertable.DfsBroker.hadoop");
  44. protected static AtomicInteger msUniqueId = new AtomicInteger(0);
  45. public HdfsBroker(Comm comm, Properties props) throws IOException {
  46. String str;
  47. if (props.getProperty("verbose").equalsIgnoreCase("true"))
  48. mVerbose = true;
  49. str = props.getProperty("HdfsBroker.fs.default.name");
  50. if (str == null) {
  51. java.lang.System.err.println("error: 'HdfsBroker.fs.default.name' property not specified.");
  52. java.lang.System.exit(1);
  53. }
  54. if (mVerbose) {
  55. java.lang.System.out.println("HdfsBroker.Server.fs.default.name=" + str);
  56. }
  57. mConf.set("fs.default.name", str);
  58. mConf.set("dfs.client.buffer.dir", "/tmp");
  59. mConf.setInt("dfs.client.block.write.retries", 3);
  60. mFilesystem = FileSystem.get(mConf);
  61. }
  62. /**
  63. *
  64. */
  65. public OpenFileMap GetOpenFileMap() {
  66. return mOpenFileMap;
  67. }
  68. /**
  69. *
  70. */
  71. public void Open(ResponseCallbackOpen cb, String fileName, int bufferSize) {
  72. int fd;
  73. OpenFileData ofd;
  74. int error = Error.OK;
  75. try {
  76. if (fileName.endsWith("/")) {
  77. log.severe("Unable to open file, bad filename: " + fileName);
  78. error = cb.error(Error.DFSBROKER_BAD_FILENAME, fileName);
  79. return;
  80. }
  81. fd = msUniqueId.incrementAndGet();
  82. if (mVerbose)
  83. log.info("Opening file '" + fileName + "' bs=" + bufferSize + " handle = " + fd);
  84. ofd = mOpenFileMap.Create(fd, cb.GetAddress());
  85. ofd.is = mFilesystem.open(new Path(fileName));
  86. // todo: do something with bufferSize
  87. error = cb.response(fd);
  88. }
  89. catch (FileNotFoundException e) {
  90. log.info("File not found: " + fileName);
  91. error = cb.error(Error.DFSBROKER_FILE_NOT_FOUND, e.getMessage());
  92. }
  93. catch (IOException e) {
  94. log.info("I/O exception while opening file '" + fileName + "' - " + e.getMessage());
  95. error = cb.error(Error.DFSBROKER_IO_ERROR, e.getMessage());
  96. }
  97. if (error != Error.OK)
  98. log.severe("Problem sending response to 'open' command - " + Error.GetText(error));
  99. }
  100. /**
  101. *
  102. */
  103. public void Close(ResponseCallback cb, int fd) {
  104. OpenFileData ofd;
  105. int error = Error.OK;
  106. try {
  107. ofd = mOpenFileMap.Remove(fd);
  108. if (mVerbose)
  109. log.info("Closing handle " + fd);
  110. if (ofd == null) {
  111. error = Error.DFSBROKER_BAD_FILE_HANDLE;
  112. throw new IOException("Invalid file handle " + fd);
  113. }
  114. if (ofd.is != null)
  115. ofd.is.close();
  116. if (ofd.os != null)
  117. ofd.os.close();
  118. error = cb.response_ok();
  119. }
  120. catch (IOException e) {
  121. log.info("I/O exception - " + e.getMessage());
  122. error = cb.error(error, e.getMessage());
  123. }
  124. if (error != Error.OK)
  125. log.severe("Error sending CLOSE response back");
  126. }
  127. public void Create(ResponseCallbackCreate cb, String fileName, boolean overwrite,
  128. int bufferSize, short replication, long blockSize) {
  129. int fd;
  130. OpenFileData ofd;
  131. int error = Error.OK;
  132. try {
  133. if (fileName.endsWith("/")) {
  134. log.severe("Unable to open file, bad filename: " + fileName);
  135. error = cb.error(Error.DFSBROKER_BAD_FILENAME, fileName);
  136. return;
  137. }
  138. fd = msUniqueId.incrementAndGet();
  139. ofd = mOpenFileMap.Create(fd, cb.GetAddress());
  140. if (mVerbose)
  141. log.info("Creating file '" + fileName + "' handle = " + fd);
  142. if (replication == -1)
  143. replication = mFilesystem.getDefaultReplication();
  144. if (bufferSize == -1)
  145. bufferSize = mConf.getInt("io.file.buffer.size", 4096);
  146. if (blockSize == -1)
  147. blockSize = mFilesystem.getDefaultBlockSize();
  148. ofd.os = mFilesystem.create(new Path(fileName), overwrite, bufferSize, replication, blockSize);
  149. error = cb.response(fd);
  150. }
  151. catch (FileNotFoundException e) {
  152. log.info("File not found: " + fileName);
  153. error = cb.error(Error.DFSBROKER_FILE_NOT_FOUND, e.getMessage());
  154. }
  155. catch (IOException e) {
  156. log.info("I/O exception while creating file '" + fileName + "' - " + e.getMessage());
  157. error = cb.error(Error.DFSBROKER_IO_ERROR, e.getMessage());
  158. }
  159. if (error != Error.OK)
  160. log.severe("Problem sending response to 'create' command - " + Error.GetText(error));
  161. }
  162. /**
  163. *
  164. */
  165. public void Length(ResponseCallbackLength cb, String fileName) {
  166. int error = Error.OK;
  167. long length;
  168. try {
  169. if (mVerbose)
  170. log.info("Getting length of file '" + fileName);
  171. length = mFilesystem.getLength(new Path(fileName));
  172. error = cb.response(length);
  173. }
  174. catch (FileNotFoundException e) {
  175. log.info("File not found: " + fileName);
  176. error = cb.error(Error.DFSBROKER_FILE_NOT_FOUND, e.getMessage());
  177. }
  178. catch (IOException e) {
  179. log.info("I/O exception while getting length of file '" + fileName + "' - " + e.getMessage());
  180. error = cb.error(Error.DFSBROKER_IO_ERROR, e.getMessage());
  181. }
  182. if (error != Error.OK)
  183. log.severe("Problem sending response to 'length' command - " + Error.GetText(error));
  184. }
  185. /**
  186. *
  187. */
  188. public void Mkdirs(ResponseCallback cb, String fileName) {
  189. int error = Error.OK;
  190. try {
  191. if (mVerbose)
  192. log.info("Making directory '" + fileName + "'");
  193. if (!mFilesystem.mkdirs(new Path(fileName)))
  194. throw new IOException("Problem creating directory '" + fileName + "'");
  195. error = cb.response_ok();
  196. }
  197. catch (FileNotFoundException e) {
  198. log.info("File not found: " + fileName);
  199. error = cb.error(Error.DFSBROKER_FILE_NOT_FOUND, e.getMessage());
  200. }
  201. catch (IOException e) {
  202. log.info("I/O exception while making directory '" + fileName + "' - " + e.getMessage());
  203. error = cb.error(Error.DFSBROKER_IO_ERROR, e.getMessage());
  204. }
  205. if (error != Error.OK)
  206. log.severe("Problem sending response to 'mkdirs' command - " + Error.GetText(error));
  207. }
  208. public void Read(ResponseCallbackRead cb, int fd, int amount) {
  209. int error = Error.OK;
  210. OpenFileData ofd;
  211. try {
  212. if ((ofd = mOpenFileMap.Get(fd)) == null) {
  213. error = Error.DFSBROKER_BAD_FILE_HANDLE;
  214. throw new IOException("Invalid file handle " + fd);
  215. }
  216. /**
  217. if (mVerbose)
  218. log.info("Reading " + amount + " bytes from fd=" + fd);
  219. */
  220. if (ofd.is == null)
  221. throw new IOException("File handle " + fd + " not open for reading");
  222. long offset = ofd.is.getPos();
  223. byte [] data = new byte [ amount ];
  224. int nread = 0;
  225. try {
  226. ofd.is.readFully(data, 0, data.length);
  227. nread = data.length;
  228. }
  229. catch (EOFException e) {
  230. nread = ofd.is.read(data, 0, data.length);
  231. }
  232. error = cb.response(offset, nread, data);
  233. }
  234. catch (IOException e) {
  235. log.info("I/O exception - " + e.getMessage());
  236. error = cb.error(error, e.getMessage());
  237. }
  238. if (error != Error.OK)
  239. log.severe("Error sending CLOSE response back");
  240. }
  241. public void Write(ResponseCallbackWrite cb, int fd, int amount, byte [] data) {
  242. int error = Error.OK;
  243. OpenFileData ofd;
  244. try {
  245. /**
  246. if (Global.verbose)
  247. log.info("Write request handle=" + fd + " amount=" + mAmount);
  248. */
  249. if ((ofd = mOpenFileMap.Get(fd)) == null) {
  250. error = Error.DFSBROKER_BAD_FILE_HANDLE;
  251. throw new IOException("Invalid file handle " + fd);
  252. }
  253. if (ofd.os == null)
  254. throw new IOException("File handle " + ofd + " not open for writing");
  255. long offset = ofd.os.getPos();
  256. ofd.os.write(data, 0, amount);
  257. error = cb.response(offset, amount);
  258. }
  259. catch (IOException e) {
  260. e.printStackTrace();
  261. error = cb.error(error, e.getMessage());
  262. }
  263. catch (BufferUnderflowException e) {
  264. e.printStackTrace();
  265. error = cb.error(Error.PROTOCOL_ERROR, e.getMessage());
  266. }
  267. if (error != Error.OK)
  268. log.severe("Error sending WRITE response back");
  269. }
  270. public void PositionRead(ResponseCallbackPositionRead cb, int fd, long offset, int amount) {
  271. int error = Error.OK;
  272. OpenFileData ofd;
  273. try {
  274. if ((ofd = mOpenFileMap.Get(fd)) == null) {
  275. error = Error.DFSBROKER_BAD_FILE_HANDLE;
  276. throw new IOException("Invalid file handle " + fd);
  277. }
  278. /**
  279. if (mVerbose)
  280. log.info("Reading " + amount + " bytes from fd=" + fd);
  281. */
  282. if (ofd.is == null)
  283. throw new IOException("File handle " + fd + " not open for reading");
  284. byte [] data = new byte [ amount ];
  285. ofd.is.seek(offset);
  286. int nread = 0;
  287. try {
  288. ofd.is.readFully(data, 0, data.length);
  289. nread = data.length;
  290. }
  291. catch (EOFException e) {
  292. nread = ofd.is.read(data, 0, data.length);
  293. }
  294. error = cb.response(offset, nread, data);
  295. }
  296. catch (IOException e) {
  297. log.info("I/O exception - " + e.getMessage());
  298. error = cb.error(error, e.getMessage());
  299. }
  300. if (error != Error.OK)
  301. log.severe("Error sending PREAD response back");
  302. }
  303. /**
  304. *
  305. */
  306. public void Remove(ResponseCallback cb, String fileName) {
  307. int error = Error.OK;
  308. try {
  309. if (mVerbose)
  310. log.info("Removing file '" + fileName);
  311. if (!mFilesystem.delete(new Path(fileName)))
  312. throw new IOException("Problem deleting file '" + fileName + "'");
  313. error = cb.response_ok();
  314. }
  315. catch (FileNotFoundException e) {
  316. log.info("File not found: " + fileName);
  317. error = cb.error(Error.DFSBROKER_FILE_NOT_FOUND, e.getMessage());
  318. }
  319. catch (IOException e) {
  320. log.info("I/O exception while removing file '" + fileName + "' - " + e.getMessage());
  321. error = cb.error(Error.DFSBROKER_IO_ERROR, e.getMessage());
  322. }
  323. if (error != Error.OK)
  324. log.severe("Problem sending response to 'remove' command - " + Error.GetText(error));
  325. }
  326. public void Seek(ResponseCallback cb, int fd, long offset) {
  327. int error = Error.OK;
  328. OpenFileData ofd;
  329. try {
  330. if ((ofd = mOpenFileMap.Get(fd)) == null) {
  331. error = Error.DFSBROKER_BAD_FILE_HANDLE;
  332. throw new IOException("Invalid file handle " + fd);
  333. }
  334. if (mVerbose)
  335. log.info("Seek request handle=" + fd + " offset=" + offset);
  336. if (ofd.is == null)
  337. throw new IOException("File handle " + fd + " not open for reading");
  338. ofd.is.seek(offset);
  339. error = cb.response_ok();
  340. }
  341. catch (IOException e) {
  342. log.info("I/O exception - " + e.getMessage());
  343. error = cb.error(error, e.getMessage());
  344. }
  345. if (error != Error.OK)
  346. log.severe("Error sending SEEK response back");
  347. }
  348. /**
  349. *
  350. */
  351. public void Flush(ResponseCallback cb) {
  352. // todo: implement me!!
  353. log.info("Flush not implemented!");
  354. if (cb.response_ok() != Error.OK)
  355. log.severe("Error sending SEEK response back");
  356. }
  357. /**
  358. *
  359. */
  360. public void Rmdir(ResponseCallback cb, String fileName) {
  361. int error = Error.OK;
  362. try {
  363. if (mVerbose)
  364. log.info("Removing directory '" + fileName + "'");
  365. if (!mFilesystem.delete(new Path(fileName)))
  366. throw new IOException("Problem deleting directory '" + fileName + "'");
  367. error = cb.response_ok();
  368. }
  369. catch (FileNotFoundException e) {
  370. log.info("File not found: " + fileName);
  371. error = cb.error(Error.DFSBROKER_FILE_NOT_FOUND, e.getMessage());
  372. }
  373. catch (IOException e) {
  374. log.info("I/O exception while removing directory '" + fileName + "' - " + e.getMessage());
  375. error = cb.error(Error.DFSBROKER_IO_ERROR, e.getMessage());
  376. }
  377. if (error != Error.OK)
  378. log.severe("Problem sending response to 'rmdir' command - " + Error.GetText(error));
  379. }
  380. /**
  381. *
  382. */
  383. public void Readdir(ResponseCallbackReaddir cb, String dirName) {
  384. int error = Error.OK;
  385. String pathStr;
  386. try {
  387. if (mVerbose)
  388. log.info("Readdir('" + dirName + "')");
  389. Path [] paths = mFilesystem.listPaths(new Path(dirName));
  390. String [] listing = new String [ paths.length ];
  391. for (int i=0; i<paths.length; i++) {
  392. pathStr = paths[i].toString();
  393. int lastSlash = pathStr.lastIndexOf('/');
  394. if (lastSlash == -1)
  395. listing[i] = pathStr;
  396. else
  397. listing[i] = pathStr.substring(lastSlash+1);
  398. }
  399. error = cb.response(listing);
  400. }
  401. catch (FileNotFoundException e) {
  402. log.info("File not found: " + dirName);
  403. error = cb.error(Error.DFSBROKER_FILE_NOT_FOUND, e.getMessage());
  404. }
  405. catch (IOException e) {
  406. log.info("I/O exception while reading directory '" + dirName + "' - " + e.getMessage());
  407. error = cb.error(Error.DFSBROKER_IO_ERROR, e.getMessage());
  408. }
  409. if (error != Error.OK)
  410. log.severe("Problem sending response to 'readdir' command - " + Error.GetText(error));
  411. }
  412. private Configuration mConf = new Configuration();
  413. private FileSystem mFilesystem;
  414. private boolean mVerbose = false;
  415. private OpenFileMap mOpenFileMap = new OpenFileMap();
  416. }