├── .gitignore
├── src
├── main
│ └── java
│ │ └── org
│ │ └── apache
│ │ └── storm
│ │ └── hbase
│ │ ├── trident
│ │ ├── mapper
│ │ │ ├── TridentHBaseMapper.java
│ │ │ └── SimpleTridentHBaseMapper.java
│ │ └── state
│ │ │ ├── HBaseUpdater.java
│ │ │ ├── HBaseStateFactory.java
│ │ │ ├── HBaseQuery.java
│ │ │ ├── HBaseState.java
│ │ │ └── HBaseMapState.java
│ │ ├── common
│ │ ├── ICounter.java
│ │ ├── IColumn.java
│ │ ├── Utils.java
│ │ ├── HBaseClient.java
│ │ └── ColumnList.java
│ │ ├── bolt
│ │ ├── mapper
│ │ │ ├── HBaseMapper.java
│ │ │ ├── HBaseValueMapper.java
│ │ │ ├── HBaseProjectionCriteria.java
│ │ │ └── SimpleHBaseMapper.java
│ │ ├── HBaseBolt.java
│ │ ├── AbstractHBaseBolt.java
│ │ └── HBaseLookupBolt.java
│ │ └── security
│ │ └── HBaseSecurityUtil.java
└── test
│ └── java
│ └── org
│ └── apache
│ └── storm
│ └── hbase
│ ├── trident
│ ├── PrintFunction.java
│ └── WordCountTrident.java
│ └── topology
│ ├── WordCounter.java
│ ├── WordCountClient.java
│ ├── WordCountValueMapper.java
│ ├── TotalWordCounter.java
│ ├── WordSpout.java
│ ├── PersistentWordCount.java
│ └── LookupWordCount.java
├── pom.xml
├── README.md
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 |
--------------------------------------------------------------------------------
/src/main/java/org/apache/storm/hbase/trident/mapper/TridentHBaseMapper.java:
--------------------------------------------------------------------------------
1 | package org.apache.storm.hbase.trident.mapper;
2 |
3 |
4 | import backtype.storm.tuple.Tuple;
5 | import org.apache.storm.hbase.common.ColumnList;
6 | import storm.trident.tuple.TridentTuple;
7 |
8 | import java.io.Serializable;
9 | /**
10 | * Maps a storm.trident.tuple.TridentTuple object
11 | * to a row in an HBase table.
12 | */
13 | public interface TridentHBaseMapper extends Serializable {
14 |
15 |
16 | /**
17 | * Given a tuple, return the HBase rowkey.
18 | *
19 | * @param tuple
20 | * @return
21 | */
22 | byte[] rowKey(TridentTuple tuple);
23 |
24 | /**
25 | * Given a tuple, return a list of HBase columns to insert.
26 | *
27 | * @param tuple
28 | * @return
29 | */
30 | ColumnList columns(TridentTuple tuple);
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/org/apache/storm/hbase/common/ICounter.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Licensed to the Apache Software Foundation (ASF) under one
3 | * or more contributor license agreements. See the NOTICE file
4 | * distributed with this work for additional information
5 | * regarding copyright ownership. The ASF licenses this file
6 | * to you under the Apache License, Version 2.0 (the
7 | * "License"); you may not use this file except in compliance
8 | * with the License. You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package org.apache.storm.hbase.common;
19 |
20 | /**
21 | * Interface definition for classes that support being written to HBase as
22 | * a counter column.
23 | *
24 | */
25 | public interface ICounter {
26 | byte[] family();
27 | byte[] qualifier();
28 | long increment();
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/org/apache/storm/hbase/common/IColumn.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Licensed to the Apache Software Foundation (ASF) under one
3 | * or more contributor license agreements. See the NOTICE file
4 | * distributed with this work for additional information
5 | * regarding copyright ownership. The ASF licenses this file
6 | * to you under the Apache License, Version 2.0 (the
7 | * "License"); you may not use this file except in compliance
8 | * with the License. You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package org.apache.storm.hbase.common;
19 |
20 | /**
21 | * Interface definition for classes that support being written to HBase as
22 | * a regular column.
23 | *
24 | */
25 | public interface IColumn {
26 | byte[] family();
27 | byte[] qualifier();
28 | byte[] value();
29 | long timestamp();
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/org/apache/storm/hbase/trident/state/HBaseUpdater.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Licensed to the Apache Software Foundation (ASF) under one
3 | * or more contributor license agreements. See the NOTICE file
4 | * distributed with this work for additional information
5 | * regarding copyright ownership. The ASF licenses this file
6 | * to you under the Apache License, Version 2.0 (the
7 | * "License"); you may not use this file except in compliance
8 | * with the License. You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package org.apache.storm.hbase.trident.state;
19 |
20 | import storm.trident.operation.TridentCollector;
21 | import storm.trident.state.BaseStateUpdater;
22 | import storm.trident.tuple.TridentTuple;
23 |
24 | import java.util.List;
25 |
26 | public class HBaseUpdater extends BaseStateUpdater {
27 |
28 | @Override
29 | public void updateState(HBaseState hBaseState, List tuples, TridentCollector collector) {
30 | hBaseState.updateState(tuples, collector);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/test/java/org/apache/storm/hbase/trident/PrintFunction.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Licensed to the Apache Software Foundation (ASF) under one
3 | * or more contributor license agreements. See the NOTICE file
4 | * distributed with this work for additional information
5 | * regarding copyright ownership. The ASF licenses this file
6 | * to you under the Apache License, Version 2.0 (the
7 | * "License"); you may not use this file except in compliance
8 | * with the License. You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package org.apache.storm.hbase.trident;
19 |
20 | import org.slf4j.Logger;
21 | import org.slf4j.LoggerFactory;
22 | import storm.trident.operation.BaseFunction;
23 | import storm.trident.operation.TridentCollector;
24 | import storm.trident.tuple.TridentTuple;
25 |
26 | import java.util.Random;
27 |
28 | public class PrintFunction extends BaseFunction {
29 |
30 | private static final Logger LOG = LoggerFactory.getLogger(PrintFunction.class);
31 |
32 | private static final Random RANDOM = new Random();
33 |
34 | @Override
35 | public void execute(TridentTuple tuple, TridentCollector tridentCollector) {
36 | if(RANDOM.nextInt(1000) > 995) {
37 | LOG.info(tuple.toString());
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/org/apache/storm/hbase/bolt/mapper/HBaseMapper.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Licensed to the Apache Software Foundation (ASF) under one
3 | * or more contributor license agreements. See the NOTICE file
4 | * distributed with this work for additional information
5 | * regarding copyright ownership. The ASF licenses this file
6 | * to you under the Apache License, Version 2.0 (the
7 | * "License"); you may not use this file except in compliance
8 | * with the License. You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package org.apache.storm.hbase.bolt.mapper;
19 |
20 |
21 | import backtype.storm.tuple.Tuple;
22 | import org.apache.storm.hbase.common.ColumnList;
23 |
24 | import java.io.Serializable;
25 |
26 | /**
27 | * Maps a backtype.storm.tuple.Tuple object
28 | * to a row in an HBase table.
29 | */
30 | public interface HBaseMapper extends Serializable {
31 |
32 | /**
33 | * Given a tuple, return the HBase rowkey.
34 | *
35 | * @param tuple
36 | * @return
37 | */
38 | byte[] rowKey(Tuple tuple);
39 |
40 | /**
41 | * Given a tuple, return a list of HBase columns to insert.
42 | *
43 | * @param tuple
44 | * @return
45 | */
46 | ColumnList columns(Tuple tuple);
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/org/apache/storm/hbase/trident/state/HBaseStateFactory.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Licensed to the Apache Software Foundation (ASF) under one
3 | * or more contributor license agreements. See the NOTICE file
4 | * distributed with this work for additional information
5 | * regarding copyright ownership. The ASF licenses this file
6 | * to you under the Apache License, Version 2.0 (the
7 | * "License"); you may not use this file except in compliance
8 | * with the License. You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package org.apache.storm.hbase.trident.state;
19 |
20 | import backtype.storm.task.IMetricsContext;
21 | import storm.trident.state.State;
22 | import storm.trident.state.StateFactory;
23 |
24 | import java.util.Map;
25 |
26 | public class HBaseStateFactory implements StateFactory {
27 |
28 | private HBaseState.Options options;
29 |
30 | public HBaseStateFactory(HBaseState.Options options) {
31 | this.options = options;
32 | }
33 |
34 | @Override
35 | public State makeState(Map map, IMetricsContext iMetricsContext, int partitionIndex, int numPartitions) {
36 | HBaseState state = new HBaseState(map , partitionIndex, numPartitions, options);
37 | state.prepare();
38 | return state;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/org/apache/storm/hbase/bolt/mapper/HBaseValueMapper.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Licensed to the Apache Software Foundation (ASF) under one
3 | * or more contributor license agreements. See the NOTICE file
4 | * distributed with this work for additional information
5 | * regarding copyright ownership. The ASF licenses this file
6 | * to you under the Apache License, Version 2.0 (the
7 | * "License"); you may not use this file except in compliance
8 | * with the License. You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package org.apache.storm.hbase.bolt.mapper;
19 |
20 | import backtype.storm.topology.OutputFieldsDeclarer;
21 | import backtype.storm.tuple.Values;
22 | import org.apache.hadoop.hbase.client.Result;
23 |
24 | import java.io.Serializable;
25 | import java.util.List;
26 |
27 | public interface HBaseValueMapper extends Serializable {
28 | /**
29 | *
30 | * @param result HBase lookup result instance.
31 | * @return list of values that should be emitted by the lookup bolt.
32 | * @throws Exception
33 | */
34 | public List toValues(Result result) throws Exception;
35 |
36 | /**
37 | * declares the output fields for the lookup bolt.
38 | * @param declarer
39 | */
40 | void declareOutputFields(OutputFieldsDeclarer declarer);
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/org/apache/storm/hbase/trident/state/HBaseQuery.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Licensed to the Apache Software Foundation (ASF) under one
3 | * or more contributor license agreements. See the NOTICE file
4 | * distributed with this work for additional information
5 | * regarding copyright ownership. The ASF licenses this file
6 | * to you under the Apache License, Version 2.0 (the
7 | * "License"); you may not use this file except in compliance
8 | * with the License. You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package org.apache.storm.hbase.trident.state;
19 |
20 | import backtype.storm.tuple.Values;
21 | import storm.trident.operation.TridentCollector;
22 | import storm.trident.state.BaseQueryFunction;
23 | import storm.trident.tuple.TridentTuple;
24 |
25 | import java.util.List;
26 |
27 | public class HBaseQuery extends BaseQueryFunction> {
28 |
29 | @Override
30 | public List> batchRetrieve(HBaseState hBaseState, List tridentTuples) {
31 | return hBaseState.batchRetrieve(tridentTuples);
32 | }
33 |
34 | @Override
35 | public void execute(TridentTuple tuples, List values, TridentCollector tridentCollector) {
36 | for (Values value : values) {
37 | tridentCollector.emit(value);
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/test/java/org/apache/storm/hbase/topology/WordCounter.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Licensed to the Apache Software Foundation (ASF) under one
3 | * or more contributor license agreements. See the NOTICE file
4 | * distributed with this work for additional information
5 | * regarding copyright ownership. The ASF licenses this file
6 | * to you under the Apache License, Version 2.0 (the
7 | * "License"); you may not use this file except in compliance
8 | * with the License. You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package org.apache.storm.hbase.topology;
19 |
20 | import backtype.storm.task.TopologyContext;
21 | import backtype.storm.topology.BasicOutputCollector;
22 | import backtype.storm.topology.IBasicBolt;
23 | import backtype.storm.topology.OutputFieldsDeclarer;
24 | import backtype.storm.tuple.Fields;
25 | import backtype.storm.tuple.Tuple;
26 |
27 | import java.util.Map;
28 |
29 | import static backtype.storm.utils.Utils.tuple;
30 |
31 | public class WordCounter implements IBasicBolt {
32 |
33 |
34 | @SuppressWarnings("rawtypes")
35 | public void prepare(Map stormConf, TopologyContext context) {
36 | }
37 |
38 | /*
39 | * Just output the word value with a count of 1.
40 | * The HBaseBolt will handle incrementing the counter.
41 | */
42 | public void execute(Tuple input, BasicOutputCollector collector) {
43 | collector.emit(tuple(input.getValues().get(0), 1));
44 | }
45 |
46 | public void cleanup() {
47 |
48 | }
49 |
50 | public void declareOutputFields(OutputFieldsDeclarer declarer) {
51 | declarer.declare(new Fields("word", "count"));
52 | }
53 |
54 | @Override
55 | public Map getComponentConfiguration() {
56 | return null;
57 | }
58 |
59 | }
--------------------------------------------------------------------------------
/src/main/java/org/apache/storm/hbase/security/HBaseSecurityUtil.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Licensed to the Apache Software Foundation (ASF) under one
3 | * or more contributor license agreements. See the NOTICE file
4 | * distributed with this work for additional information
5 | * regarding copyright ownership. The ASF licenses this file
6 | * to you under the Apache License, Version 2.0 (the
7 | * "License"); you may not use this file except in compliance
8 | * with the License. You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package org.apache.storm.hbase.security;
19 |
20 | import org.apache.hadoop.conf.Configuration;
21 | import org.apache.hadoop.hbase.security.UserProvider;
22 | import org.apache.hadoop.security.UserGroupInformation;
23 |
24 | import java.io.IOException;
25 | import java.net.InetAddress;
26 | import java.util.Map;
27 |
28 | /**
29 | * This class provides util methods for storm-hbase connector communicating
30 | * with secured HBase.
31 | */
32 | public class HBaseSecurityUtil {
33 | public static final String STORM_KEYTAB_FILE_KEY = "storm.keytab.file";
34 | public static final String STORM_USER_NAME_KEY = "storm.kerberos.principal";
35 |
36 | public static UserProvider login(Map conf, Configuration hbaseConfig) throws IOException {
37 | UserProvider provider = UserProvider.instantiate(hbaseConfig);
38 | if (UserGroupInformation.isSecurityEnabled()) {
39 | String keytab = (String) conf.get(STORM_KEYTAB_FILE_KEY);
40 | if (keytab != null) {
41 | hbaseConfig.set(STORM_KEYTAB_FILE_KEY, keytab);
42 | }
43 | String userName = (String) conf.get(STORM_USER_NAME_KEY);
44 | if (userName != null) {
45 | hbaseConfig.set(STORM_USER_NAME_KEY, userName);
46 | }
47 | provider.login(STORM_KEYTAB_FILE_KEY, STORM_USER_NAME_KEY,
48 | InetAddress.getLocalHost().getCanonicalHostName());
49 | }
50 | return provider;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/test/java/org/apache/storm/hbase/topology/WordCountClient.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Licensed to the Apache Software Foundation (ASF) under one
3 | * or more contributor license agreements. See the NOTICE file
4 | * distributed with this work for additional information
5 | * regarding copyright ownership. The ASF licenses this file
6 | * to you under the Apache License, Version 2.0 (the
7 | * "License"); you may not use this file except in compliance
8 | * with the License. You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package org.apache.storm.hbase.topology;
19 |
20 | import org.apache.hadoop.conf.Configuration;
21 | import org.apache.hadoop.hbase.HBaseConfiguration;
22 | import org.apache.hadoop.hbase.client.Get;
23 | import org.apache.hadoop.hbase.client.HTable;
24 | import org.apache.hadoop.hbase.client.Result;
25 | import org.apache.hadoop.hbase.util.Bytes;
26 |
27 | /**
28 | * Connects to the 'WordCount' table and prints counts for each word.
29 | *
30 | * Assumes you have run (or are running) PersistentWordCount
31 | */
32 | public class WordCountClient {
33 |
34 | public static void main(String[] args) throws Exception {
35 | Configuration config = HBaseConfiguration.create();
36 | if(args.length > 0){
37 | config.set("hbase.rootdir", args[0]);
38 | }
39 |
40 | HTable table = new HTable(config, "WordCount");
41 |
42 |
43 | for (String word : WordSpout.words) {
44 | Get get = new Get(Bytes.toBytes(word));
45 | Result result = table.get(get);
46 |
47 | byte[] countBytes = result.getValue(Bytes.toBytes("cf"), Bytes.toBytes("count"));
48 | byte[] wordBytes = result.getValue(Bytes.toBytes("cf"), Bytes.toBytes("word"));
49 |
50 | String wordStr = Bytes.toString(wordBytes);
51 | System.out.println(wordStr);
52 | long count = Bytes.toLong(countBytes);
53 | System.out.println("Word: '" + wordStr + "', Count: " + count);
54 | }
55 |
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/test/java/org/apache/storm/hbase/topology/WordCountValueMapper.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Licensed to the Apache Software Foundation (ASF) under one
3 | * or more contributor license agreements. See the NOTICE file
4 | * distributed with this work for additional information
5 | * regarding copyright ownership. The ASF licenses this file
6 | * to you under the Apache License, Version 2.0 (the
7 | * "License"); you may not use this file except in compliance
8 | * with the License. You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package org.apache.storm.hbase.topology;
19 |
20 |
21 | import backtype.storm.topology.OutputFieldsDeclarer;
22 | import backtype.storm.tuple.Fields;
23 | import backtype.storm.tuple.Values;
24 | import org.apache.hadoop.hbase.Cell;
25 | import org.apache.hadoop.hbase.CellUtil;
26 | import org.apache.hadoop.hbase.client.Result;
27 | import org.apache.hadoop.hbase.util.Bytes;
28 | import org.apache.storm.hbase.bolt.mapper.HBaseValueMapper;
29 |
30 | import java.util.ArrayList;
31 | import java.util.List;
32 |
33 | /**
34 | * Takes a Hbase result and returns a value list that has a value instance for each column and corresponding value.
35 | * So if the result from Hbase was
36 | *