blob: 6d75019abf35bdd9341b8e2049e96fe23a1d0262 [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>org.apache.hadoop.hbase.client.coprocessor (Apache HBase 3.0.0-alpha-2-SNAPSHOT API)</title>
<link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">
<script type="text/javascript" src="../../../../../../script.js"></script>
</head>
<body>
<script type="text/javascript"><!--
try {
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="org.apache.hadoop.hbase.client.coprocessor (Apache HBase 3.0.0-alpha-2-SNAPSHOT API)";
}
}
catch(err) {
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a name="navbar.top">
<!-- -->
</a>
<div class="skipNav"><a href="#skip.navbar.top" title="Skip navigation links">Skip navigation links</a></div>
<a name="navbar.top.firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../../../../overview-summary.html">Overview</a></li>
<li class="navBarCell1Rev">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">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="../../../../../../org/apache/hadoop/hbase/client/backoff/package-summary.html">Prev&nbsp;Package</a></li>
<li><a href="../../../../../../org/apache/hadoop/hbase/client/example/package-summary.html">Next&nbsp;Package</a></li>
</ul>
<ul class="navList">
<li><a href="../../../../../../index.html?org/apache/hadoop/hbase/client/coprocessor/package-summary.html" target="_top">Frames</a></li>
<li><a href="package-summary.html" target="_top">No&nbsp;Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_top">
<li><a href="../../../../../../allclasses-noframe.html">All&nbsp;Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip.navbar.top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
<div class="header">
<h1 title="Package" class="title">Package&nbsp;org.apache.hadoop.hbase.client.coprocessor</h1>
<div class="docSummary">
<div class="block">Provides client classes for invoking Coprocessor RPC protocols
<a href="#overview">Overview</a>
<a href="#usage">Example Usage</a>
</div>
</div>
<p>See:&nbsp;<a href="#package.description">Description</a></p>
</div>
<div class="contentContainer">
<ul class="blockList">
<li class="blockList">
<table class="typeSummary" border="0" cellpadding="3" cellspacing="0" summary="Interface Summary table, listing interfaces, and an explanation">
<caption><span>Interface Summary</span><span class="tabEnd">&nbsp;</span></caption>
<tr>
<th class="colFirst" scope="col">Interface</th>
<th class="colLast" scope="col">Description</th>
</tr>
<tbody>
<tr class="altColor">
<td class="colFirst"><a href="../../../../../../org/apache/hadoop/hbase/client/coprocessor/Batch.Call.html" title="interface in org.apache.hadoop.hbase.client.coprocessor">Batch.Call</a>&lt;T,R&gt;</td>
<td class="colLast">
<div class="block">Defines a unit of work to be executed.</div>
</td>
</tr>
<tr class="rowColor">
<td class="colFirst"><a href="../../../../../../org/apache/hadoop/hbase/client/coprocessor/Batch.Callback.html" title="interface in org.apache.hadoop.hbase.client.coprocessor">Batch.Callback</a>&lt;R&gt;</td>
<td class="colLast">
<div class="block">Defines a generic callback to be triggered for each <a href="../../../../../../org/apache/hadoop/hbase/client/coprocessor/Batch.Call.html#call-T-"><code>Batch.Call.call(Object)</code></a> result.</div>
</td>
</tr>
</tbody>
</table>
</li>
<li class="blockList">
<table class="typeSummary" border="0" cellpadding="3" cellspacing="0" summary="Class Summary table, listing classes, and an explanation">
<caption><span>Class Summary</span><span class="tabEnd">&nbsp;</span></caption>
<tr>
<th class="colFirst" scope="col">Class</th>
<th class="colLast" scope="col">Description</th>
</tr>
<tbody>
<tr class="altColor">
<td class="colFirst"><a href="../../../../../../org/apache/hadoop/hbase/client/coprocessor/Batch.html" title="class in org.apache.hadoop.hbase.client.coprocessor">Batch</a></td>
<td class="colLast">
<div class="block">A collection of interfaces and utilities used for interacting with custom RPC
interfaces exposed by Coprocessors.</div>
</td>
</tr>
<tr class="rowColor">
<td class="colFirst"><a href="../../../../../../org/apache/hadoop/hbase/client/coprocessor/BigDecimalColumnInterpreter.html" title="class in org.apache.hadoop.hbase.client.coprocessor">BigDecimalColumnInterpreter</a></td>
<td class="colLast">
<div class="block">ColumnInterpreter for doing Aggregation's with BigDecimal columns.</div>
</td>
</tr>
<tr class="altColor">
<td class="colFirst"><a href="../../../../../../org/apache/hadoop/hbase/client/coprocessor/DoubleColumnInterpreter.html" title="class in org.apache.hadoop.hbase.client.coprocessor">DoubleColumnInterpreter</a></td>
<td class="colLast">
<div class="block">a concrete column interpreter implementation.</div>
</td>
</tr>
<tr class="rowColor">
<td class="colFirst"><a href="../../../../../../org/apache/hadoop/hbase/client/coprocessor/LongColumnInterpreter.html" title="class in org.apache.hadoop.hbase.client.coprocessor">LongColumnInterpreter</a></td>
<td class="colLast">
<div class="block">a concrete column interpreter implementation.</div>
</td>
</tr>
</tbody>
</table>
</li>
</ul>
<a name="package.description">
<!-- -->
</a>
<h2 title="Package org.apache.hadoop.hbase.client.coprocessor Description">Package org.apache.hadoop.hbase.client.coprocessor Description</h2>
<div class="block">Provides client classes for invoking Coprocessor RPC protocols
<ul>
<li><a href="#overview">Overview</a></li>
<li><a href="#usage">Example Usage</a></li>
</ul>
<h2><a name="overview">Overview</a></h2>
<p>
The coprocessor framework provides a way for custom code to run in place on the
HBase region servers with each of a table's regions. These client classes
enable applications to communicate with coprocessor instances via custom RPC
protocols.
</p>
<p>
In order to provide a custom RPC protocol to clients, a coprocessor implementation
must:
</p>
<ul>
<li>Define a protocol buffer Service and supporting Message types for the RPC methods.
See the
<a href="https://developers.google.com/protocol-buffers/docs/proto#services">protocol buffer guide</a>
for more details on defining services.</li>
<li>Generate the Service and Message code using the protoc compiler</li>
<li>Implement the generated Service interface in your coprocessor class and implement the
org.apache.hadoop.hbase.coprocessor.CoprocessorService interface. The
org.apache.hadoop.hbase.coprocessor.CoprocessorService#getService()
method should return a reference to the Endpoint's protocol buffer Service instance.
</ul>
<p>
Clients may then call the defined service methods on coprocessor instances via
the <a href="../../../../../../org/apache/hadoop/hbase/client/Table.html#coprocessorService-byte:A-"><code>Table.coprocessorService(byte[])</code></a>,
<a href="../../../../../../org/apache/hadoop/hbase/client/Table.html#coprocessorService-java.lang.Class-byte:A-byte:A-org.apache.hadoop.hbase.client.coprocessor.Batch.Call-"><code>Table.coprocessorService(Class, byte[], byte[], org.apache.hadoop.hbase.client.coprocessor.Batch.Call)</code></a>, and
<a href="../../../../../../org/apache/hadoop/hbase/client/Table.html#coprocessorService-java.lang.Class-byte:A-byte:A-org.apache.hadoop.hbase.client.coprocessor.Batch.Call-org.apache.hadoop.hbase.client.coprocessor.Batch.Callback-"><code>Table.coprocessorService(Class, byte[], byte[], org.apache.hadoop.hbase.client.coprocessor.Batch.Call, org.apache.hadoop.hbase.client.coprocessor.Batch.Callback)</code></a>
methods.
</p>
<p>
Since coprocessor Service instances are associated with individual regions within the table,
the client RPC calls must ultimately identify which regions should be used in the Service
method invocations. Since regions are seldom handled directly in client code
and the region names may change over time, the coprocessor RPC calls use row keys
to identify which regions should be used for the method invocations. Clients
can call coprocessor Service methods against either:
</p>
<ul>
<li><strong>a single region</strong> - calling
<a href="../../../../../../org/apache/hadoop/hbase/client/Table.html#coprocessorService-byte:A-"><code>Table.coprocessorService(byte[])</code></a>
with a single row key. This returns a <a href="../../../../../../org/apache/hadoop/hbase/ipc/CoprocessorRpcChannel.html" title="interface in org.apache.hadoop.hbase.ipc"><code>CoprocessorRpcChannel</code></a>
instance which communicates with the region containing the given row key (even if the
row does not exist) as the RPC endpoint. Clients can then use the <code>CoprocessorRpcChannel</code>
instance in creating a new Service stub to call RPC methods on the region's coprocessor.</li>
<li><strong>a range of regions</strong> - calling
<a href="../../../../../../org/apache/hadoop/hbase/client/Table.html#coprocessorService-java.lang.Class-byte:A-byte:A-org.apache.hadoop.hbase.client.coprocessor.Batch.Call-"><code>Table.coprocessorService(Class, byte[], byte[], org.apache.hadoop.hbase.client.coprocessor.Batch.Call)</code></a>
or <a href="../../../../../../org/apache/hadoop/hbase/client/Table.html#coprocessorService-java.lang.Class-byte:A-byte:A-org.apache.hadoop.hbase.client.coprocessor.Batch.Call-org.apache.hadoop.hbase.client.coprocessor.Batch.Callback-"><code>Table.coprocessorService(Class, byte[], byte[], org.apache.hadoop.hbase.client.coprocessor.Batch.Call, org.apache.hadoop.hbase.client.coprocessor.Batch.Callback)</code></a>
with a starting row key and an ending row key. All regions in the table
from the region containing the start row key to the region containing the end
row key (inclusive), will we used as the RPC endpoints.</li>
</ul>
<p><em>Note that the row keys passed as parameters to the <code>Table</code>
methods are not passed directly to the coprocessor Service implementations.
They are only used to identify the regions for endpoints of the remote calls.
</em></p>
<p>
The <a href="../../../../../../org/apache/hadoop/hbase/client/coprocessor/Batch.html" title="class in org.apache.hadoop.hbase.client.coprocessor"><code>Batch</code></a> class defines two
interfaces used for coprocessor Service invocations against multiple regions. Clients implement
<a href="../../../../../../org/apache/hadoop/hbase/client/coprocessor/Batch.Call.html" title="interface in org.apache.hadoop.hbase.client.coprocessor"><code>Batch.Call</code></a> to call methods of the actual
coprocessor Service instance. The interface's <code>call()</code> method will be called once
per selected region, passing the Service instance for the region as a parameter. Clients
can optionally implement <a href="../../../../../../org/apache/hadoop/hbase/client/coprocessor/Batch.Callback.html" title="interface in org.apache.hadoop.hbase.client.coprocessor"><code>Batch.Callback</code></a>
to be notified of the results from each region invocation as they complete.
The instance's <a href="../../../../../../org/apache/hadoop/hbase/client/coprocessor/Batch.Callback.html#update-byte:A-byte:A-R-"><code>Batch.Callback.update(byte[], byte[], Object)</code></a>
method will be called with the <a href="../../../../../../org/apache/hadoop/hbase/client/coprocessor/Batch.Call.html#call-T-"><code>Batch.Call.call(Object)</code></a>
return value from each region.
</p>
<h2><a name="usage">Example usage</a></h2>
<p>
To start with, let's use a fictitious coprocessor, <code>RowCountEndpoint</code>
that counts the number of rows and key-values in each region where it is running.
For clients to query this information, the coprocessor defines the following protocol buffer
service:
</p>
<div style="background-color: #cccccc; padding: 2px">
<blockquote><pre>
message CountRequest {
}
message CountResponse {
required int64 count = 1 [default = 0];
}
service RowCountService {
rpc getRowCount(CountRequest)
returns (CountResponse);
rpc getKeyValueCount(CountRequest)
returns (CountResponse);
}
</pre></blockquote></div>
<p>
Next run the protoc compiler on the .proto file to generate Java code for the Service interface.
The generated <code>RowCountService</code> interface should look something like:
</p>
<div style="background-color: #cccccc; padding: 2px">
<blockquote><pre>
public static abstract class RowCountService
implements com.google.protobuf.Service {
...
public interface Interface {
public abstract void getRowCount(
com.google.protobuf.RpcController controller,
org.apache.hadoop.hbase.coprocessor.example.generated.ExampleProtos.CountRequest request,
com.google.protobuf.RpcCallback&lt;org.apache.hadoop.hbase.coprocessor.example.generated.ExampleProtos.CountResponse&gt; done);
public abstract void getKeyValueCount(
com.google.protobuf.RpcController controller,
org.apache.hadoop.hbase.coprocessor.example.generated.ExampleProtos.CountRequest request,
com.google.protobuf.RpcCallback&lt;org.apache.hadoop.hbase.coprocessor.example.generated.ExampleProtos.CountResponse&gt; done);
}
}
</pre></blockquote></div>
<p>
Our coprocessor Service will need to implement this interface and the org.apache.hadoop.hbase.coprocessor.CoprocessorService
in order to be registered correctly as an endpoint. For the sake of simplicity the server-side
implementation is omitted. To see the implementing code, please see the
org.apache.hadoop.hbase.coprocessor.example.RowCountEndpoint class in the HBase source code.
</p>
<p>
Now we need a way to access the results that <code>RowCountService</code>
is making available. If we want to find the row count for all regions, we could
use:
</p>
<div style="background-color: #cccccc; padding: 2px">
<blockquote><pre>
Connection connection = ConnectionFactory.createConnection(conf);
Table table = connection.getTable(TableName.valueOf("mytable"));
final ExampleProtos.CountRequest request = ExampleProtos.CountRequest.getDefaultInstance();
Map&lt;byte[],Long&gt; results = table.coprocessorService(
ExampleProtos.RowCountService.class, // the protocol interface we're invoking
null, null, // start and end row keys
new Batch.Call&lt;ExampleProtos.RowCountService,Long&gt;() {
public Long call(ExampleProtos.RowCountService counter) throws IOException {
BlockingRpcCallback&lt;ExampleProtos.CountResponse&gt; rpcCallback =
new BlockingRpcCallback&lt;ExampleProtos.CountResponse&gt;();
counter.getRowCount(null, request, rpcCallback);
ExampleProtos.CountResponse response = rpcCallback.get();
return response.hasCount() ? response.getCount() : 0;
}
});
</pre></blockquote></div>
<p>
This will return a <code>java.util.Map</code> of the <code>counter.getRowCount()</code>
result for the <code>RowCountService</code> instance running in each region
of <code>mytable</code>, keyed by the region name.
</p>
<p>
By implementing <a href="../../../../../../org/apache/hadoop/hbase/client/coprocessor/Batch.Call.html" title="interface in org.apache.hadoop.hbase.client.coprocessor"><code>Batch.Call</code></a>
as an anonymous class, we can invoke <code>RowCountService</code> methods
directly against the <a href="../../../../../../org/apache/hadoop/hbase/client/coprocessor/Batch.Call.html#call-T-"><code>Batch.Call.call(Object)</code></a>
method's argument. Calling <a href="../../../../../../org/apache/hadoop/hbase/client/Table.html#coprocessorService-java.lang.Class-byte:A-byte:A-org.apache.hadoop.hbase.client.coprocessor.Batch.Call-"><code>Table.coprocessorService(Class, byte[], byte[], org.apache.hadoop.hbase.client.coprocessor.Batch.Call)</code></a>
will take care of invoking <code>Batch.Call.call()</code> against our anonymous class
with the <code>RowCountService</code> instance for each table region.
</p>
<p>
Implementing <a href="../../../../../../org/apache/hadoop/hbase/client/coprocessor/Batch.Call.html" title="interface in org.apache.hadoop.hbase.client.coprocessor"><code>Batch.Call</code></a> also allows you to
perform additional processing against each region's Service instance. For example, if you would
like to combine row count and key-value count for each region:
</p>
<div style="background-color: #cccccc; padding: 2px">
<blockquote><pre>
Connection connection = ConnectionFactory.createConnection(conf);
Table table = connection.getTable(TableName.valueOf("mytable"));
// combine row count and kv count for region
final ExampleProtos.CountRequest request = ExampleProtos.CountRequest.getDefaultInstance();
Map&lt;byte[],Long&gt; results = table.coprocessorService(
ExampleProtos.RowCountService.class, // the protocol interface we're invoking
null, null, // start and end row keys
new Batch.Call&lt;ExampleProtos.RowCountService,Pair&lt;Long,Long&gt;&gt;() {
public Long call(ExampleProtos.RowCountService counter) throws IOException {
BlockingRpcCallback&lt;ExampleProtos.CountResponse&gt; rowCallback =
new BlockingRpcCallback&lt;ExampleProtos.CountResponse&gt;();
counter.getRowCount(null, request, rowCallback);
BlockingRpcCallback&lt;ExampleProtos.CountResponse&gt; kvCallback =
new BlockingRpcCallback&lt;ExampleProtos.CountResponse&gt;();
counter.getKeyValueCount(null, request, kvCallback);
ExampleProtos.CountResponse rowResponse = rowCallback.get();
ExampleProtos.CountResponse kvResponse = kvCallback.get();
return new Pair(rowResponse.hasCount() ? rowResponse.getCount() : 0,
kvResponse.hasCount() ? kvResponse.getCount() : 0);
}
});
</pre></blockquote></div></div>
</div>
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a name="navbar.bottom">
<!-- -->
</a>
<div class="skipNav"><a href="#skip.navbar.bottom" title="Skip navigation links">Skip navigation links</a></div>
<a name="navbar.bottom.firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../../../../overview-summary.html">Overview</a></li>
<li class="navBarCell1Rev">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">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="../../../../../../org/apache/hadoop/hbase/client/backoff/package-summary.html">Prev&nbsp;Package</a></li>
<li><a href="../../../../../../org/apache/hadoop/hbase/client/example/package-summary.html">Next&nbsp;Package</a></li>
</ul>
<ul class="navList">
<li><a href="../../../../../../index.html?org/apache/hadoop/hbase/client/coprocessor/package-summary.html" target="_top">Frames</a></li>
<li><a href="package-summary.html" target="_top">No&nbsp;Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="../../../../../../allclasses-noframe.html">All&nbsp;Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_bottom");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<a name="skip.navbar.bottom">
<!-- -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
<p class="legalCopy"><small>Copyright &#169; 2007&#x2013;2021 <a href="https://www.apache.org/">The Apache Software Foundation</a>. All rights reserved.</small></p>
</body>
</html>