@@ -549,18 +549,45 @@ 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 $import-configs := setup:process-conditionals ($import-configs, $properties)
561583 let $config :=
562584 element { fn:node-name ($import-configs[1 ]) } {
563- $import-configs/@*,
585+ setup:unique-attributes ($import-configs/@*),
586+
587+ (: capture comments before gr:groups, and its older counterparts :)
588+ $import-configs/(
589+ gr:groups, gr:http-servers, gr:xdbc-servers, gr:odbc-servers, gr:task-server
590+ )/preceding-sibling::node (),
564591
565592 <groups xmlns = "http://marklogic.com/xdmp/group" >{
566593 $import-configs/gr:groups/@*,
@@ -579,9 +606,10 @@ declare function setup:rewrite-config($import-configs as element(configuration)+
579606 where fn:exists ($servers | $databases | $group-config)
580607 return
581608 <group>
582- { $group-config/@* }
609+ { setup:unique-attributes ( $group-config/@*) }
583610 <group-name>{$group}</group-name>
584611 {
612+ $group-config/(node () except (gr:group-name, gr:http-servers, gr:xdbc-servers, gr:odbc-servers, gr:task-server)),
585613 if ($http-servers) then
586614 <http-servers>{$http-servers}</http-servers>
587615 else (),
@@ -593,13 +621,20 @@ declare function setup:rewrite-config($import-configs as element(configuration)+
593621 else (),
594622 if ($task-server) then
595623 $task-server
596- else (),
597- $group-config/(node () except gr:group-name)
624+ else ()
598625 }
599626 </group>
600627 }</groups>,
601628
602- $import-configs/(node () except (gr:groups, gr:http-servers, gr:xdbc-servers, gr:odbc-servers, gr:task-server))
629+ (: capture anything following gr:groups, and its older counterparts :)
630+ $import-configs/(
631+ gr:groups, gr:http-servers, gr:xdbc-servers, gr:odbc-servers, gr:task-server
632+ )/following-sibling::node (),
633+
634+ (: other fragments with configuration as root :)
635+ $import-configs[fn:empty ((
636+ gr:groups, gr:http-servers, gr:xdbc-servers, gr:odbc-servers, gr:task-server
637+ ))]/node ()
603638 }
604639
605640 (: Check config on group consistency! :)
@@ -612,10 +647,11 @@ declare function setup:rewrite-config($import-configs as element(configuration)+
612647 return
613648 fn:error (
614649 xs:QName ("NO_HOSTS_IN_GROUP" ),
615- fn:concat ("No hosts assigned to group " , $group, ", needed for app servers and forests!" ))
650+ fn:concat ("No hosts assigned to group " , $group, ", needed for app servers and forests!" )
651+ )
616652
617653 (: all good :)
618- return setup:suppress-comments ($config)
654+ return if ($keep-comments) then $config else setup:suppress-comments ($config)
619655};
620656
621657
@@ -664,7 +700,7 @@ declare private function setup:parse-options( $options as xs:string ) as map:map
664700 return $optionsMap
665701};
666702
667- declare function setup:do-setup ($import-config as element (configuration )+, $options as xs:string, $properties as map:map) as item ()*
703+ declare function setup:do-setup ($import-config as node ( )+, $options as xs:string, $properties as map:map) as item ()*
668704{
669705 let $optionsMap := setup:parse-options ( $options )
670706 let $do-internals := map:contains ( $optionsMap, "internals" )
@@ -731,7 +767,7 @@ declare function setup:do-setup($import-config as element(configuration)+, $opti
731767 }
732768};
733769
734- declare function setup:do-wipe ($import-config as element (configuration )+, $options as xs:string, $properties as map:map) as item ()*
770+ declare function setup:do-wipe ($import-config as node ( )+, $options as xs:string, $properties as map:map) as item ()*
735771{
736772 let $options := if (fn:empty ($options) or $options eq "" ) then ("all" ) else fn:tokenize ($options, "," )
737773
@@ -1162,7 +1198,7 @@ declare function setup:do-wipe($import-config as element(configuration)+, $optio
11621198 Attempt to remove replicas that are to be decommissioned due to scaling out of the cluster.
11631199 Replicas are only removed after their new replacements have gone to sync replication.
11641200:)
1165- declare function setup:do-clean-replicas ($import-config as element (configuration )+, $options as xs:string, $properties as map:map) as item ()*
1201+ declare function setup:do-clean-replicas ($import-config as node ( )+, $options as xs:string, $properties as map:map) as item ()*
11661202{
11671203 let $optionsMap := setup:parse-options ( $options )
11681204 let $do-internals := map:contains ( $optionsMap, "internals" )
0 commit comments