diff --git a/deploy/lib/xquery/setup.xqy b/deploy/lib/xquery/setup.xqy index c0ac0ef1..ea31136d 100644 --- a/deploy/lib/xquery/setup.xqy +++ b/deploy/lib/xquery/setup.xqy @@ -1009,18 +1009,25 @@ declare function setup:create-forests-from-config( $db-config as element(db:database), $database-name as xs:string) as item()* { + let $group-id := setup:get-group($db-config) for $forest-config in setup:get-database-forest-configs($import-config, $database-name) for $forest-name as xs:string in $forest-config/as:forest-name[fn:string-length(fn:string(.)) > 0] let $data-directory as xs:string? := $forest-config/as:data-directory[fn:string-length(fn:string(.)) > 0] + let $hosts := admin:group-get-host-ids(admin:get-configuration(), $group-id) let $host-name as xs:string? := $forest-config/as:host-name[fn:string-length(fn:string(.)) > 0] + let $host-id := if ($host-name) then xdmp:host($host-name) else $default-host + let $hostnr := fn:index-of($hosts, $host-id) let $replica-names as xs:string* := $forest-config/as:replica-names/as:replica-name[fn:string-length(fn:string(.)) > 0] - let $replicas := $import-config/as:assignments/as:assignment[as:forest-name = $replica-names] + let $replicas := + if (fn:count($hosts) gt 1) then + $import-config/as:assignments/as:assignment[as:forest-name = $replica-names] + else () return setup:create-forest( $forest-name, $data-directory, - if ($host-name) then xdmp:host($host-name) else (), - $replicas) + $host-id, + setup:reassign-replicas($replicas, $hosts, $hostnr, $forest-name, 1, fn:false())) }; @@ -1057,13 +1064,16 @@ declare function setup:create-forests-from-count( for $forestnr in (1 to $forests-per-host) let $new-forest-name := fn:string-join(($forest-name, fn:format-number(xs:integer($hostnr), "000"), xs:string($forestnr)), "-") let $replica-names as xs:string* := $forest-config/as:replica-names/as:replica-name[fn:string-length(fn:string(.)) > 0] - let $replicas := $import-config/as:assignments/as:assignment[as:forest-name = $replica-names] + let $replicas := + if (fn:count($hosts) gt 1) then + $import-config/as:assignments/as:assignment[as:forest-name = $replica-names] + else () return setup:create-forest( $new-forest-name, $data-directory, $host, - setup:reassign-replicas($replicas, $hosts, $hostnr, $forest-name, $forestnr)) + setup:reassign-replicas($replicas, $hosts, $hostnr, $forest-name, $forestnr, fn:true())) }; declare function setup:reassign-replicas( @@ -1071,10 +1081,11 @@ declare function setup:reassign-replicas( $hosts as xs:unsignedLong+, $hostnr as xs:integer, $forest-name as xs:string, - $forestnr as xs:int) as element(as:assignment)* + $forestnr as xs:int, + $append-numbering as xs:boolean) as element(as:assignment)* { - let $default-replica-host := xdmp:host-name($hosts[$hostnr mod count($hosts) + 1]) - for $replica in $replicas + for $replica at $pos in $replicas + let $default-replica-host := xdmp:host-name($hosts[($hostnr + $pos - 1) mod count($hosts) + 1]) let $replica-name as xs:string := ($replica/as:forest-name[fn:string-length(fn:string(.)) > 0], fn:concat($forest-name, '-replica'))[1] let $replica-host-name := $replica/as:host-name[fn:string-length(fn:string(.)) > 0] let $replica-host-name := @@ -1084,7 +1095,17 @@ declare function setup:reassign-replicas( $default-replica-host return element { fn:node-name($replica) } { $replica/@*, - {fn:string-join(($replica-name, fn:format-number(xs:integer($hostnr), "000"), xs:string($forestnr)), "-")}, + { + fn:string-join(( + $replica-name, + if ($append-numbering) then + fn:string-join( + (fn:format-number(xs:integer($hostnr), "000"), xs:string($forestnr)), + "-" + ) + else () + ), "-") + }, {$replica-host-name}, $replica/node() except ($replica/as:forest-name, $replica/as:host-name) } @@ -1132,49 +1153,83 @@ declare function setup:create-forest( $host-id as xs:unsignedLong?, $replicas as element(as:assignment)*) as item()* { - if (xdmp:forests()[$forest-name = xdmp:forest-name(.)]) then - fn:concat("Forest ", $forest-name, " already exists, not recreated..") - else - ( - let $host := ($host-id, $default-host)[1] - let $admin-config := - admin:forest-create(admin:get-configuration(), $forest-name, $host, $data-directory) - let $forest-id := admin:forest-get-id($admin-config, $forest-name) - let $_ := - for $replica in $replicas - let $replica-host-name := $replica/as:host-name[fn:string-length(fn:string(.)) > 0] - let $replica-host-id := - if ($replica-host-name) then xdmp:host($replica-host-name) else () - let $replica-host := ($replica-host-id, $default-host)[1] - let $cfg := + let $exists := xdmp:forests()[$forest-name = xdmp:forest-name(.)] + let $host := ($host-id, $default-host)[1] + let $admin-config := admin:get-configuration() + let $admin-config := + if ($exists) then + $admin-config + else + admin:forest-create($admin-config, $forest-name, $host, $data-directory) + let $forest-id := admin:forest-get-id($admin-config, $forest-name) + let $forest-replicas := admin:forest-get-replicas($admin-config, $forest-id) + let $rep-log := + for $replica in $replicas + let $replica-name := $replica/as:forest-name + let $replica-dir := $replica/as:data-directory[fn:string-length(fn:string(.)) > 0] + let $rep-exists := admin:forest-exists($admin-config, $replica-name) + let $replica-host-name := $replica/as:host-name[fn:string-length(fn:string(.)) > 0] + let $replica-host-id := + if ($replica-host-name) then xdmp:host($replica-host-name) else () + let $replica-host := ($replica-host-id, $default-host)[1] + let $cfg := + if ($rep-exists) then + $admin-config + else admin:forest-create( $admin-config, - $replica/as:forest-name, + $replica-name, $replica-host, - $replica/as:data-directory[fn:string-length(fn:string(.)) > 0]) - let $replica-id := admin:forest-get-id($cfg, $replica/as:forest-name) - let $cfg := admin:forest-set-failover-enable($cfg, $forest-id, fn:true()) - let $cfg := admin:forest-set-failover-enable($cfg, $replica-id, fn:true()) - return - xdmp:set($admin-config, admin:forest-add-replica($cfg, $forest-id, $replica-id)) - return - ( - if (admin:save-configuration-without-restart($admin-config)) then - xdmp:set($restart-needed, fn:true()) - else (), - setup:add-rollback( - "assignments", - element as:assignment - { - element as:forest-name { $forest-name } - }), + $replica-dir) + let $replica-id := admin:forest-get-id($cfg, $replica-name) + let $cfg := admin:forest-set-failover-enable($cfg, $forest-id, fn:true()) + let $cfg := admin:forest-set-failover-enable($cfg, $replica-id, fn:true()) + let $rep-attached := fn:exists( + for $r in $forest-replicas + where $r eq $replica-id + return $r + ) + where fn:not($rep-attached) + return ( fn:string-join(( - "Forest ", $forest-name, " succesfully created", - if ($data-directory) then (" at ", $data-directory) + "Forest ", $replica-name, " succesfully created", + + if ($replica-dir) then (" at ", $replica-dir) else (), - if ($host) then (" on ", xdmp:host-name($host)) - else ()), "") + + if ($replica-host-name) then (" on ", $replica-host-name) + else (), + + " as replica of ", $forest-name + ), ""), + xdmp:set($admin-config, admin:forest-add-replica($cfg, $forest-id, $replica-id)) ) + return ( + if (admin:save-configuration-without-restart($admin-config)) then + xdmp:set($restart-needed, fn:true()) + else (), + + setup:add-rollback( + "assignments", + element as:assignment + { + element as:forest-name { $forest-name } + }), + + fn:string-join(( + if ($exists) then + ("Forest ", $forest-name, " already exists, not recreated..") + else + ("Forest ", $forest-name, " succesfully created"), + + if ($data-directory) then (" at ", $data-directory) + else (), + + if ($host) then (" on ", xdmp:host-name($host)) + else () + ), ""), + + $rep-log ) };