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.omid.examples;
19
20 import org.apache.commons.lang.StringUtils;
21 import org.apache.hadoop.hbase.client.Connection;
22 import org.apache.hadoop.hbase.client.ConnectionFactory;
23 import org.apache.hadoop.hbase.client.Put;
24 import org.apache.hadoop.hbase.util.Bytes;
25 import org.apache.omid.transaction.HBaseTransactionManager;
26 import org.apache.omid.transaction.TTable;
27 import org.apache.omid.transaction.Transaction;
28 import org.apache.omid.transaction.TransactionManager;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 /**
33 * ****************************************************************************************************
34 *
35 * Example code which demonstrates an atomic write into two different rows in HBase
36 *
37 * ****************************************************************************************************
38 *
39 * After building the package with 'mvn clean package' find the resulting examples-{version}-bin.tar.gz file in the
40 * 'examples/target' folder. Copy it to the target host and expand with 'tar -zxvf examples-{version}-bin.tar.gz'.
41 *
42 * Make sure that 'hbase-site.xml' and 'core-site.xml' are either in classpath (see run.sh) or explicitly referenced in
43 * configuration file. If a secure HBase deployment is needed, make sure to specify the principal (user) and keytab file.
44 *
45 * The example requires a user table to perform transactional read/write operations. A table is already specified in
46 * the default configuration, and can be created with the following command using the 'hbase shell':
47 *
48 * <pre>
49 * create 'MY_TX_TABLE', {NAME => 'MY_CF', VERSIONS => '2147483647', TTL => '2147483647'}
50 * </pre>
51 *
52 * Make sure that the principal/user has RW permissions for the given table using also the 'hbase shell':
53 * <pre>
54 * grant '{principal/user}', 'RW', 'MY_TX_TABLE'
55 * </pre>
56 *
57 * Alternatively, a table with a column family already created can be used by specifying the table name and column
58 * family identifiers using the command line arguments (see details also in 'run.sh') If a table namespace is required,
59 * specify it like this: 'namespace:table_name'
60 *
61 * Finally, run the example using the 'run.sh' script without arguments or specifying the necessary configuration
62 * parameters.
63 */
64 public class BasicExample {
65
66 private static final Logger LOG = LoggerFactory.getLogger(BasicExample.class);
67
68 public static void main(String[] args) throws Exception {
69
70 LOG.info("Parsing command line arguments");
71 String userTableName = "MY_TX_TABLE";
72 if (args != null && args.length > 0 && StringUtils.isNotEmpty(args[0])) {
73 userTableName = args[0];
74 }
75 byte[] family = Bytes.toBytes("MY_CF");
76 if (args != null && args.length > 1 && StringUtils.isNotEmpty(args[1])) {
77 family = Bytes.toBytes(args[1]);
78 }
79 LOG.info("Table '{}', column family '{}'", userTableName, Bytes.toString(family));
80
81 byte[] exampleRow1 = Bytes.toBytes("EXAMPLE_ROW1");
82 byte[] exampleRow2 = Bytes.toBytes("EXAMPLE_ROW2");
83 byte[] qualifier = Bytes.toBytes("MY_Q");
84 byte[] dataValue1 = Bytes.toBytes("val1");
85 byte[] dataValue2 = Bytes.toBytes("val2");
86
87 LOG.info("Creating access to Omid Transaction Manager & Transactional Table '{}'", userTableName);
88 try (TransactionManager tm = HBaseTransactionManager.newInstance();
89 Connection conn = ConnectionFactory.createConnection();
90 TTable txTable = new TTable(conn, userTableName))
91 {
92 Transaction tx = tm.begin();
93 LOG.info("Transaction {} STARTED", tx);
94
95 Put row1 = new Put(exampleRow1);
96 row1.addColumn(family, qualifier, dataValue1);
97 txTable.put(tx, row1);
98 LOG.info("Transaction {} trying to write a new value in [TABLE:ROW/CF/Q] => {}:{}/{}/{} = {} ",
99 tx, userTableName, Bytes.toString(exampleRow1), Bytes.toString(family),
100 Bytes.toString(qualifier), Bytes.toString(dataValue1));
101
102 Put row2 = new Put(exampleRow2);
103 row2.addColumn(family, qualifier, dataValue2);
104 txTable.put(tx, row2);
105 LOG.info("Transaction {} trying to write a new value in [TABLE:ROW/CF/Q] => {}:{}/{}/{} = {} ",
106 tx, userTableName, Bytes.toString(exampleRow2), Bytes.toString(family),
107 Bytes.toString(qualifier), Bytes.toString(dataValue2));
108
109 tm.commit(tx);
110 LOG.info("Transaction {} COMMITTED", tx);
111 }
112
113 }
114
115 }