From e602f067adc63b86fad69f6669318c264d36790d Mon Sep 17 00:00:00 2001 From: Fraser Savage Date: Wed, 30 Aug 2023 11:56:58 +0100 Subject: [PATCH] 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. --- .../influxdata/iox/namespace/v1/service.proto | 4 ++ ioxd_querier/src/rpc/namespace.rs | 3 ++ service_grpc_namespace/src/lib.rs | 44 +++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/generated_types/protos/influxdata/iox/namespace/v1/service.proto b/generated_types/protos/influxdata/iox/namespace/v1/service.proto index f629ac4995..ff1ed74427 100644 --- a/generated_types/protos/influxdata/iox/namespace/v1/service.proto +++ b/generated_types/protos/influxdata/iox/namespace/v1/service.proto @@ -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; } diff --git a/ioxd_querier/src/rpc/namespace.rs b/ioxd_querier/src/rpc/namespace.rs index 03f6e24399..c63ca9a309 100644 --- a/ioxd_querier/src/rpc/namespace.rs +++ b/ioxd_querier/src/rpc/namespace.rs @@ -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, }, ] } diff --git a/service_grpc_namespace/src/lib.rs b/service_grpc_namespace/src/lib.rs index 5a57987a42..90646eeb20 100644 --- a/service_grpc_namespace/src/lib.rs +++ b/service_grpc_namespace/src/lib.rs @@ -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 = + 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 =