Kodey Converse created HBASE-29850:
--------------------------------------
Summary: Add support for dynamic per-request attributes in
AsyncTable
Key: HBASE-29850
URL: https://issues.apache.org/jira/browse/HBASE-29850
Project: HBase
Issue Type: Improvement
Components: Client
Reporter: Kodey Converse
Some request attributes are useful to set on a per-request basis rather than
statically on the client. For example, when {{hbase.quota.user.override.key}}
is configured, the corresponding request attribute can override the effective
user for quota/throttling purposes. With dynamic request attributes, users can
set up throttles on arbitrary callers coming into the system.
A use case for this at my company, which we utilize heavily, is propagating the
original caller through HTTP thread metadata when requests jump through
multiple HTTP servers before reaching HBase. This allows throttling the
original caller rather than the service making the HBase call.
For the synchronous {{Table}} interface, it's already possible to generate
request attributes per-request by overriding {{RpcControllerFactory}} and
generating the request attributes dynamically in
{{{}HBaseRpcController.getRequestAttributes(){}}}. However, that doesn't work
with {{{}AsyncTable{}}}, because when requests are retried automatically, the
{{RpcControllerFactory}} is called from within a netty thread and not on the
client's original thread, so the attributes can't reliably use thread locals to
generate the attributes.
This change introduces support for dynamic request attributes by adding a
{{RequestAttributesFactory}} interface. The factory is called on each request,
receives the static attributes configured on the table, and can return
modified/augmented attributes for that specific request.
h3. API Addition
{code:java}
public interface RequestAttributesFactory {
Map<String, byte[]> create(Map<String, byte[]> requestAttributes);
}
// Usage
AsyncTable<?> table = conn.getTableBuilder(tableName)
.setRequestAttributesFactory(attrs -> {
Map<String, byte[]> newAttrs = new HashMap<>(attrs);
newAttrs.put("hbase.user", getCurrentUserFromThreadContext());
return newAttrs;
})
.build();
{code}
The factory is guaranteed to be called on the same thread that initiates the
client call, making it safe to read thread-local context.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)