@@ -3,7 +3,7 @@ use std::collections::BTreeMap;
33use security:: AuthenticationConfig ;
44use serde:: { Deserialize , Serialize } ;
55use shell_escape:: escape;
6- use snafu:: { OptionExt , ResultExt , Snafu } ;
6+ use snafu:: { ResultExt , Snafu } ;
77use stackable_operator:: {
88 builder:: pod:: volume:: {
99 ListenerOperatorVolumeSourceBuilder , ListenerOperatorVolumeSourceBuilderError ,
@@ -19,15 +19,15 @@ use stackable_operator::{
1919 } ,
2020 } ,
2121 config:: {
22- fragment:: { self , Fragment , ValidationError } ,
22+ fragment:: Fragment ,
2323 merge:: { Atomic , Merge } ,
2424 } ,
2525 deep_merger:: ObjectOverrides ,
2626 k8s_openapi:: {
2727 api:: core:: v1:: { EnvVar , PersistentVolumeClaim , Volume } ,
2828 apimachinery:: pkg:: api:: resource:: Quantity ,
2929 } ,
30- kube:: { CustomResource , ResourceExt , runtime:: reflector:: ObjectRef } ,
30+ kube:: { CustomResource , runtime:: reflector:: ObjectRef } ,
3131 kvp:: Labels ,
3232 product_logging:: { self , spec:: Logging } ,
3333 role_utils:: { GenericRoleConfig , Role , RoleGroupRef } ,
@@ -107,18 +107,6 @@ pub type RestServerRoleType =
107107
108108#[ derive( Snafu , Debug ) ]
109109pub enum Error {
110- #[ snafu( display( "the HBase role [{role}] is missing from spec" ) ) ]
111- MissingHbaseRole { role : String } ,
112-
113- #[ snafu( display( "fragment validation failure" ) ) ]
114- FragmentValidationFailure { source : ValidationError } ,
115-
116- #[ snafu( display( "empty values for role-group are not permitted" ) ) ]
117- EmptyRoleGroup ,
118-
119- #[ snafu( display( "role-group not found by name" ) ) ]
120- RoleGroupNotFound ,
121-
122110 #[ snafu( display( "failed to build listener volume" ) ) ]
123111 BuildListenerVolume {
124112 source : ListenerOperatorVolumeSourceBuilderError ,
@@ -241,112 +229,6 @@ impl HasStatusCondition for v1alpha1::HbaseCluster {
241229}
242230
243231impl v1alpha1:: HbaseCluster {
244- /// Retrieve and merge resource configs for role and role groups
245- /// Merges and validates the config for `role`/`role_group`.
246- ///
247- /// The role-group config is merged on top of the role config on top of the
248- /// operator defaults (most specific wins) and the result is validated.
249- pub fn merged_config (
250- & self ,
251- role : & HbaseRole ,
252- role_group : & str ,
253- hdfs_discovery_cm_name : & str ,
254- ) -> Result < AnyServiceConfig , Error > {
255- // Trivial values for role-groups are not allowed
256- if role_group. is_empty ( ) {
257- return Err ( Error :: EmptyRoleGroup ) ;
258- }
259-
260- match role {
261- HbaseRole :: Master => {
262- let default_config = HbaseConfigFragment :: default_config (
263- role,
264- & self . name_any ( ) ,
265- hdfs_discovery_cm_name,
266- ) ;
267- let role_obj = self . spec . masters . as_ref ( ) . context ( MissingHbaseRoleSnafu {
268- role : role. to_string ( ) ,
269- } ) ?;
270-
271- let mut role_config = role_obj. config . config . clone ( ) ;
272- let mut role_group_config = role_obj
273- . role_groups
274- . get ( role_group)
275- . context ( RoleGroupNotFoundSnafu ) ?
276- . config
277- . config
278- . clone ( ) ;
279-
280- role_config. merge ( & default_config) ;
281- role_group_config. merge ( & role_config) ;
282- Ok ( AnyServiceConfig :: Master (
283- fragment:: validate ( role_group_config)
284- . context ( FragmentValidationFailureSnafu ) ?,
285- ) )
286- }
287- HbaseRole :: RegionServer => {
288- let default_config = RegionServerConfigFragment :: default_config (
289- role,
290- & self . name_any ( ) ,
291- hdfs_discovery_cm_name,
292- ) ;
293- let role_obj =
294- self . spec
295- . region_servers
296- . as_ref ( )
297- . context ( MissingHbaseRoleSnafu {
298- role : role. to_string ( ) ,
299- } ) ?;
300-
301- let mut role_config = role_obj. config . config . clone ( ) ;
302- let mut role_group_config = role_obj
303- . role_groups
304- . get ( role_group)
305- . context ( RoleGroupNotFoundSnafu ) ?
306- . config
307- . config
308- . clone ( ) ;
309-
310- role_config. merge ( & default_config) ;
311- role_group_config. merge ( & role_config) ;
312- Ok ( AnyServiceConfig :: RegionServer (
313- fragment:: validate ( role_group_config)
314- . context ( FragmentValidationFailureSnafu ) ?,
315- ) )
316- }
317- HbaseRole :: RestServer => {
318- let default_config = HbaseConfigFragment :: default_config (
319- role,
320- & self . name_any ( ) ,
321- hdfs_discovery_cm_name,
322- ) ;
323- let role_obj = self
324- . spec
325- . rest_servers
326- . as_ref ( )
327- . context ( MissingHbaseRoleSnafu {
328- role : role. to_string ( ) ,
329- } ) ?;
330-
331- let mut role_config = role_obj. config . config . clone ( ) ;
332- let mut role_group_config = role_obj
333- . role_groups
334- . get ( role_group)
335- . context ( RoleGroupNotFoundSnafu ) ?
336- . config
337- . config
338- . clone ( ) ;
339-
340- role_config. merge ( & default_config) ;
341- role_group_config. merge ( & role_config) ;
342- Ok ( AnyServiceConfig :: RestServer (
343- fragment:: validate ( role_group_config)
344- . context ( FragmentValidationFailureSnafu ) ?,
345- ) )
346- }
347- }
348- }
349-
350232 /// Metadata about a server rolegroup
351233 pub fn server_rolegroup_ref (
352234 & self ,
@@ -951,6 +833,110 @@ impl AnyServiceConfig {
951833 }
952834}
953835
836+ #[ cfg( test) ]
837+ pub ( crate ) mod test_helpers {
838+ use stackable_operator:: {
839+ config:: { fragment:: FromFragment , merge:: Merge } ,
840+ kube:: ResourceExt ,
841+ role_utils:: { GenericRoleConfig , Role } ,
842+ v2:: {
843+ jvm_argument_overrides:: JvmArgumentOverrides ,
844+ role_utils:: { JavaCommonConfig , with_validated_config} ,
845+ } ,
846+ } ;
847+
848+ use super :: {
849+ AnyServiceConfig , HbaseConfig , HbaseConfigFragment , HbaseRole , RegionServerConfig ,
850+ RegionServerConfigFragment , v1alpha1,
851+ } ;
852+
853+ /// Test helper: merge + validate a single role group via the production
854+ /// [`with_validated_config`] path (the same merge the controller runs), returning the
855+ /// role-specific [`AnyServiceConfig`] and the merged [`JvmArgumentOverrides`].
856+ pub ( crate ) fn merged_role_group_config (
857+ hbase : & v1alpha1:: HbaseCluster ,
858+ role : & HbaseRole ,
859+ role_group : & str ,
860+ hdfs_discovery_cm_name : & str ,
861+ ) -> ( AnyServiceConfig , JvmArgumentOverrides ) {
862+ match role {
863+ HbaseRole :: Master => merge :: < HbaseConfig , _ > (
864+ hbase
865+ . spec
866+ . masters
867+ . as_ref ( )
868+ . expect ( "master role must be defined" ) ,
869+ role_group,
870+ HbaseConfigFragment :: default_config (
871+ role,
872+ & hbase. name_any ( ) ,
873+ hdfs_discovery_cm_name,
874+ ) ,
875+ AnyServiceConfig :: Master ,
876+ ) ,
877+ HbaseRole :: RegionServer => merge :: < RegionServerConfig , _ > (
878+ hbase
879+ . spec
880+ . region_servers
881+ . as_ref ( )
882+ . expect ( "region server role must be defined" ) ,
883+ role_group,
884+ RegionServerConfigFragment :: default_config (
885+ role,
886+ & hbase. name_any ( ) ,
887+ hdfs_discovery_cm_name,
888+ ) ,
889+ AnyServiceConfig :: RegionServer ,
890+ ) ,
891+ HbaseRole :: RestServer => merge :: < HbaseConfig , _ > (
892+ hbase
893+ . spec
894+ . rest_servers
895+ . as_ref ( )
896+ . expect ( "rest server role must be defined" ) ,
897+ role_group,
898+ HbaseConfigFragment :: default_config (
899+ role,
900+ & hbase. name_any ( ) ,
901+ hdfs_discovery_cm_name,
902+ ) ,
903+ AnyServiceConfig :: RestServer ,
904+ ) ,
905+ }
906+ }
907+
908+ fn merge < ValidatedConfig , Config > (
909+ role : & Role < Config , v1alpha1:: HbaseConfigOverrides , GenericRoleConfig , JavaCommonConfig > ,
910+ role_group : & str ,
911+ default_config : Config ,
912+ wrap : fn ( ValidatedConfig ) -> AnyServiceConfig ,
913+ ) -> ( AnyServiceConfig , JvmArgumentOverrides )
914+ where
915+ Config : Clone + Merge ,
916+ ValidatedConfig : FromFragment < Fragment = Config > ,
917+ {
918+ let role_group = role
919+ . role_groups
920+ . get ( role_group)
921+ . expect ( "role group must be defined" ) ;
922+ let validated = with_validated_config :: <
923+ ValidatedConfig ,
924+ JavaCommonConfig ,
925+ Config ,
926+ GenericRoleConfig ,
927+ v1alpha1:: HbaseConfigOverrides ,
928+ > ( role_group, role, & default_config)
929+ . expect ( "role group config should merge and validate" ) ;
930+ (
931+ wrap ( validated. config . config ) ,
932+ validated
933+ . config
934+ . product_specific_common_config
935+ . jvm_argument_overrides ,
936+ )
937+ }
938+ }
939+
954940#[ cfg( test) ]
955941mod tests {
956942 use indoc:: indoc;
@@ -1011,13 +997,12 @@ spec:
1011997 let hbase_role = HbaseRole :: RegionServer ;
1012998 let rolegroup = hbase. server_rolegroup_ref ( hbase_role. to_string ( ) , role_group_name) ;
1013999
1014- let merged_config = hbase
1015- . merged_config (
1016- & hbase_role,
1017- & rolegroup. role_group ,
1018- & hbase. spec . cluster_config . hdfs_config_map_name ,
1019- )
1020- . unwrap ( ) ;
1000+ let ( merged_config, _) = super :: test_helpers:: merged_role_group_config (
1001+ & hbase,
1002+ & hbase_role,
1003+ & rolegroup. role_group ,
1004+ & hbase. spec . cluster_config . hdfs_config_map_name ,
1005+ ) ;
10211006 if let AnyServiceConfig :: RegionServer ( config) = merged_config {
10221007 assert_eq ! ( run_before_shutdown, config. region_mover. run_before_shutdown) ;
10231008 assert_eq ! ( max_threads, config. region_mover. max_threads) ;
0 commit comments