CDAP HBase SPI providing abstraction for HBase DDL operations within the CDAP platform
npx @tessl/cli install tessl/maven-io-cdap-cdap--cdap-hbase-spi@6.10.0The CDAP HBase SPI (Service Provider Interface) provides abstraction for HBase DDL operations within the CDAP platform. It defines interfaces and descriptors for managing HBase tables, namespaces, column families, and coprocessors through a standardized API with idempotent operations.
<dependency>
<groupId>io.cdap.cdap</groupId>
<artifactId>cdap-hbase-spi</artifactId>
<version>6.10.1</version>
</dependency>import io.cdap.cdap.spi.hbase.HBaseDDLExecutor;
import io.cdap.cdap.spi.hbase.HBaseDDLExecutorContext;
import io.cdap.cdap.spi.hbase.TableDescriptor;
import io.cdap.cdap.spi.hbase.ColumnFamilyDescriptor;
import io.cdap.cdap.spi.hbase.CoprocessorDescriptor;
import javax.annotation.Nullable;
import java.io.Closeable;
import java.io.IOException;
import java.util.Map;
import java.util.Set;import io.cdap.cdap.spi.hbase.*;
import java.util.*;
// Implement the HBaseDDLExecutor interface
public class MyHBaseDDLExecutor implements HBaseDDLExecutor {
@Override
public void initialize(HBaseDDLExecutorContext context) {
// Initialize with context
Map<String, String> properties = context.getProperties();
// Use configuration and properties
}
@Override
public boolean createNamespaceIfNotExists(String name) throws IOException {
// Create namespace implementation
return true;
}
// ... implement other methods
}
// Create table descriptor
Set<ColumnFamilyDescriptor> families = new HashSet<>();
families.add(new ColumnFamilyDescriptor(
"cf1",
1,
ColumnFamilyDescriptor.CompressionType.SNAPPY,
ColumnFamilyDescriptor.BloomType.ROW,
Collections.emptyMap()
));
TableDescriptor tableDescriptor = new TableDescriptor(
"my_namespace",
"my_table",
families,
Collections.emptySet(),
Collections.emptyMap()
);The CDAP HBase SPI is organized around key components:
Core interface providing idempotent HBase Data Definition Language operations for namespaces, tables, and permissions.
public interface HBaseDDLExecutor extends Closeable {
void initialize(HBaseDDLExecutorContext context);
boolean createNamespaceIfNotExists(String name) throws IOException;
void deleteNamespaceIfExists(String name) throws IOException;
void createTableIfNotExists(TableDescriptor descriptor, @Nullable byte[][] splitKeys) throws IOException;
void enableTableIfDisabled(String namespace, String name) throws IOException;
void disableTableIfEnabled(String namespace, String name) throws IOException;
void modifyTable(String namespace, String name, TableDescriptor descriptor) throws IOException;
void truncateTable(String namespace, String name) throws IOException;
void deleteTableIfExists(String namespace, String name) throws IOException;
void grantPermissions(String namespace, @Nullable String table, Map<String, String> permissions) throws IOException;
}Context interface providing configuration and properties to HBase DDL executors.
public interface HBaseDDLExecutorContext {
<T> T getConfiguration();
Map<String, String> getProperties();
}Immutable descriptor class that defines HBase table structure including column families and coprocessors.
public final class TableDescriptor {
public TableDescriptor(String namespace, String name, Set<ColumnFamilyDescriptor> families,
Set<CoprocessorDescriptor> coprocessors, Map<String, String> properties);
public String getNamespace();
public String getName();
public Map<String, ColumnFamilyDescriptor> getFamilies();
public Map<String, CoprocessorDescriptor> getCoprocessors();
public Map<String, String> getProperties();
}Immutable descriptor class defining HBase column family properties including compression and bloom filters.
public final class ColumnFamilyDescriptor {
public ColumnFamilyDescriptor(String name, int maxVersions, CompressionType compressionType,
BloomType bloomType, Map<String, String> properties);
public String getName();
public int getMaxVersions();
public CompressionType getCompressionType();
public BloomType getBloomType();
public Map<String, String> getProperties();
public enum CompressionType { LZO, SNAPPY, GZIP, NONE }
public enum BloomType { ROW, ROWCOL, NONE }
}Immutable descriptor class defining HBase coprocessor configuration including class name, path, and priority.
public final class CoprocessorDescriptor {
public CoprocessorDescriptor(String className, @Nullable String path, int priority,
Map<String, String> properties);
public String getClassName();
@Nullable public String getPath();
public int getPriority();
public Map<String, String> getProperties();
}All HBaseDDLExecutor methods throw IOException for remote or network exceptions. Additionally:
deleteNamespaceIfExists() throws IllegalStateException if there are tables in the namespacemodifyTable(), truncateTable(), and deleteTableIfExists() throw IllegalStateException if the table is not disabled// Create column family with compression and bloom filter
ColumnFamilyDescriptor dataFamily = new ColumnFamilyDescriptor(
"data",
3, // max versions
ColumnFamilyDescriptor.CompressionType.SNAPPY,
ColumnFamilyDescriptor.BloomType.ROW,
Collections.emptyMap()
);
ColumnFamilyDescriptor metaFamily = new ColumnFamilyDescriptor(
"meta",
1, // max versions
ColumnFamilyDescriptor.CompressionType.GZIP,
ColumnFamilyDescriptor.BloomType.NONE,
Collections.emptyMap()
);
Set<ColumnFamilyDescriptor> families = new HashSet<>();
families.add(dataFamily);
families.add(metaFamily);
// Create table descriptor
TableDescriptor descriptor = new TableDescriptor(
"analytics",
"user_events",
families,
Collections.emptySet(), // no coprocessors
Collections.singletonMap("MAX_FILESIZE", "10737418240") // 10GB
);
// Create table with split keys
byte[][] splitKeys = {
"2023".getBytes(),
"2024".getBytes(),
"2025".getBytes()
};
executor.createTableIfNotExists(descriptor, splitKeys);// Define coprocessor
CoprocessorDescriptor auditProcessor = new CoprocessorDescriptor(
"com.company.hbase.AuditCoprocessor",
"/path/to/audit-coprocessor.jar",
1000, // priority
Collections.singletonMap("audit.enabled", "true")
);
Set<CoprocessorDescriptor> coprocessors = new HashSet<>();
coprocessors.add(auditProcessor);
// Create table with coprocessor
TableDescriptor descriptor = new TableDescriptor(
"audit",
"access_log",
families,
coprocessors,
Collections.emptyMap()
);
executor.createTableIfNotExists(descriptor, null);// Grant permissions to users and groups
Map<String, String> permissions = new HashMap<>();
permissions.put("alice", "rw"); // read/write for user alice
permissions.put("@admins", "arwxc"); // all permissions for admins group
permissions.put("@readers", "r"); // read-only for readers group
// Grant table-level permissions
executor.grantPermissions("analytics", "user_events", permissions);
// Grant namespace-level permissions
executor.grantPermissions("analytics", null, permissions);// Standard table modification workflow
String namespace = "analytics";
String tableName = "user_events";
// 1. Disable table
executor.disableTableIfEnabled(namespace, tableName);
// 2. Modify table structure
executor.modifyTable(namespace, tableName, newDescriptor);
// 3. Re-enable table
executor.enableTableIfDisabled(namespace, tableName);
// Truncate table (handles disable/enable internally)
executor.truncateTable(namespace, tableName);
// Delete table (requires table to be disabled first)
executor.disableTableIfEnabled(namespace, tableName);
executor.deleteTableIfExists(namespace, tableName);