feat(namespace): Return namespace custom partition templates to API

This exposes the custom partitionining scheme of a namespace (if any)
in the response to namespace create and list calls.
pull/24376/head
Fraser Savage 2023-08-30 11:56:58 +01:00
parent 5925440d6a
commit e602f067ad
No known key found for this signature in database
GPG Key ID: DE47C33CE8C5C446
3 changed files with 51 additions and 0 deletions

View File

@ -111,4 +111,8 @@ message Namespace {
// The maximum number of columns a table belonging to this namespace may have.
int32 max_columns_per_table = 5;
// The default partitioning scheme used for any new tables that are created
// in this namespace, if any.
optional influxdata.iox.partition_template.v1.PartitionTemplate partition_template = 6;
}

View File

@ -38,6 +38,7 @@ fn namespace_to_proto(namespace: Namespace) -> proto::Namespace {
retention_period_ns: namespace.retention_period_ns,
max_tables: namespace.max_tables,
max_columns_per_table: namespace.max_columns_per_table,
partition_template: namespace.partition_template.as_proto().cloned(),
}
}
@ -186,6 +187,7 @@ mod tests {
retention_period_ns: TEST_RETENTION_PERIOD_NS,
max_tables: TEST_MAX_TABLES,
max_columns_per_table: TEST_MAX_COLUMNS_PER_TABLE,
partition_template: None,
},
proto::Namespace {
id: 2,
@ -193,6 +195,7 @@ mod tests {
retention_period_ns: TEST_RETENTION_PERIOD_NS,
max_tables: TEST_MAX_TABLES,
max_columns_per_table: TEST_MAX_COLUMNS_PER_TABLE,
partition_template: None,
},
]
}

View File

@ -265,6 +265,7 @@ fn namespace_to_proto(namespace: CatalogNamespace) -> Namespace {
retention_period_ns: namespace.retention_period_ns,
max_tables: namespace.max_tables,
max_columns_per_table: namespace.max_columns_per_table,
partition_template: namespace.partition_template.as_proto().cloned(),
}
}
@ -276,6 +277,7 @@ fn namespace_to_create_response_proto(namespace: CatalogNamespace) -> CreateName
retention_period_ns: namespace.retention_period_ns,
max_tables: namespace.max_tables,
max_columns_per_table: namespace.max_columns_per_table,
partition_template: namespace.partition_template.as_proto().cloned(),
}),
}
}
@ -311,6 +313,7 @@ mod tests {
use std::time::Duration;
use assert_matches::assert_matches;
use data_types::partition_template::PARTITION_BY_DAY_PROTO;
use generated_types::influxdata::iox::{
namespace::v1::namespace_service_server::NamespaceService as _,
partition_template::v1::PartitionTemplate,
@ -396,6 +399,7 @@ mod tests {
.expect("no namespace in response");
assert_eq!(created_ns.name, NS_NAME);
assert_eq!(created_ns.retention_period_ns, Some(RETENTION));
assert_eq!(created_ns.partition_template, None);
// There should now be one namespace
{
@ -425,6 +429,7 @@ mod tests {
assert_eq!(updated_ns.id, created_ns.id);
assert_eq!(created_ns.retention_period_ns, Some(RETENTION));
assert_eq!(updated_ns.retention_period_ns, None);
assert_eq!(created_ns.partition_template, updated_ns.partition_template);
// Listing the namespaces should return the updated namespace
{
@ -547,6 +552,45 @@ mod tests {
assert_eq!(all_namespaces.len(), 1);
}
#[tokio::test]
async fn custom_namespace_template_returned_in_responses() {
let catalog: Arc<dyn Catalog> =
Arc::new(MemCatalog::new(Arc::new(metric::Registry::default())));
let handler = NamespaceService::new(Arc::clone(&catalog));
// Ensure the create reponse feeds back the partition template
let req = CreateNamespaceRequest {
name: NS_NAME.to_string(),
retention_period_ns: None,
partition_template: Some(PARTITION_BY_DAY_PROTO.as_ref().clone()),
service_protection_limits: None,
};
let created_ns = handler
.create_namespace(Request::new(req))
.await
.expect("failed to create namespace")
.into_inner()
.namespace
.expect("no namespace in response");
assert_eq!(created_ns.name, NS_NAME);
assert_eq!(created_ns.retention_period_ns, None);
assert_eq!(
created_ns.partition_template,
Some(PARTITION_BY_DAY_PROTO.as_ref().clone())
);
// And then make sure that a list call will include the details.
let listed_ns = handler
.get_namespaces(Request::new(Default::default()))
.await
.expect("must return namespaces")
.into_inner()
.namespaces;
assert_matches!(listed_ns.as_slice(), [listed_ns] => {
assert_eq!(listed_ns.partition_template, Some(PARTITION_BY_DAY_PROTO.as_ref().clone()));
})
}
#[tokio::test]
async fn invalid_custom_namespace_template_returns_error() {
let catalog: Arc<dyn Catalog> =