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
parent
5925440d6a
commit
e602f067ad
|
@ -111,4 +111,8 @@ message Namespace {
|
||||||
|
|
||||||
// The maximum number of columns a table belonging to this namespace may have.
|
// The maximum number of columns a table belonging to this namespace may have.
|
||||||
int32 max_columns_per_table = 5;
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ fn namespace_to_proto(namespace: Namespace) -> proto::Namespace {
|
||||||
retention_period_ns: namespace.retention_period_ns,
|
retention_period_ns: namespace.retention_period_ns,
|
||||||
max_tables: namespace.max_tables,
|
max_tables: namespace.max_tables,
|
||||||
max_columns_per_table: namespace.max_columns_per_table,
|
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,
|
retention_period_ns: TEST_RETENTION_PERIOD_NS,
|
||||||
max_tables: TEST_MAX_TABLES,
|
max_tables: TEST_MAX_TABLES,
|
||||||
max_columns_per_table: TEST_MAX_COLUMNS_PER_TABLE,
|
max_columns_per_table: TEST_MAX_COLUMNS_PER_TABLE,
|
||||||
|
partition_template: None,
|
||||||
},
|
},
|
||||||
proto::Namespace {
|
proto::Namespace {
|
||||||
id: 2,
|
id: 2,
|
||||||
|
@ -193,6 +195,7 @@ mod tests {
|
||||||
retention_period_ns: TEST_RETENTION_PERIOD_NS,
|
retention_period_ns: TEST_RETENTION_PERIOD_NS,
|
||||||
max_tables: TEST_MAX_TABLES,
|
max_tables: TEST_MAX_TABLES,
|
||||||
max_columns_per_table: TEST_MAX_COLUMNS_PER_TABLE,
|
max_columns_per_table: TEST_MAX_COLUMNS_PER_TABLE,
|
||||||
|
partition_template: None,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -265,6 +265,7 @@ fn namespace_to_proto(namespace: CatalogNamespace) -> Namespace {
|
||||||
retention_period_ns: namespace.retention_period_ns,
|
retention_period_ns: namespace.retention_period_ns,
|
||||||
max_tables: namespace.max_tables,
|
max_tables: namespace.max_tables,
|
||||||
max_columns_per_table: namespace.max_columns_per_table,
|
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,
|
retention_period_ns: namespace.retention_period_ns,
|
||||||
max_tables: namespace.max_tables,
|
max_tables: namespace.max_tables,
|
||||||
max_columns_per_table: namespace.max_columns_per_table,
|
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 std::time::Duration;
|
||||||
|
|
||||||
use assert_matches::assert_matches;
|
use assert_matches::assert_matches;
|
||||||
|
use data_types::partition_template::PARTITION_BY_DAY_PROTO;
|
||||||
use generated_types::influxdata::iox::{
|
use generated_types::influxdata::iox::{
|
||||||
namespace::v1::namespace_service_server::NamespaceService as _,
|
namespace::v1::namespace_service_server::NamespaceService as _,
|
||||||
partition_template::v1::PartitionTemplate,
|
partition_template::v1::PartitionTemplate,
|
||||||
|
@ -396,6 +399,7 @@ mod tests {
|
||||||
.expect("no namespace in response");
|
.expect("no namespace in response");
|
||||||
assert_eq!(created_ns.name, NS_NAME);
|
assert_eq!(created_ns.name, NS_NAME);
|
||||||
assert_eq!(created_ns.retention_period_ns, Some(RETENTION));
|
assert_eq!(created_ns.retention_period_ns, Some(RETENTION));
|
||||||
|
assert_eq!(created_ns.partition_template, None);
|
||||||
|
|
||||||
// There should now be one namespace
|
// There should now be one namespace
|
||||||
{
|
{
|
||||||
|
@ -425,6 +429,7 @@ mod tests {
|
||||||
assert_eq!(updated_ns.id, created_ns.id);
|
assert_eq!(updated_ns.id, created_ns.id);
|
||||||
assert_eq!(created_ns.retention_period_ns, Some(RETENTION));
|
assert_eq!(created_ns.retention_period_ns, Some(RETENTION));
|
||||||
assert_eq!(updated_ns.retention_period_ns, None);
|
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
|
// Listing the namespaces should return the updated namespace
|
||||||
{
|
{
|
||||||
|
@ -547,6 +552,45 @@ mod tests {
|
||||||
assert_eq!(all_namespaces.len(), 1);
|
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]
|
#[tokio::test]
|
||||||
async fn invalid_custom_namespace_template_returns_error() {
|
async fn invalid_custom_namespace_template_returns_error() {
|
||||||
let catalog: Arc<dyn Catalog> =
|
let catalog: Arc<dyn Catalog> =
|
||||||
|
|
Loading…
Reference in New Issue