Core data management capabilities for CDAP including dataset operations, metadata management, lineage tracking, audit functionality, and data registry services for Hadoop-based applications.
—
Namespace lifecycle management for multi-tenancy support with metadata persistence and comprehensive administrative operations. The NamespaceStore provides essential functionality for managing isolated environments within the CDAP platform, enabling secure multi-tenant deployments with proper resource isolation.
The primary interface for namespace lifecycle management with complete CRUD operations and metadata handling.
public interface NamespaceStore {
// Namespace lifecycle operations
NamespaceMeta create(NamespaceMeta metadata) throws NamespaceAlreadyExistsException;
void update(NamespaceMeta metadata) throws NamespaceNotFoundException;
NamespaceMeta get(NamespaceId id) throws NamespaceNotFoundException;
NamespaceMeta delete(NamespaceId id) throws NamespaceNotFoundException, NamespaceCannotBeDeletedException;
List<NamespaceMeta> list();
// Existence checks
boolean hasNamespace(NamespaceId id);
}Different implementations of the NamespaceStore for various deployment scenarios and storage requirements.
// Default persistent namespace store implementation
public class DefaultNamespaceStore implements NamespaceStore {
// Full-featured namespace management with persistent storage backend
}
// In-memory implementation for testing and development
public class InMemoryNamespaceStore implements NamespaceStore {
// Fast in-memory namespace operations for testing scenarios
}Comprehensive namespace metadata structure with configuration options for resource limits, security, and custom properties.
// Namespace metadata container
public final class NamespaceMeta {
public static Builder builder();
public NamespaceId getNamespaceId();
public String getName();
public String getDescription();
public NamespaceConfig getConfig();
public long getCreationTimeMillis();
public Map<String, String> getProperties();
public static class Builder {
public Builder setName(String name);
public Builder setDescription(String description);
public Builder setConfig(NamespaceConfig config);
public Builder setProperties(Map<String, String> properties);
public Builder setProperty(String key, String value);
public NamespaceMeta build();
}
}
// Namespace configuration options
public final class NamespaceConfig {
public static Builder builder();
public String getSchedulerQueueName();
public String getRootDirectory();
public String getHbaseNamespace();
public String getPrincipal();
public String getKeytabURI();
public Map<String, String> getExploreProperties();
public Map<String, String> getHiveProperties();
public static class Builder {
public Builder setSchedulerQueueName(String queueName);
public Builder setRootDirectory(String rootDirectory);
public Builder setHbaseNamespace(String hbaseNamespace);
public Builder setPrincipal(String principal);
public Builder setKeytabURI(String keytabURI);
public Builder setExploreProperties(Map<String, String> properties);
public Builder setHiveProperties(Map<String, String> properties);
public NamespaceConfig build();
}
}// Access namespace store (typically injected)
NamespaceStore namespaceStore = // ... obtain instance
// Create a new namespace with basic configuration
NamespaceMeta namespaceMeta = NamespaceMeta.builder()
.setName("analytics")
.setDescription("Analytics and data science workspace")
.setProperty("owner", "data-team")
.setProperty("environment", "production")
.setProperty("cost-center", "engineering")
.build();
try {
NamespaceMeta created = namespaceStore.create(namespaceMeta);
System.out.println("Created namespace: " + created.getName());
System.out.println("Creation time: " + new Date(created.getCreationTimeMillis()));
} catch (NamespaceAlreadyExistsException e) {
System.out.println("Namespace already exists: " + e.getMessage());
}
// Retrieve namespace information
NamespaceId namespaceId = NamespaceId.of("analytics");
try {
NamespaceMeta retrieved = namespaceStore.get(namespaceId);
System.out.println("Namespace: " + retrieved.getName());
System.out.println("Description: " + retrieved.getDescription());
System.out.println("Properties: " + retrieved.getProperties());
} catch (NamespaceNotFoundException e) {
System.out.println("Namespace not found: " + e.getMessage());
}
// Check if namespace exists
boolean exists = namespaceStore.hasNamespace(namespaceId);
System.out.println("Namespace exists: " + exists);// Create namespace with comprehensive configuration
NamespaceConfig config = NamespaceConfig.builder()
.setSchedulerQueueName("analytics-queue")
.setRootDirectory("/data/analytics")
.setHbaseNamespace("analytics_hbase")
.setPrincipal("analytics@COMPANY.COM")
.setKeytabURI("file:///etc/security/keytabs/analytics.keytab")
.setExploreProperties(Map.of(
"hive.exec.dynamic.partition", "true",
"hive.exec.dynamic.partition.mode", "nonstrict"
))
.setHiveProperties(Map.of(
"hive.metastore.warehouse.dir", "/data/analytics/warehouse",
"javax.jdo.option.ConnectionURL", "jdbc:mysql://localhost/analytics_metastore"
))
.build();
NamespaceMeta advancedNamespace = NamespaceMeta.builder()
.setName("advanced-analytics")
.setDescription("Advanced analytics environment with custom Hive and HBase configuration")
.setConfig(config)
.setProperty("security-level", "high")
.setProperty("data-classification", "confidential")
.setProperty("backup-enabled", "true")
.setProperty("retention-days", "2555") // 7 years
.build();
try {
namespaceStore.create(advancedNamespace);
System.out.println("Created advanced namespace with custom configuration");
} catch (NamespaceAlreadyExistsException e) {
System.out.println("Advanced namespace already exists");
}// List all namespaces
List<NamespaceMeta> allNamespaces = namespaceStore.list();
System.out.println("Total namespaces: " + allNamespaces.size());
for (NamespaceMeta namespace : allNamespaces) {
System.out.println("Namespace: " + namespace.getName());
System.out.println(" Description: " + namespace.getDescription());
System.out.println(" Created: " + new Date(namespace.getCreationTimeMillis()));
System.out.println(" Properties: " + namespace.getProperties());
if (namespace.getConfig() != null) {
NamespaceConfig config = namespace.getConfig();
System.out.println(" Queue: " + config.getSchedulerQueueName());
System.out.println(" Root Dir: " + config.getRootDirectory());
System.out.println(" HBase Namespace: " + config.getHbaseNamespace());
}
System.out.println();
}
// Filter namespaces by properties
List<NamespaceMeta> productionNamespaces = allNamespaces.stream()
.filter(ns -> "production".equals(ns.getProperties().get("environment")))
.collect(Collectors.toList());
System.out.println("Production namespaces: " + productionNamespaces.size());// Update namespace metadata
NamespaceId namespaceId = NamespaceId.of("analytics");
try {
NamespaceMeta existing = namespaceStore.get(namespaceId);
// Create updated metadata with new properties
NamespaceMeta updated = NamespaceMeta.builder()
.setName(existing.getName())
.setDescription("Updated: Analytics and machine learning workspace")
.setConfig(existing.getConfig())
.setProperties(existing.getProperties())
.setProperty("last-updated", String.valueOf(System.currentTimeMillis()))
.setProperty("updated-by", "admin-user")
.setProperty("version", "2.0")
.build();
namespaceStore.update(updated);
System.out.println("Updated namespace: " + namespaceId.getNamespace());
} catch (NamespaceNotFoundException e) {
System.out.println("Cannot update - namespace not found: " + e.getMessage());
}
// Namespace maintenance operations
public void performNamespaceMaintenance() {
List<NamespaceMeta> namespaces = namespaceStore.list();
for (NamespaceMeta namespace : namespaces) {
// Check if namespace needs cleanup
long creationTime = namespace.getCreationTimeMillis();
long daysSinceCreation = (System.currentTimeMillis() - creationTime) / (1000 * 60 * 60 * 24);
// Add maintenance properties
if (daysSinceCreation > 30) {
NamespaceMeta maintained = NamespaceMeta.builder()
.setName(namespace.getName())
.setDescription(namespace.getDescription())
.setConfig(namespace.getConfig())
.setProperties(namespace.getProperties())
.setProperty("maintenance-check", String.valueOf(System.currentTimeMillis()))
.setProperty("days-active", String.valueOf(daysSinceCreation))
.build();
try {
namespaceStore.update(maintained);
System.out.println("Updated maintenance info for: " + namespace.getName());
} catch (NamespaceNotFoundException e) {
System.out.println("Namespace disappeared during maintenance: " + namespace.getName());
}
}
}
}// Safe namespace deletion with checks
public boolean safeDeleteNamespace(NamespaceId namespaceId) {
try {
// Check if namespace exists
if (!namespaceStore.hasNamespace(namespaceId)) {
System.out.println("Namespace does not exist: " + namespaceId.getNamespace());
return false;
}
// Get namespace info before deletion
NamespaceMeta namespace = namespaceStore.get(namespaceId);
System.out.println("Deleting namespace: " + namespace.getName());
System.out.println("Description: " + namespace.getDescription());
// Perform deletion
NamespaceMeta deleted = namespaceStore.delete(namespaceId);
System.out.println("Successfully deleted namespace: " + deleted.getName());
return true;
} catch (NamespaceNotFoundException e) {
System.out.println("Namespace not found during deletion: " + e.getMessage());
return false;
} catch (NamespaceCannotBeDeletedException e) {
System.out.println("Namespace cannot be deleted: " + e.getMessage());
System.out.println("Reason: " + e.getCause());
return false;
}
}
// Bulk namespace cleanup
public void cleanupTestNamespaces() {
List<NamespaceMeta> namespaces = namespaceStore.list();
for (NamespaceMeta namespace : namespaces) {
// Identify test namespaces
if (namespace.getName().startsWith("test-") ||
"test".equals(namespace.getProperties().get("environment"))) {
NamespaceId namespaceId = NamespaceId.of(namespace.getName());
System.out.println("Cleaning up test namespace: " + namespace.getName());
if (safeDeleteNamespace(namespaceId)) {
System.out.println("Successfully removed test namespace: " + namespace.getName());
}
}
}
}// Create tenant-specific namespaces
public void setupTenantNamespaces(String tenantId, String tenantName) {
// Development namespace
NamespaceMeta devNamespace = NamespaceMeta.builder()
.setName(tenantId + "-dev")
.setDescription("Development environment for " + tenantName)
.setProperty("tenant-id", tenantId)
.setProperty("tenant-name", tenantName)
.setProperty("environment", "development")
.setProperty("data-retention-days", "30")
.build();
// Staging namespace
NamespaceMeta stagingNamespace = NamespaceMeta.builder()
.setName(tenantId + "-staging")
.setDescription("Staging environment for " + tenantName)
.setProperty("tenant-id", tenantId)
.setProperty("tenant-name", tenantName)
.setProperty("environment", "staging")
.setProperty("data-retention-days", "90")
.build();
// Production namespace with advanced configuration
NamespaceConfig prodConfig = NamespaceConfig.builder()
.setSchedulerQueueName(tenantId + "-prod")
.setRootDirectory("/data/tenants/" + tenantId + "/prod")
.setHbaseNamespace(tenantId + "_prod")
.build();
NamespaceMeta prodNamespace = NamespaceMeta.builder()
.setName(tenantId + "-prod")
.setDescription("Production environment for " + tenantName)
.setConfig(prodConfig)
.setProperty("tenant-id", tenantId)
.setProperty("tenant-name", tenantName)
.setProperty("environment", "production")
.setProperty("data-retention-days", "2555") // 7 years
.setProperty("backup-enabled", "true")
.build();
try {
namespaceStore.create(devNamespace);
namespaceStore.create(stagingNamespace);
namespaceStore.create(prodNamespace);
System.out.println("Created tenant namespaces for: " + tenantName);
} catch (NamespaceAlreadyExistsException e) {
System.out.println("Some namespaces already exist for tenant: " + tenantId);
}
}
// Get namespaces for a specific tenant
public List<NamespaceMeta> getTenantNamespaces(String tenantId) {
return namespaceStore.list().stream()
.filter(ns -> tenantId.equals(ns.getProperties().get("tenant-id")))
.collect(Collectors.toList());
}// Core namespace types
public final class NamespaceId extends EntityId {
public static final NamespaceId DEFAULT = new NamespaceId("default");
public static final NamespaceId SYSTEM = new NamespaceId("system");
public static NamespaceId of(String namespace);
public String getNamespace();
// Factory methods for child entities
public ApplicationId app(String application);
public DatasetId dataset(String dataset);
public StreamId stream(String stream);
public DatasetModuleId datasetModule(String module);
public DatasetTypeId datasetType(String type);
}
// Namespace metadata
public final class NamespaceMeta {
public NamespaceId getNamespaceId();
public String getName();
public String getDescription();
public NamespaceConfig getConfig();
public long getCreationTimeMillis();
public Map<String, String> getProperties();
public static Builder builder();
public static class Builder {
public Builder setName(String name);
public Builder setDescription(String description);
public Builder setConfig(NamespaceConfig config);
public Builder setProperties(Map<String, String> properties);
public Builder setProperty(String key, String value);
public NamespaceMeta build();
}
}
// Namespace configuration
public final class NamespaceConfig {
public String getSchedulerQueueName();
public String getRootDirectory();
public String getHbaseNamespace();
public String getPrincipal();
public String getKeytabURI();
public Map<String, String> getExploreProperties();
public Map<String, String> getHiveProperties();
public static Builder builder();
public static class Builder {
public Builder setSchedulerQueueName(String queueName);
public Builder setRootDirectory(String rootDirectory);
public Builder setHbaseNamespace(String hbaseNamespace);
public Builder setPrincipal(String principal);
public Builder setKeytabURI(String keytabURI);
public Builder setExploreProperties(Map<String, String> properties);
public Builder setHiveProperties(Map<String, String> properties);
public NamespaceConfig build();
}
}
// Exception types
public class NamespaceAlreadyExistsException extends Exception {
public NamespaceAlreadyExistsException(String namespace);
public NamespaceAlreadyExistsException(String namespace, Throwable cause);
}
public class NamespaceNotFoundException extends Exception {
public NamespaceNotFoundException(String namespace);
public NamespaceNotFoundException(String namespace, Throwable cause);
}
public class NamespaceCannotBeDeletedException extends Exception {
public NamespaceCannotBeDeletedException(String namespace, String reason);
public NamespaceCannotBeDeletedException(String namespace, String reason, Throwable cause);
}Install with Tessl CLI
npx tessl i tessl/maven-co-cask-cdap--cdap-data-fabric