001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hbase.archetypes.exemplars.client;
019
020import java.io.IOException;
021import java.util.Map.Entry;
022import java.util.NavigableMap;
023import org.apache.hadoop.hbase.NamespaceDescriptor;
024import org.apache.hadoop.hbase.NamespaceNotFoundException;
025import org.apache.hadoop.hbase.TableName;
026import org.apache.hadoop.hbase.client.Admin;
027import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
028import org.apache.hadoop.hbase.client.Connection;
029import org.apache.hadoop.hbase.client.ConnectionFactory;
030import org.apache.hadoop.hbase.client.Delete;
031import org.apache.hadoop.hbase.client.Get;
032import org.apache.hadoop.hbase.client.Put;
033import org.apache.hadoop.hbase.client.Result;
034import org.apache.hadoop.hbase.client.Table;
035import org.apache.hadoop.hbase.client.TableDescriptor;
036import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
037import org.apache.hadoop.hbase.util.Bytes;
038
039/**
040 * Successful running of this application requires access to an active instance of HBase. For
041 * install instructions for a standalone instance of HBase, please refer to
042 * https://hbase.apache.org/book.html#quickstart
043 */
044public final class HelloHBase {
045
046  static final String MY_NAMESPACE_NAME = "myTestNamespace";
047  static final TableName MY_TABLE_NAME = TableName.valueOf("myTestTable");
048  static final byte[] MY_COLUMN_FAMILY_NAME = Bytes.toBytes("cf");
049  static final byte[] MY_FIRST_COLUMN_QUALIFIER = Bytes.toBytes("myFirstColumn");
050  static final byte[] MY_SECOND_COLUMN_QUALIFIER = Bytes.toBytes("mySecondColumn");
051  static final byte[] MY_ROW_ID = Bytes.toBytes("rowId01");
052
053  // Private constructor included here to avoid checkstyle warnings
054  private HelloHBase() {
055  }
056
057  public static void main(final String[] args) throws IOException {
058    final boolean deleteAllAtEOJ = true;
059
060    /**
061     * ConnectionFactory#createConnection() automatically looks for hbase-site.xml (HBase
062     * configuration parameters) on the system's CLASSPATH, to enable creation of Connection to
063     * HBase via ZooKeeper.
064     */
065    try (Connection connection = ConnectionFactory.createConnection();
066      Admin admin = connection.getAdmin()) {
067
068      admin.getClusterStatus(); // assure connection successfully established
069      System.out
070        .println("\n*** Hello HBase! -- Connection has been " + "established via ZooKeeper!!\n");
071
072      createNamespaceAndTable(admin);
073
074      System.out.println("Getting a Table object for [" + MY_TABLE_NAME
075        + "] with which to perform CRUD operations in HBase.");
076      try (Table table = connection.getTable(MY_TABLE_NAME)) {
077
078        putRowToTable(table);
079        getAndPrintRowContents(table);
080
081        if (deleteAllAtEOJ) {
082          deleteRow(table);
083        }
084      }
085
086      if (deleteAllAtEOJ) {
087        deleteNamespaceAndTable(admin);
088      }
089    }
090  }
091
092  /**
093   * Invokes Admin#createNamespace and Admin#createTable to create a namespace with a table that has
094   * one column-family.
095   * @param admin Standard Admin object
096   * @throws IOException If IO problem encountered
097   */
098  static void createNamespaceAndTable(final Admin admin) throws IOException {
099
100    if (!namespaceExists(admin, MY_NAMESPACE_NAME)) {
101      System.out.println("Creating Namespace [" + MY_NAMESPACE_NAME + "].");
102
103      admin.createNamespace(NamespaceDescriptor.create(MY_NAMESPACE_NAME).build());
104    }
105    if (!admin.tableExists(MY_TABLE_NAME)) {
106      System.out.println("Creating Table [" + MY_TABLE_NAME.getNameAsString()
107        + "], with one Column Family [" + Bytes.toString(MY_COLUMN_FAMILY_NAME) + "].");
108      TableDescriptor desc = TableDescriptorBuilder.newBuilder(MY_TABLE_NAME)
109        .setColumnFamily(ColumnFamilyDescriptorBuilder.of(MY_COLUMN_FAMILY_NAME)).build();
110      admin.createTable(desc);
111    }
112  }
113
114  /**
115   * Invokes Table#put to store a row (with two new columns created 'on the fly') into the table.
116   * @param table Standard Table object (used for CRUD operations).
117   * @throws IOException If IO problem encountered
118   */
119  static void putRowToTable(final Table table) throws IOException {
120
121    table.put(new Put(MY_ROW_ID)
122      .addColumn(MY_COLUMN_FAMILY_NAME, MY_FIRST_COLUMN_QUALIFIER, Bytes.toBytes("Hello"))
123      .addColumn(MY_COLUMN_FAMILY_NAME, MY_SECOND_COLUMN_QUALIFIER, Bytes.toBytes("World!")));
124
125    System.out.println("Row [" + Bytes.toString(MY_ROW_ID) + "] was put into Table ["
126      + table.getName().getNameAsString() + "] in HBase;\n"
127      + "  the row's two columns (created 'on the fly') are: ["
128      + Bytes.toString(MY_COLUMN_FAMILY_NAME) + ":" + Bytes.toString(MY_FIRST_COLUMN_QUALIFIER)
129      + "] and [" + Bytes.toString(MY_COLUMN_FAMILY_NAME) + ":"
130      + Bytes.toString(MY_SECOND_COLUMN_QUALIFIER) + "]");
131  }
132
133  /**
134   * Invokes Table#get and prints out the contents of the retrieved row.
135   * @param table Standard Table object
136   * @throws IOException If IO problem encountered
137   */
138  static void getAndPrintRowContents(final Table table) throws IOException {
139
140    Result row = table.get(new Get(MY_ROW_ID));
141
142    System.out.println("Row [" + Bytes.toString(row.getRow()) + "] was retrieved from Table ["
143      + table.getName().getNameAsString() + "] in HBase, with the following content:");
144
145    for (Entry<byte[], NavigableMap<byte[], byte[]>> colFamilyEntry : row.getNoVersionMap()
146      .entrySet()) {
147      String columnFamilyName = Bytes.toString(colFamilyEntry.getKey());
148
149      System.out.println("  Columns in Column Family [" + columnFamilyName + "]:");
150
151      for (Entry<byte[], byte[]> columnNameAndValueMap : colFamilyEntry.getValue().entrySet()) {
152
153        System.out.println("    Value of Column [" + columnFamilyName + ":"
154          + Bytes.toString(columnNameAndValueMap.getKey()) + "] == "
155          + Bytes.toString(columnNameAndValueMap.getValue()));
156      }
157    }
158  }
159
160  /**
161   * Checks to see whether a namespace exists.
162   * @param admin         Standard Admin object
163   * @param namespaceName Name of namespace
164   * @return true If namespace exists
165   * @throws IOException If IO problem encountered
166   */
167  static boolean namespaceExists(final Admin admin, final String namespaceName) throws IOException {
168    try {
169      admin.getNamespaceDescriptor(namespaceName);
170    } catch (NamespaceNotFoundException e) {
171      return false;
172    }
173    return true;
174  }
175
176  /**
177   * Invokes Table#delete to delete test data (i.e. the row)
178   * @param table Standard Table object
179   * @throws IOException If IO problem is encountered
180   */
181  static void deleteRow(final Table table) throws IOException {
182    System.out.println("Deleting row [" + Bytes.toString(MY_ROW_ID) + "] from Table ["
183      + table.getName().getNameAsString() + "].");
184    table.delete(new Delete(MY_ROW_ID));
185  }
186
187  /**
188   * Invokes Admin#disableTable, Admin#deleteTable, and Admin#deleteNamespace to disable/delete
189   * Table and delete Namespace.
190   * @param admin Standard Admin object
191   * @throws IOException If IO problem is encountered
192   */
193  static void deleteNamespaceAndTable(final Admin admin) throws IOException {
194    if (admin.tableExists(MY_TABLE_NAME)) {
195      System.out.println("Disabling/deleting Table [" + MY_TABLE_NAME.getNameAsString() + "].");
196      admin.disableTable(MY_TABLE_NAME); // Disable a table before deleting it.
197      admin.deleteTable(MY_TABLE_NAME);
198    }
199    if (namespaceExists(admin, MY_NAMESPACE_NAME)) {
200      System.out.println("Deleting Namespace [" + MY_NAMESPACE_NAME + "].");
201      admin.deleteNamespace(MY_NAMESPACE_NAME);
202    }
203  }
204}