@@ -549,17 +549,44 @@ declare function setup:suppress-comments($nodes) {
549549 default return $node
550550};
551551
552+ declare function setup:unique-attributes ($attrs) {
553+ let $result := map:map ()
554+ let $_ :=
555+ for $attr in $attrs
556+ let $attr-name := fn:name ($attr)
557+ let $existing-attr := map:get ($result, $attr-name)
558+ return
559+ if (fn:exists ($existing-attr) and fn:string ($existing-attr) != fn:string ($attr)) then
560+ fn:error (
561+ xs:QName ("ATTR-CONFLICT" ),
562+ fn:concat ("The config-files contain multiple attributes " , $attr-name, " with different values: " || fn:string ($existing-attr) || " vs " || fn:string ($attr))
563+ )
564+ else
565+ map:put ($result, name ($attr), $attr)
566+ return map:keys ($result) ! map:get ($result, .)
567+ };
568+
552569(: for backwards-compatibility :)
553- declare function setup:rewrite-config ($import-configs as element (configuration )+, $properties as map:map) as element (configuration)
570+ declare function setup:rewrite-config ($import-configs as node ( )+, $properties as map:map) as element (configuration)
554571{
555572 setup:rewrite-config ($import-configs, $properties, ())
556573};
557574
558- declare function setup:rewrite-config ($import-configs as element (configuration)+, $properties as map:map, $silent as xs:boolean?) as element (configuration)
575+ declare function setup:rewrite-config ($import-configs as node ()+, $properties as map:map, $silent as xs:boolean?) as element (configuration)
576+ {
577+ setup:rewrite-config ($import-configs, $properties, $silent, ())
578+ };
579+
580+ declare function setup:rewrite-config ($import-configs as node ()+, $properties as map:map, $silent as xs:boolean?, $keep-comments as xs:boolean?) as element (configuration)
559581{
560582 let $config :=
561583 element { fn:node-name ($import-configs[1 ]) } {
562- $import-configs/@*,
584+ setup:unique-attributes ($import-configs/@*),
585+
586+ (: capture comments before gr:groups, and its older counterparts :)
587+ $import-configs/(
588+ gr:groups, gr:http-servers, gr:xdbc-servers, gr:odbc-servers, gr:task-server
589+ )/preceding-sibling::node (),
563590
564591 <groups xmlns = "http://marklogic.com/xdmp/group" >{
565592 $import-configs/gr:groups/@*,
@@ -578,9 +605,10 @@ declare function setup:rewrite-config($import-configs as element(configuration)+
578605 where fn:exists ($servers | $databases | $group-config)
579606 return
580607 <group>
581- { $group-config/@* }
608+ { setup:unique-attributes ( $group-config/@*) }
582609 <group-name>{$group}</group-name>
583610 {
611+ $group-config/(node () except (gr:group-name, gr:http-servers, gr:xdbc-servers, gr:odbc-servers, gr:task-server)),
584612 if ($http-servers) then
585613 <http-servers>{$http-servers}</http-servers>
586614 else (),
@@ -592,13 +620,20 @@ declare function setup:rewrite-config($import-configs as element(configuration)+
592620 else (),
593621 if ($task-server) then
594622 $task-server
595- else (),
596- $group-config/(node () except gr:group-name)
623+ else ()
597624 }
598625 </group>
599626 }</groups>,
600627
601- $import-configs/(node () except (gr:groups, gr:http-servers, gr:xdbc-servers, gr:odbc-servers, gr:task-server))
628+ (: capture anything following gr:groups, and its older counterparts :)
629+ $import-configs/(
630+ gr:groups, gr:http-servers, gr:xdbc-servers, gr:odbc-servers, gr:task-server
631+ )/following-sibling::node (),
632+
633+ (: other fragments with configuration as root :)
634+ $import-configs[fn:empty ((
635+ gr:groups, gr:http-servers, gr:xdbc-servers, gr:odbc-servers, gr:task-server
636+ ))]/node ()
602637 }
603638
604639 (: Check config on group consistency! :)
@@ -611,10 +646,13 @@ declare function setup:rewrite-config($import-configs as element(configuration)+
611646 return
612647 fn:error (
613648 xs:QName ("NO_HOSTS_IN_GROUP" ),
614- fn:concat ("No hosts assigned to group " , $group, ", needed for app servers and forests!" ))
649+ fn:concat ("No hosts assigned to group " , $group, ", needed for app servers and forests!" )
650+ )
615651
616652 (: all good :)
617- return setup:process-conditionals (setup:suppress-comments ($config), $properties)
653+ return setup:process-conditionals (
654+ if ($keep-comments) then $config else setup:suppress-comments ($config)
655+ )
618656};
619657
620658
@@ -663,7 +701,7 @@ declare private function setup:parse-options( $options as xs:string ) as map:map
663701 return $optionsMap
664702};
665703
666- declare function setup:do-setup ($import-config as element (configuration )+, $options as xs:string, $properties as map:map) as item ()*
704+ declare function setup:do-setup ($import-config as node ( )+, $options as xs:string, $properties as map:map) as item ()*
667705{
668706 let $optionsMap := setup:parse-options ( $options )
669707 let $do-internals := map:contains ( $optionsMap, "internals" )
@@ -730,7 +768,7 @@ declare function setup:do-setup($import-config as element(configuration)+, $opti
730768 }
731769};
732770
733- declare function setup:do-wipe ($import-config as element (configuration )+, $options as xs:string, $properties as map:map) as item ()*
771+ declare function setup:do-wipe ($import-config as node ( )+, $options as xs:string, $properties as map:map) as item ()*
734772{
735773 let $options := if (fn:empty ($options) or $options eq "" ) then ("all" ) else fn:tokenize ($options, "," )
736774
@@ -1161,7 +1199,7 @@ declare function setup:do-wipe($import-config as element(configuration)+, $optio
11611199 Attempt to remove replicas that are to be decommissioned due to scaling out of the cluster.
11621200 Replicas are only removed after their new replacements have gone to sync replication.
11631201:)
1164- declare function setup:do-clean-replicas ($import-config as element (configuration )+, $options as xs:string, $properties as map:map) as item ()*
1202+ declare function setup:do-clean-replicas ($import-config as node ( )+, $options as xs:string, $properties as map:map) as item ()*
11651203{
11661204 let $optionsMap := setup:parse-options ( $options )
11671205 let $do-internals := map:contains ( $optionsMap, "internals" )
0 commit comments