| <!DOCTYPE HTML> |
| <html lang="en"> |
| <head> |
| <!-- Generated by javadoc (17) --> |
| <title>org.apache.hadoop.hbase.constraint (Apache HBase 4.0.0-alpha-1-SNAPSHOT API)</title> |
| <meta name="viewport" content="width=device-width, initial-scale=1"> |
| <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
| <meta name="description" content="declaration: package: org.apache.hadoop.hbase.constraint"> |
| <meta name="generator" content="javadoc/PackageWriterImpl"> |
| <link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style"> |
| <link rel="stylesheet" type="text/css" href="../../../../../script-dir/jquery-ui.min.css" title="Style"> |
| <link rel="stylesheet" type="text/css" href="../../../../../jquery-ui.overrides.css" title="Style"> |
| <script type="text/javascript" src="../../../../../script.js"></script> |
| <script type="text/javascript" src="../../../../../script-dir/jquery-3.6.1.min.js"></script> |
| <script type="text/javascript" src="../../../../../script-dir/jquery-ui.min.js"></script> |
| </head> |
| <body class="package-declaration-page"> |
| <script type="text/javascript">var evenRowColor = "even-row-color"; |
| var oddRowColor = "odd-row-color"; |
| var tableTab = "table-tab"; |
| var activeTableTab = "active-table-tab"; |
| var pathtoroot = "../../../../../"; |
| loadScripts(document, 'script');</script> |
| <noscript> |
| <div>JavaScript is disabled on your browser.</div> |
| </noscript> |
| <div class="flex-box"> |
| <header role="banner" class="flex-header"> |
| <nav role="navigation"> |
| <!-- ========= START OF TOP NAVBAR ======= --> |
| <div class="top-nav" id="navbar-top"> |
| <div class="skip-nav"><a href="#skip-navbar-top" title="Skip navigation links">Skip navigation links</a></div> |
| <ul id="navbar-top-firstrow" class="nav-list" title="Navigation"> |
| <li><a href="../../../../../index.html">Overview</a></li> |
| <li class="nav-bar-cell1-rev">Package</li> |
| <li>Class</li> |
| <li><a href="package-use.html">Use</a></li> |
| <li><a href="package-tree.html">Tree</a></li> |
| <li><a href="../../../../../deprecated-list.html">Deprecated</a></li> |
| <li><a href="../../../../../index-all.html">Index</a></li> |
| <li><a href="../../../../../help-doc.html#package">Help</a></li> |
| </ul> |
| </div> |
| <div class="sub-nav"> |
| <div> |
| <ul class="sub-nav-list"> |
| <li>Package: </li> |
| <li><a href="#package-description">Description</a> | </li> |
| <li><a href="#related-package-summary">Related Packages</a> | </li> |
| <li><a href="#class-summary">Classes and Interfaces</a></li> |
| </ul> |
| </div> |
| <div class="nav-list-search"><label for="search-input">SEARCH:</label> |
| <input type="text" id="search-input" value="search" disabled="disabled"> |
| <input type="reset" id="reset-button" value="reset" disabled="disabled"> |
| </div> |
| </div> |
| <!-- ========= END OF TOP NAVBAR ========= --> |
| <span class="skip-nav" id="skip-navbar-top"></span></nav> |
| </header> |
| <div class="flex-content"> |
| <main role="main"> |
| <div class="header"> |
| <h1 title="Package org.apache.hadoop.hbase.constraint" class="title">Package org.apache.hadoop.hbase.constraint</h1> |
| </div> |
| <hr> |
| <div class="package-signature">package <span class="element-name">org.apache.hadoop.hbase.constraint</span></div> |
| <section class="package-description" id="package-description"> |
| <div class="block">Restrict the domain of a data attribute, often times to fulfill business rules/requirements. |
| <h2>Table of Contents</h2> |
| <ul> |
| <li><a href="#overview">Overview</a></li> |
| <li><a href="#concurrency">Concurrency and Atomicity</a></li> |
| <li><a href="#caveats">Caveats</a></li> |
| <li><a href="#usage">Example Usage</a></li> |
| </ul> |
| <h2><a name="overview">Overview</a></h2> Constraints are used to enforce business rules in a |
| database. By checking all <a href="../client/Put.html" title="class in org.apache.hadoop.hbase.client"><code>Puts</code></a> on a given table, you |
| can enforce very specific data policies. For instance, you can ensure that a certain column |
| family-column qualifier pair always has a value between 1 and 10. Otherwise, the |
| <a href="../client/Put.html" title="class in org.apache.hadoop.hbase.client"><code>Put</code></a> is rejected and the data integrity is maintained. |
| <p/> |
| Constraints are designed to be configurable, so a constraint can be used across different tables, |
| but implement different behavior depending on the specific configuration given to that |
| constraint. |
| <p/> |
| By adding a constraint to a table (see <a href="#usage">Example Usage</a>), constraints will |
| automatically be enabled. You also then have the option of to disable (just 'turn off') or remove |
| (delete all associated information) all constraints on a table. If you remove all constraints |
| (see |
| <a href="Constraints.html#remove(org.apache.hadoop.hbase.client.TableDescriptorBuilder)"><code>Constraints.remove(org.apache.hadoop.hbase.client.TableDescriptorBuilder)</code></a>, |
| you must re-add any <a href="Constraint.html" title="interface in org.apache.hadoop.hbase.constraint"><code>Constraint</code></a> you want on that table. |
| However, if they are just disabled (see |
| <a href="Constraints.html#disable(org.apache.hadoop.hbase.client.TableDescriptorBuilder)"><code>Constraints.disable(org.apache.hadoop.hbase.client.TableDescriptorBuilder)</code></a>, |
| all you need to do is enable constraints again, and everything will be turned back on as it was |
| configured. Individual constraints can also be individually enabled, disabled or removed without |
| affecting other constraints. |
| <p/> |
| By default, constraints are disabled on a table. This means you will not see <i>any</i> slow down |
| on a table if constraints are not enabled. |
| <p/> |
| <h2><a name="concurrency">Concurrency and Atomicity</a></h2> Currently, no attempts at enforcing |
| correctness in a multi-threaded scenario when modifying a constraint, via |
| <a href="Constraints.html" title="class in org.apache.hadoop.hbase.constraint"><code>Constraints</code></a>, to the the |
| <a href="../client/TableDescriptorBuilder.html" title="class in org.apache.hadoop.hbase.client"><code>TableDescriptorBuilder</code></a>. This is particularly important |
| when adding a constraint(s) to the <a href="../client/TableDescriptorBuilder.html" title="class in org.apache.hadoop.hbase.client"><code>TableDescriptorBuilder</code></a> |
| as it first retrieves the next priority from a custom value set in the descriptor, adds each |
| constraint (with increasing priority) to the descriptor, and then the next available priority is |
| re-stored back in the <a href="../client/TableDescriptorBuilder.html" title="class in org.apache.hadoop.hbase.client"><code>TableDescriptorBuilder</code></a>. |
| <p/> |
| Locking is recommended around each of Constraints add methods: |
| <a href="Constraints.html#add(org.apache.hadoop.hbase.client.TableDescriptorBuilder,java.lang.Class...)"><code>Constraints.add(org.apache.hadoop.hbase.client.TableDescriptorBuilder, Class...)</code></a>, |
| <a href="Constraints.html#add(org.apache.hadoop.hbase.client.TableDescriptorBuilder,org.apache.hadoop.hbase.util.Pair...)"><code>Constraints.add(org.apache.hadoop.hbase.client.TableDescriptorBuilder, org.apache.hadoop.hbase.util.Pair...)</code></a>, |
| and |
| <a href="Constraints.html#add(org.apache.hadoop.hbase.client.TableDescriptorBuilder,java.lang.Class,org.apache.hadoop.conf.Configuration)"><code>Constraints.add(org.apache.hadoop.hbase.client.TableDescriptorBuilder, Class, org.apache.hadoop.conf.Configuration)</code></a>. |
| Any changes on <i>a single TableDescriptor</i> should be serialized, either within a single |
| thread or via external mechanisms. |
| <p/> |
| Note that having a higher priority means that a constraint will run later; e.g. a constraint with |
| priority 1 will run before a constraint with priority 2. |
| <p/> |
| Since Constraints currently are designed to just implement simple checks (e.g. is the value in |
| the right range), there will be no atomicity conflicts. Even if one of the puts finishes the |
| constraint first, the single row will not be corrupted and the 'fastest' write will win; the |
| underlying region takes care of breaking the tie and ensuring that writes get serialized to the |
| table. So yes, this doesn't ensure that we are going to get specific ordering or even a fully |
| consistent view of the underlying data. |
| <p/> |
| Each constraint should only use local/instance variables, unless doing more advanced usage. |
| Static variables could cause difficulties when checking concurrent writes to the same region, |
| leading to either highly locked situations (decreasing through-put) or higher probability of |
| errors. However, as long as each constraint just uses local variables, each thread interacting |
| with the constraint will execute correctly and efficiently. |
| <h2><a name="caveats">Caveats</a></h2> In traditional (SQL) databases, Constraints are often used |
| to enforce <a href="http://en.wikipedia.org/wiki/Relational_database#Constraints">referential |
| integrity</a>. However, in HBase, this will likely cause significant overhead and dramatically |
| decrease the number of <a href="../client/Put.html" title="class in org.apache.hadoop.hbase.client"><code>Puts</code></a>/second possible on a |
| table. This is because to check the referential integrity when making a |
| <a href="../client/Put.html" title="class in org.apache.hadoop.hbase.client"><code>Put</code></a>, one must block on a scan for the 'remote' table, |
| checking for the valid reference. For millions of <a href="../client/Put.html" title="class in org.apache.hadoop.hbase.client"><code>Puts</code></a> |
| a second, this will breakdown very quickly. There are several options around the blocking |
| behavior including, but not limited to: |
| <ul> |
| <li>Create a 'pre-join' table where the keys are already denormalized</li> |
| <li>Designing for 'incorrect' references</li> |
| <li>Using an external enforcement mechanism</li> |
| </ul> |
| There are also several general considerations that must be taken into account, when using |
| Constraints: |
| <ol> |
| <li>All changes made via <a href="Constraints.html" title="class in org.apache.hadoop.hbase.constraint"><code>Constraints</code></a> will make |
| modifications to the <a href="../client/TableDescriptor.html" title="interface in org.apache.hadoop.hbase.client"><code>TableDescriptor</code></a> for a given table. As |
| such, the usual renabling of tables should be used for propagating changes to the table. When at |
| all possible, Constraints should be added to the table before the table is created.</li> |
| <li>Constraints are run in the order that they are added to a table. This has implications for |
| what order constraints should be added to a table.</li> |
| <li>Whenever new Constraint jars are added to a region server, those region servers need to go |
| through a rolling restart to make sure that they pick up the new jars and can enable the new |
| constraints.</li> |
| <li>There are certain keys that are reserved for the Configuration namespace: |
| <ul> |
| <li>_ENABLED - used server-side to determine if a constraint should be run</li> |
| <li>_PRIORITY - used server-side to determine what order a constraint should be run</li> |
| </ul> |
| If these items are set, they will be respected in the constraint configuration, but they are |
| taken care of by default in when adding constraints to an |
| <a href="../client/TableDescriptorBuilder.html" title="class in org.apache.hadoop.hbase.client"><code>TableDescriptorBuilder</code></a> via the usual method.</li> |
| </ol> |
| <p/> |
| Under the hood, constraints are implemented as a Coprocessor (see |
| <a href="ConstraintProcessor.html" title="class in org.apache.hadoop.hbase.constraint"><code>ConstraintProcessor</code></a> if you are interested). |
| <h2><a name="usage">Example usage</a></h2> First, you must define a |
| <a href="Constraint.html" title="interface in org.apache.hadoop.hbase.constraint"><code>Constraint</code></a>. The best way to do this is to extend |
| <a href="BaseConstraint.html" title="class in org.apache.hadoop.hbase.constraint"><code>BaseConstraint</code></a>, which takes care of some of the more |
| mundane details of using a <a href="Constraint.html" title="interface in org.apache.hadoop.hbase.constraint"><code>Constraint</code></a>. |
| <p/> |
| Let's look at one possible implementation of a constraint - an IntegerConstraint(there are also |
| several simple examples in the tests). The IntegerConstraint checks to make sure that the value |
| is a String-encoded <code>int</code>. It is really simple to implement this kind of constraint, |
| the only method needs to be implemented is |
| <a href="Constraint.html#check(org.apache.hadoop.hbase.client.Put)"><code>Constraint.check(org.apache.hadoop.hbase.client.Put)</code></a>: |
| <div style="background-color: #cccccc; padding: 2px"> <blockquote> |
| |
| <pre> |
| public class IntegerConstraint extends BaseConstraint { |
| public void check(Put p) throws ConstraintException { |
| |
| Map<byte[], List<KeyValue>> familyMap = p.getFamilyMap(); |
| |
| for (List <KeyValue> kvs : familyMap.values()) { |
| for (KeyValue kv : kvs) { |
| |
| // just make sure that we can actually pull out an int |
| // this will automatically throw a NumberFormatException if we try to |
| // store something that isn't an Integer. |
| |
| try { |
| Integer.parseInt(new String(kv.getValue())); |
| } catch (NumberFormatException e) { |
| throw new ConstraintException("Value in Put (" + p |
| + ") was not a String-encoded integer", e); |
| } } } |
| </pre> |
| |
| </blockquote> </div> |
| <p/> |
| Note that all exceptions that you expect to be thrown must be caught and then rethrown as a |
| <a href="ConstraintException.html" title="class in org.apache.hadoop.hbase.constraint"><code>ConstraintException</code></a>. This way, you can be sure that a |
| <a href="../client/Put.html" title="class in org.apache.hadoop.hbase.client"><code>Put</code></a> fails for an expected reason, rather than for any |
| reason. For example, an <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/OutOfMemoryError.html" title="class or interface in java.lang" class="external-link"><code>OutOfMemoryError</code></a> is probably indicative of an inherent |
| problem in the <a href="Constraint.html" title="interface in org.apache.hadoop.hbase.constraint"><code>Constraint</code></a>, rather than a failed |
| <a href="../client/Put.html" title="class in org.apache.hadoop.hbase.client"><code>Put</code></a>. |
| <p/> |
| If an unexpected exception is thrown (for example, any kind of uncaught |
| <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/RuntimeException.html" title="class or interface in java.lang" class="external-link"><code>RuntimeException</code></a>), constraint-checking will be 'unloaded' from the regionserver |
| where that error occurred. This means no further |
| <a href="Constraint.html" title="interface in org.apache.hadoop.hbase.constraint"><code>Constraints</code></a> will be checked on that server |
| until it is reloaded. This is done to ensure the system remains as available as possible. |
| Therefore, be careful when writing your own Constraint. |
| <p/> |
| So now that we have a Constraint, we want to add it to a table. It's as easy as: |
| <div style="background-color: #cccccc; padding: 2px"> <blockquote> |
| |
| <pre> |
| TableDescriptor builder = TableDescriptorBuilder.newBuilder(TABLE_NAME); |
| ... |
| Constraints.add(builder, IntegerConstraint.class); |
| </pre> |
| |
| </blockquote></div> |
| <p/> |
| Once we added the IntegerConstraint, constraints will be enabled on the table (once it is |
| created) and we will always check to make sure that the value is an String-encoded integer. |
| <p/> |
| However, suppose we also write our own constraint, <code>MyConstraint.java</code>. First, you |
| need to make sure this class-files are in the classpath (in a jar) on the regionserver where that |
| constraint will be run (this could require a rolling restart on the region server - see |
| <a href="#caveats">Caveats</a> above) |
| <p/> |
| Suppose that MyConstraint also uses a Configuration (see |
| <code>Configurable.getConf()</code>). Then adding MyConstraint looks |
| like this: <div style="background-color: #cccccc; padding: 2px"> <blockquote> |
| |
| <pre> |
| TableDescriptor builder = TableDescriptorBuilder.newBuilder(TABLE_NAME); |
| Configuration conf = new Configuration(false); |
| ... |
| (add values to the conf) |
| (modify the table descriptor) |
| ... |
| Constraints.add(builder, new Pair(MyConstraint.class, conf)); |
| </pre> |
| |
| </blockquote></div> |
| <p/> |
| At this point we added both the IntegerConstraint and MyConstraint to the table, the |
| IntegerConstraint <i>will be run first</i>, followed by MyConstraint. |
| <p/> |
| Suppose we realize that the <code>Configuration</code> for MyConstraint is |
| actually wrong when it was added to the table. Note, when it is added to the table, it is |
| <i>not</i> added by reference, but is instead copied into the |
| <a href="../client/TableDescriptor.html" title="interface in org.apache.hadoop.hbase.client"><code>TableDescriptor</code></a>. Thus, to change the |
| <code>Configuration</code> we are using for MyConstraint, we need to do this: |
| <div style="background-color: #cccccc; padding: 2px"> <blockquote> |
| |
| <pre> |
| (add/modify the conf) |
| ... |
| Constraints.setConfiguration(desc, MyConstraint.class, conf); |
| </pre> |
| |
| </blockquote></div> |
| <p/> |
| This will overwrite the previous configuration for MyConstraint, but <i>not</i> change the order |
| of the constraint nor if it is enabled/disabled. |
| <p/> |
| Note that the same constraint class can be added multiple times to a table without repercussion. |
| A use case for this is the same constraint working differently based on its configuration. |
| <p/> |
| Suppose then we want to disable <i>just</i> MyConstraint. Its as easy as: |
| <div style="background-color: #cccccc"> <blockquote> |
| |
| <pre> |
| Constraints.disable(desc, MyConstraint.class); |
| </pre> |
| |
| </blockquote></div> |
| <p/> |
| This just turns off MyConstraint, but retains the position and the configuration associated with |
| MyConstraint. Now, if we want to re-enable the constraint, its just another one-liner: |
| <div style="background-color: #cccccc"> <blockquote> |
| |
| <pre> |
| Constraints.enable(desc, MyConstraint.class); |
| </pre> |
| |
| </blockquote></div> |
| <p/> |
| Similarly, constraints on the entire table are disabled via: |
| <div style="background-color: #cccccc"> <blockquote> |
| |
| <pre> |
| Constraints.disable(desc); |
| </pre> |
| |
| </blockquote></div> |
| <p/> |
| Or enabled via: <div style="background-color: #cccccc"> <blockquote> |
| |
| <pre> |
| Constraints.enable(desc); |
| </pre> |
| |
| </blockquote></div> |
| <p/> |
| Lastly, suppose you want to remove MyConstraint from the table, including with position it should |
| be run at and its configuration. This is similarly simple: |
| <div style="background-color: #cccccc"> <blockquote> |
| |
| <pre> |
| Constraints.remove(desc, MyConstraint.class); |
| </pre> |
| |
| </blockquote></div> |
| <p/> |
| Also, removing <i>all</i> constraints from a table is similarly simple: |
| <div style="background-color: #cccccc"> <blockquote> |
| |
| <pre> |
| Constraints.remove(desc); |
| </pre> |
| |
| </blockquote></div> This will remove all constraints (and associated information) from the table |
| and turn off the constraint processing. |
| <p/> |
| <b>NOTE</b> |
| <p/> |
| It is important to note the use above of <div style="background-color: #cccccc"> <blockquote> |
| |
| <pre> |
| Configuration conf = new Configuration(false); |
| </pre> |
| |
| </blockquote></div> If you just use <code> new Configuration()</code>, then the Configuration |
| will be loaded with the default properties. While in the simple case, this is not going to be an |
| issue, it will cause pain down the road. First, these extra properties are going to cause serious |
| bloat in your <a href="../client/TableDescriptor.html" title="interface in org.apache.hadoop.hbase.client"><code>TableDescriptor</code></a>, meaning you are keeping |
| around a ton of redundant information. Second, it is going to make examining your table in the |
| shell, via <code>describe 'table'</code>, a huge pain as you will have to dig through a ton of |
| irrelevant config values to find the ones you set. In short, just do it the right way.</div> |
| </section> |
| <section class="summary"> |
| <ul class="summary-list"> |
| <li> |
| <div id="related-package-summary"> |
| <div class="caption"><span>Related Packages</span></div> |
| <div class="summary-table two-column-summary"> |
| <div class="table-header col-first">Package</div> |
| <div class="table-header col-last">Description</div> |
| <div class="col-first even-row-color"><a href="../package-summary.html">org.apache.hadoop.hbase</a></div> |
| <div class="col-last even-row-color"> </div> |
| </div> |
| </div> |
| </li> |
| <li> |
| <div id="class-summary"> |
| <div class="table-tabs" role="tablist" aria-orientation="horizontal"><button id="class-summary-tab0" role="tab" aria-selected="true" aria-controls="class-summary.tabpanel" tabindex="0" onkeydown="switchTab(event)" onclick="show('class-summary', 'class-summary', 2)" class="active-table-tab">All Classes and Interfaces</button><button id="class-summary-tab1" role="tab" aria-selected="false" aria-controls="class-summary.tabpanel" tabindex="-1" onkeydown="switchTab(event)" onclick="show('class-summary', 'class-summary-tab1', 2)" class="table-tab">Interfaces</button><button id="class-summary-tab2" role="tab" aria-selected="false" aria-controls="class-summary.tabpanel" tabindex="-1" onkeydown="switchTab(event)" onclick="show('class-summary', 'class-summary-tab2', 2)" class="table-tab">Classes</button><button id="class-summary-tab5" role="tab" aria-selected="false" aria-controls="class-summary.tabpanel" tabindex="-1" onkeydown="switchTab(event)" onclick="show('class-summary', 'class-summary-tab5', 2)" class="table-tab">Exceptions</button></div> |
| <div id="class-summary.tabpanel" role="tabpanel"> |
| <div class="summary-table two-column-summary" aria-labelledby="class-summary-tab0"> |
| <div class="table-header col-first">Class</div> |
| <div class="table-header col-last">Description</div> |
| <div class="col-first even-row-color class-summary class-summary-tab2"><a href="BaseConstraint.html" title="class in org.apache.hadoop.hbase.constraint">BaseConstraint</a></div> |
| <div class="col-last even-row-color class-summary class-summary-tab2"> |
| <div class="block">Base class to use when actually implementing a <a href="Constraint.html" title="interface in org.apache.hadoop.hbase.constraint"><code>Constraint</code></a>.</div> |
| </div> |
| <div class="col-first odd-row-color class-summary class-summary-tab1"><a href="Constraint.html" title="interface in org.apache.hadoop.hbase.constraint">Constraint</a></div> |
| <div class="col-last odd-row-color class-summary class-summary-tab1"> |
| <div class="block">Apply a <a href="Constraint.html" title="interface in org.apache.hadoop.hbase.constraint"><code>Constraint</code></a> (in traditional database terminology) to a Table.</div> |
| </div> |
| <div class="col-first even-row-color class-summary class-summary-tab5"><a href="ConstraintException.html" title="class in org.apache.hadoop.hbase.constraint">ConstraintException</a></div> |
| <div class="col-last even-row-color class-summary class-summary-tab5"> |
| <div class="block">Exception that a user defined constraint throws on failure of a |
| <a href="../client/Put.html" title="class in org.apache.hadoop.hbase.client"><code>Put</code></a>.</div> |
| </div> |
| <div class="col-first odd-row-color class-summary class-summary-tab2"><a href="ConstraintProcessor.html" title="class in org.apache.hadoop.hbase.constraint">ConstraintProcessor</a></div> |
| <div class="col-last odd-row-color class-summary class-summary-tab2"> |
| <div class="block">Processes multiple <a href="Constraint.html" title="interface in org.apache.hadoop.hbase.constraint"><code>Constraints</code></a> on a given table.</div> |
| </div> |
| <div class="col-first even-row-color class-summary class-summary-tab2"><a href="Constraints.html" title="class in org.apache.hadoop.hbase.constraint">Constraints</a></div> |
| <div class="col-last even-row-color class-summary class-summary-tab2"> |
| <div class="block">Utilities for adding/removing constraints from a table.</div> |
| </div> |
| </div> |
| </div> |
| </div> |
| </li> |
| </ul> |
| </section> |
| </main> |
| <footer role="contentinfo"> |
| <hr> |
| <p class="legal-copy"><small>Copyright © 2007–2020 <a href="https://www.apache.org/">The Apache Software Foundation</a>. All rights reserved.</small></p> |
| </footer> |
| </div> |
| </div> |
| </body> |
| </html> |