@@ -433,19 +433,46 @@ declare function setup:suppress-comments($nodes) {
433
433
default return $node
434
434
};
435
435
436
+ declare function setup:unique-attributes ($attrs) {
437
+ let $result := map:map ()
438
+ let $_ :=
439
+ for $attr in $attrs
440
+ let $attr-name := fn:name ($attr)
441
+ let $existing-attr := map:get ($result, $attr-name)
442
+ return
443
+ if (fn:exists ($existing-attr) and fn:string ($existing-attr) != fn:string ($attr)) then
444
+ fn:error (
445
+ xs:QName ("ATTR-CONFLICT" ),
446
+ fn:concat ("The config-files contain multiple attributes " , $attr-name, " with different values: " || fn:string ($existing-attr) || " vs " || fn:string ($attr))
447
+ )
448
+ else
449
+ map:put ($result, name ($attr), $attr)
450
+ return map:keys ($result) ! map:get ($result, .)
451
+ };
452
+
436
453
(: for backwards-compatibility :)
437
- declare function setup:rewrite-config ($import-configs as element (configuration )+) as element (configuration)
454
+ declare function setup:rewrite-config ($import-configs as node ( )+) as element (configuration)
438
455
{
439
456
setup:rewrite-config ($import-configs, ())
440
457
};
441
458
442
- declare function setup:rewrite-config ($import-configs as element (configuration)+, $silent as xs:boolean?) as element (configuration)
459
+ declare function setup:rewrite-config ($import-configs as node ()+, $silent as xs:boolean?) as element (configuration)
460
+ {
461
+ setup:rewrite-config ($import-configs, $silent, ())
462
+ };
463
+
464
+ declare function setup:rewrite-config ($import-configs as node ()+, $silent as xs:boolean?, $keep-comments as xs:boolean?) as element (configuration)
443
465
{
444
466
let $config :=
445
467
element { fn:node-name ($import-configs[1 ]) } {
446
- $import-configs/@*,
468
+ setup:unique-attributes ( $import-configs/@*) ,
447
469
448
- <groups xmlns = "http://marklogic.com/xdmp/group" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://marklogic.com/xdmp/group group.xsd" >{
470
+ (: capture comments before gr:groups, and its older counterparts :)
471
+ $import-configs/(
472
+ gr:groups, gr:http-servers, gr:xdbc-servers, gr:odbc-servers, gr:task-server
473
+ )/preceding-sibling::node (),
474
+
475
+ <groups xmlns = "http://marklogic.com/xdmp/group" >{
449
476
let $default-group := ($import-configs/@default-group , "Default" )[1 ]
450
477
for $group in fn:distinct-values (
451
478
($import-configs/gr:groups/gr:group /gr:group-name, $import-configs/(gr:http-servers/gr:http-server, gr:xdbc-servers/gr:xdbc-server,
@@ -460,8 +487,10 @@ declare function setup:rewrite-config($import-configs as element(configuration)+
460
487
where fn:exists ($servers | $databases | $group-config)
461
488
return
462
489
<group>
490
+ { setup:unique-attributes ($group-config/@*) }
463
491
<group-name>{$group}</group-name>
464
492
{
493
+ $group-config/(node () except (gr:group-name, gr:http-servers, gr:xdbc-servers, gr:odbc-servers, gr:task-server)),
465
494
if ($http-servers) then
466
495
<http-servers>{$http-servers}</http-servers>
467
496
else (),
@@ -473,13 +502,20 @@ declare function setup:rewrite-config($import-configs as element(configuration)+
473
502
else (),
474
503
if ($task-server) then
475
504
$task-server
476
- else (),
477
- $group-config/(node () except gr:group-name)
505
+ else ()
478
506
}
479
507
</group>
480
508
}</groups>,
481
509
482
- $import-configs/(node () except (gr:groups, gr:http-servers, gr:xdbc-servers, gr:odbc-servers, gr:task-server))
510
+ (: capture anything following gr:groups, and its older counterparts :)
511
+ $import-configs/(
512
+ gr:groups, gr:http-servers, gr:xdbc-servers, gr:odbc-servers, gr:task-server
513
+ )/following-sibling::node (),
514
+
515
+ (: other fragments with configuration as root :)
516
+ $import-configs[fn:empty ((
517
+ gr:groups, gr:http-servers, gr:xdbc-servers, gr:odbc-servers, gr:task-server
518
+ ))]/node ()
483
519
}
484
520
485
521
(: Check config on group consistency! :)
@@ -492,10 +528,11 @@ declare function setup:rewrite-config($import-configs as element(configuration)+
492
528
return
493
529
fn:error (
494
530
xs:QName ("NO_HOSTS_IN_GROUP" ),
495
- fn:concat ("No hosts assigned to group " , $group, ", needed for app servers and forests!" ))
531
+ fn:concat ("No hosts assigned to group " , $group, ", needed for app servers and forests!" )
532
+ )
496
533
497
534
(: all good :)
498
- return setup:suppress-comments ($config)
535
+ return if ($keep-comments) then $config else setup:suppress-comments ($config)
499
536
};
500
537
501
538
@@ -544,7 +581,7 @@ declare private function setup:parse-options( $options as xs:string ) as map:map
544
581
return $optionsMap
545
582
};
546
583
547
- declare function setup:do-setup ($import-config as element (configuration )+, $options as xs:string) as item ()*
584
+ declare function setup:do-setup ($import-config as node ( )+, $options as xs:string) as item ()*
548
585
{
549
586
let $optionsMap := setup:parse-options ( $options )
550
587
let $do-internals := map:contains ( $optionsMap, "internals" )
@@ -611,7 +648,7 @@ declare function setup:do-setup($import-config as element(configuration)+, $opti
611
648
}
612
649
};
613
650
614
- declare function setup:do-wipe ($import-config as element (configuration )+, $options as xs:string) as item ()*
651
+ declare function setup:do-wipe ($import-config as node ( )+, $options as xs:string) as item ()*
615
652
{
616
653
let $options := if (fn:empty ($options) or $options eq "" ) then ("all" ) else fn:tokenize ($options, "," )
617
654
@@ -1038,7 +1075,7 @@ declare function setup:do-wipe($import-config as element(configuration)+, $optio
1038
1075
Attempt to remove replicas that are to be decommissioned due to scaling out of the cluster.
1039
1076
Replicas are only removed after their new replacements have gone to sync replication.
1040
1077
:)
1041
- declare function setup:do-clean-replicas ($import-config as element (configuration )+, $options as xs:string) as item ()*
1078
+ declare function setup:do-clean-replicas ($import-config as node ( )+, $options as xs:string) as item ()*
1042
1079
{
1043
1080
let $optionsMap := setup:parse-options ( $options )
1044
1081
let $do-internals := map:contains ( $optionsMap, "internals" )
@@ -1119,7 +1156,7 @@ declare function setup:do-clean-replicas($import-config as element(configuration
1119
1156
(:
1120
1157
Cleanup scale-out replica state files.
1121
1158
:)
1122
- declare function setup:do-clean-replicas-state ($import-config as element (configuration )+, $options as xs:string) as item ()*
1159
+ declare function setup:do-clean-replicas-state ($import-config as node ( )+, $options as xs:string) as item ()*
1123
1160
{
1124
1161
let $optionsMap := setup:parse-options ( $options )
1125
1162
let $do-internals := map:contains ( $optionsMap, "internals" )
0 commit comments