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