title: Insert rows into HBase from a Storm bolt
body: <p>I would like to be able to write new entries into HBase from a distributed (not local) Storm topology. There exist a few GitHub projects that provide either <a href="https://github.com/ptgoetz/storm-hbase" rel="nofollow">HBase Mappers</a> or <a href="https://github.com/jrkinley/storm-hbase/wiki/HBase-Storm-Bolts" rel="nofollow">pre-made Storm bolts</a> to write Tuples into HBase. These projects provide instructions for executing their samples on the LocalCluster.</p>
  
  <p>The problem that I am running into with both of these projects, and directly accessing the HBase API from the bolt, is that they all require the HBase-site.xml file to be included on the classpath. With the direct API approach, and perhaps with the GitHub ones as well, when you execute <code>HBaseConfiguration.create();</code> it will try to find the information it needs from an entry on the classpath. </p>
  
  <p>How can I modify the classpath for the storm bolts to include the Hbase configuration file? </p>
  
  <p><strong>Update: Using danehammer's answer, this is how i got it working</strong></p>
  
  <p>Copy the following files into your ~/.storm directory:</p>
  
  <ul>
  <li>hbase-common-0.98.0.2.1.2.0-402-hadoop2.jar  </li>
  <li>hbase-site.xml  </li>
  <li>storm.yaml  :   NOTE: if you do not copy storm.yaml into that directory, then the storm jar command will NOT use that directory in the classpath (see the <a href="https://github.com/apache/incubator-storm/blob/master/storm-core/src/multilang/py/storm.py" rel="nofollow">storm.py python script</a> to see that logic for yourself - would be nice if this was documented)</li>
  </ul>
  
  <p>Next, in your topology class's main method get the HBase Configuration and serialize it:</p>
  
  <pre><code>final Configuration hbaseConfig = HBaseConfiguration.create();
  final DataOutputBuffer databufHbaseConfig = new DataOutputBuffer();
  hbaseConfig.write(databufHbaseConfig);
  final byte[] baHbaseConfigSerialized = databufHbaseConfig.getData();
  </code></pre>
  
  <p>Pass the byte array to your spout class through the constructor. The spout class saves this byte array to a field (Do not deserialize in the constructor. I found that if the spout has a Configuration field you will get a cannot serialize exception when running the topology)</p>
  
  <p>in the spout's open method, deserialize the config and access the hbase table:</p>
  
  <pre><code>Configuration hBaseConfiguration = new Configuration();
  ByteArrayInputStream bas = new ByteArrayInputStream(baHbaseConfigSerialized);
  hBaseConfiguration.readFields(new DataInputStream(bas));
  HTable tbl = new HTable(hBaseConfiguration, HBASE_TABLE_NAME);
  
  Scan scan = new Scan();
  scan.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("YOUR_COLUMN"));
  
  scnrTbl = tbl.getScanner(scan);
  </code></pre>
  
  <p>Now, in your nextTuple method you can use the Scanner to get the next row:</p>
  
  <pre><code>Result rsltWaveform = scnrWaveformTbl.next();
  </code></pre>
  
  <p>Extract what you want from the result, and pass those values in some serializable object to the bolts.</p>