diff --git a/deploy/lib/server_config.rb b/deploy/lib/server_config.rb index c21b688d..81488818 100644 --- a/deploy/lib/server_config.rb +++ b/deploy/lib/server_config.rb @@ -320,6 +320,7 @@ def bootstrap if (r.body.match(" e + logger.error e.response.body logger.error "... Validation FAILED" result = false end diff --git a/deploy/lib/xquery/setup.xqy b/deploy/lib/xquery/setup.xqy index 5aa4be14..61a74128 100644 --- a/deploy/lib/xquery/setup.xqy +++ b/deploy/lib/xquery/setup.xqy @@ -886,15 +886,15 @@ declare function setup:configure-databases($import-config as element(configurati for $db-config in setup:get-databases-from-config($import-config) let $database-name := setup:get-database-name-from-database-config($db-config) let $database := xdmp:database($database-name) - - let $remove-existing-range-path-indexes := + let $admin-config := admin:get-configuration() + let $admin-config := (: remove-existing-range-path-indexes := :) (: wrap in try catch because this function is new to 6.0 and will fail in older version of ML :) try { - if (xdmp:eval(' + xdmp:eval(' import module namespace admin = "http://marklogic.com/xdmp/admin" at "/MarkLogic/admin.xqy"; declare variable $database external; - let $admin-config := admin:get-configuration() + declare variable $admin-config external; let $remove-existing-indexes := for $index in admin:database-get-range-path-indexes($admin-config, $database) return @@ -902,44 +902,46 @@ declare function setup:configure-databases($import-config as element(configurati $admin-config, admin:database-delete-range-path-index($admin-config, $database, $index)) return - admin:save-configuration-without-restart($admin-config)', - (xs:QName("database"), $database))) then - xdmp:set($restart-needed, fn:true()) - else () + $admin-config + (: admin:save-configuration-without-restart($admin-config) :)', + (xs:QName("database"), $database, + xs:QName("admin-config"), $admin-config)) } catch($ex) { - if ($ex/error:code = "XDMP-UNDFUN") then () + if ($ex/error:code = "XDMP-UNDFUN") then $admin-config else xdmp:rethrow() } - let $remove-existing-path-namespaces := + let $admin-config := (: remove-existing-path-namespaces := :) (: wrap in try catch because this function is new to 6.0 and will fail in older version of ML :) try { - if (xdmp:eval(' + xdmp:eval(' import module namespace admin = "http://marklogic.com/xdmp/admin" at "/MarkLogic/admin.xqy"; declare variable $database external; - let $admin-config := admin:get-configuration() + declare variable $admin-config external; let $remove-existing-indexes := - for $index in admin:database-get-path-namespaces($admin-config, $database) + for $index at $i in admin:database-get-path-namespaces($admin-config, $database) return xdmp:set($admin-config, admin:database-delete-path-namespace($admin-config, $database, $index)) return - admin:save-configuration-without-restart($admin-config)', - (xs:QName("database"), $database))) then - xdmp:set($restart-needed, fn:true()) - else () + $admin-config (: admin:save-configuration-without-restart($admin-config) :)', + (xs:QName("database"), $database, + xs:QName("admin-config"), $admin-config)) } catch($ex) { - if ($ex/error:code = "XDMP-UNDFUN") then () + xdmp:log($ex), + if ($ex/error:code = "XDMP-UNDFUN") then $admin-config + else if ($ex/error:code = "ADMIN-PATHNAMESPACEINUSE" and fn:not(setup:at-least-version("6.0-2"))) then + fn:error(xs:QName("VERSION_NOT_SUPPORTED"), "Roxy does not support path namespaces for this version of MarkLogic. Use 6.0-2 or later.") else xdmp:rethrow() } - let $admin-config := setup:add-word-lexicons(admin:get-configuration(), $database, $db-config) + let $admin-config := setup:add-word-lexicons($admin-config, $database, $db-config) let $admin-config := setup:add-fragment-roots($admin-config, $database, $db-config) let $admin-config := setup:add-fragment-parents($admin-config, $database, $db-config) @@ -1217,6 +1219,7 @@ declare function setup:add-field-excludes-R( else xdmp:eval( 'import module namespace admin = "http://marklogic.com/xdmp/admin" at "/MarkLogic/admin.xqy"; + declare namespace db="http://marklogic.com/xdmp/database"; declare variable $e external; admin:database-excluded-element( @@ -1437,6 +1440,22 @@ declare function setup:validate-range-path-indexes( xdmp:rethrow() } for $expected in $db-config/db:range-path-indexes/db:range-path-index + let $expected := + xdmp:eval(' + import module namespace admin = "http://marklogic.com/xdmp/admin" at "/MarkLogic/admin.xqy"; + declare namespace db="http://marklogic.com/xdmp/database"; + declare variable $database external; + declare variable $x external; + + admin:database-range-path-index( + $database, + $x/db:scalar-type, + $x/db:path-expression, + $x/db:collation, + $x/db:range-value-positions, + $x/db:invalid-values)', + (xs:QName("database"), $database, + xs:QName("x"), $expected)) return if ($existing[fn:deep-equal(., $expected)]) then () else @@ -3815,6 +3834,31 @@ declare function setup:get-forests-per-host-from-database-config( :: Utility functions ::) +declare function setup:at-least-version($target) +{ + let $current := xdmp:version() + let $current-formatted := + fn:concat( + fn:format-number(xs:int(fn:replace($current, "^(\d+)\..*", "$1")), "000"), (: major :) + fn:format-number(xs:int(fn:replace($current, "^\d+\.(\d+).*", "$1")), "000"), (: minor :) + fn:format-number(xs:int(fn:replace($current, "^\d+\.\d+\-(\d+).*", "$1")), "000"), (: x.x-X :) + if (fn:matches($current, "^\d+\.\d+\-\d+\.\d+")) then + fn:format-number(xs:int(fn:replace($current, "^\d+\.\d+\-\d+\.(\d+)", "$1")), "000") (: x.x-x.X :) + else "000" + ) + let $target-formatted := + fn:concat( + fn:format-number(xs:int(fn:replace($target, "^(\d+)\..*", "$1")), "000"), (: major :) + fn:format-number(xs:int(fn:replace($target, "^\d+\.(\d+).*", "$1")), "000"), (: minor :) + fn:format-number(xs:int(fn:replace($target, "^\d+\.\d+\-(\d+).*", "$1")), "000"), (: x.x-X :) + if (fn:matches($target, "^\d+\.\d+\-\d+\.\d+")) then + fn:format-number(xs:int(fn:replace($target, "^\d+\.\d+\-\d+\.(\d+)", "$1")), "000") (: x.x-x.X :) + else "000" + ) + return fn:compare($current-formatted, $target-formatted) >= 0 +}; + + declare function setup:read-config-file($filename as xs:string) as document-node() { xdmp:security-assert("http://marklogic.com/xdmp/privileges/admin-module-read", "execute"), @@ -4306,15 +4350,24 @@ declare function setup:validation-fail($message) declare function setup:validate-install($import-config as element(configuration)) { - setup:validate-privileges($import-config), - setup:validate-roles($import-config), - setup:validate-users($import-config), - setup:validate-mimetypes($import-config), - setup:validate-forests($import-config), - setup:validate-databases($import-config), - setup:validate-attached-forests($import-config), - setup:validate-amps($import-config), - setup:validate-database-settings($import-config), - setup:validate-databases-indexes($import-config), - setup:validate-appservers($import-config) + try + { + setup:validate-privileges($import-config), + setup:validate-roles($import-config), + setup:validate-users($import-config), + setup:validate-mimetypes($import-config), + setup:validate-forests($import-config), + setup:validate-databases($import-config), + setup:validate-attached-forests($import-config), + setup:validate-amps($import-config), + setup:validate-database-settings($import-config), + setup:validate-databases-indexes($import-config), + setup:validate-appservers($import-config) + } + catch($ex) + { + xdmp:set-response-code(500, 'Internal Server Error'), + xdmp:set-response-content-type("text/plain"), + $ex + } }; \ No newline at end of file diff --git a/deploy/test/data/ml5-config.xml b/deploy/test/data/ml5-config.xml index 6ed3120d..5fd18889 100644 --- a/deploy/test/data/ml5-config.xml +++ b/deploy/test/data/ml5-config.xml @@ -280,7 +280,6 @@ wgs84 point false - reject http://www.marklogic.com/ns/sample @@ -288,7 +287,6 @@ wgs84 point false - reject diff --git a/deploy/test/data/ml5-properties/build.properties b/deploy/test/data/ml5-properties/build.properties new file mode 100644 index 00000000..9cff0df0 --- /dev/null +++ b/deploy/test/data/ml5-properties/build.properties @@ -0,0 +1,80 @@ +################################################################# +# This file contains overrides to values in default.properties +# Make changes here, not in default.properties +################################################################# + +# +# Admin username/password that will exist on the dev/cert/prod servers +# +user=admin +password=admin + +# Your Application's name +app-name=roxy-deployer-tester + +# The root of you modules database or filesystem dir +modules-root=/ + +# +# the location of your marklogic configuration file +# +config.file=${basedir}/deploy/test/data/ml5-config.xml + +# +# Unit Testing +# Leave commented out for no unit testing +# turn these on if you are using the roxy unit tester +# +test-content-db=${app-name}-content-test +test-modules-db=${app-name}-modules-test +test-port=8902 + +# +# Leave commented out for default +# +schemas-db=${app-name}-schemas + +# +# Leave commented out for default +# turn it on if you are using triggers or CPF +# +triggers-db=${app-name}-triggers + +# +# the port that the Docs appserver is running on +# Docs appserver is required for boostrapping +# set this to 8000 for ML 4.x and 8002 for ML 5.x +# you should only override this if your Docs appserver +# is running on a funky port +# +# bootstrap-port= + +# +# The ports used by your application +# +app-port=8900 +xcc-port=8901 + +content-forests-per-host=2 + +# +# The authentication method used for your appserver +# application-level, basic, digest, digestbasic +# +authentication-method=digest + +# +# The user used as the default user in application level authentication. +# Using the admin user as the default user is equivalent to turning security off. +# +# default-user=${app-name}-user + +# +# the uris or IP addresses of your servers +# WARNING: if you are running these scripts on WINDOWS you may need to change localhost to 127.0.0.1 +# There have been reported issues with dns resolution when localhost wasn't in the hosts file. +# +local-server=localhost +#dev-server= +#cert-server= +#prod-server= diff --git a/deploy/test/data/ml5-properties/default.properties b/deploy/test/data/ml5-properties/default.properties new file mode 100644 index 00000000..f54caed0 --- /dev/null +++ b/deploy/test/data/ml5-properties/default.properties @@ -0,0 +1,118 @@ +################################################################# +# This file contains default application configuration options +# Don't mess with this file. Instead, copy it to build.properties +# and mess with that +################################################################# + +# +# the location of your code to load into ML +# +xquery.dir=${basedir}/src + +# +# the location of your unit test code +# +xquery-test.dir=${basedir}/src/test + +# +# the location of your xml data to load into ML +# +data.dir=${basedir}/data + +# +# the location of your marklogic configuration file +# +config.file=${basedir}/deploy/ml-config.xml + +# +# Admin username/password that will exist on the dev/cert/prod servers +# +user=admin +password=admin + +# +# Your Application's name +# +app-name=roxy +modules-root=/ + +# The role that is given permissions and execute privileges +app-role=${app-name}-role + +# +# The names of your databases. Forests are given the same names +# +app-modules-db=${app-name}-modules +content-db=${app-name}-content +modules-db=${app-name}-modules + +# +# Number of forests to create per host in the group for the content-db +# +content-forests-per-host=1 + +# +# A location on disk to store the forest data. "data directory" in the admin ui +# +# forest-data-dir= + +# Leave commented out for no test db +# turn it on if you are using the roxy unit tester +# test-content-db=${app-name}-content-test +# test-modules-db=${app-modules-db} + +# Leave commented out for default +# schemas-db=${app-name}-schemas + +# Leave commented out for default +# turn it on if you are using triggers or CPF +# triggers-db=${app-name}-triggers + +# +# the port that the Docs appserver is running on +# Docs appserver is required for boostrapping +# +bootstrap-port-five=8002 +bootstrap-port-four=8000 + +# +# The ports used by your application +# +app-port=8040 +xcc-port=8041 + +# Leave commented out for no test appserver +# turn it on if you are using the roxy unit tester +# test-port=8042 + +# +# The authentication used for your appserver +# +authentication-method=digest +default-user=${app-name}-user + +# +# The default values point to Roxy file +# +url-rewriter=/roxy/rewrite.xqy +error-handler=/roxy/error.xqy + +environments=local,dev,prod + +# +# The Major version of ML server across your environments (4 or 5). You can override +# this value in build.properties if all of your servers are the same version +# or override it in each ${env}.properties file if each server has a different +# version. +# +server-version=5 + +# +# the uris or IP addresses of your servers +# WARNING: if you are running these scripts on windows you may need to change localhost to 127.0.0.1 +# There have been reported issues with dns resolution when localhost wasn't in the hosts file. +# +local-server=localhost +#dev-server= +#cert-server= +#prod-server= diff --git a/deploy/test/data/ml6-config.xml b/deploy/test/data/ml6-config.xml index 532abd53..cd1d09ef 100644 --- a/deploy/test/data/ml6-config.xml +++ b/deploy/test/data/ml6-config.xml @@ -226,6 +226,7 @@ name http://marklogic.com/collation/codepoint false + reject string @@ -233,6 +234,7 @@ name2 http://marklogic.com/collation/codepoint false + reject @@ -244,6 +246,7 @@ name http://marklogic.com/collation/codepoint false + reject string @@ -253,6 +256,7 @@ name2 http://marklogic.com/collation/codepoint false + reject @@ -261,12 +265,14 @@ sample false + reject date sample2 false + reject @@ -323,6 +329,7 @@ lon wgs84 false + reject http://marklogic.com/ns/sample @@ -333,6 +340,7 @@ lon2 wgs84 false + reject @@ -345,6 +353,7 @@ lon wgs84 true + reject http://marklogic.com/ns/sample @@ -355,6 +364,7 @@ lon2 wgs84 true + reject @@ -366,6 +376,7 @@ wgs84 point false + reject http://marklogic.com/ns/sample @@ -375,6 +386,7 @@ wgs84 point false + reject diff --git a/deploy/test/data/ml6-properties/build.properties b/deploy/test/data/ml6-properties/build.properties index 75289878..230384f3 100644 --- a/deploy/test/data/ml6-properties/build.properties +++ b/deploy/test/data/ml6-properties/build.properties @@ -1,3 +1,80 @@ +################################################################# +# This file contains overrides to values in default.properties +# Make changes here, not in default.properties +################################################################# + +# +# Admin username/password that will exist on the dev/cert/prod servers +# user=admin password=admin -app-name=roxy-unit-tests \ No newline at end of file + +# Your Application's name +app-name=roxy-deployer-tester + +# The root of you modules database or filesystem dir +modules-root=/ + +# +# the location of your marklogic configuration file +# +config.file=${basedir}/deploy/test/data/ml6-config.xml + +# +# Unit Testing +# Leave commented out for no unit testing +# turn these on if you are using the roxy unit tester +# +#test-content-db=${app-name}-content-test +#test-modules-db=${app-name}-modules-test +#test-port=8902 + +# +# Leave commented out for default +# +schemas-db=${app-name}-schemas + +# +# Leave commented out for default +# turn it on if you are using triggers or CPF +# +#triggers-db=${app-name}-triggers + +# +# the port that the Docs appserver is running on +# Docs appserver is required for boostrapping +# set this to 8000 for ML 4.x and 8002 for ML 5.x +# you should only override this if your Docs appserver +# is running on a funky port +# +# bootstrap-port= + +# +# The ports used by your application +# +app-port=8900 +xcc-port=8901 + +content-forests-per-host=2 + +# +# The authentication method used for your appserver +# application-level, basic, digest, digestbasic +# +authentication-method=digest + +# +# The user used as the default user in application level authentication. +# Using the admin user as the default user is equivalent to turning security off. +# +# default-user=${app-name}-user + +# +# the uris or IP addresses of your servers +# WARNING: if you are running these scripts on WINDOWS you may need to change localhost to 127.0.0.1 +# There have been reported issues with dns resolution when localhost wasn't in the hosts file. +# +local-server=localhost +#dev-server= +#cert-server= +#prod-server= diff --git a/deploy/test/data/ml6-properties/default.properties b/deploy/test/data/ml6-properties/default.properties index 9aa744d7..f54caed0 100644 --- a/deploy/test/data/ml6-properties/default.properties +++ b/deploy/test/data/ml6-properties/default.properties @@ -1,3 +1,118 @@ -user=admin-user -password=admin-user -app-name=roxy-unit-tests \ No newline at end of file +################################################################# +# This file contains default application configuration options +# Don't mess with this file. Instead, copy it to build.properties +# and mess with that +################################################################# + +# +# the location of your code to load into ML +# +xquery.dir=${basedir}/src + +# +# the location of your unit test code +# +xquery-test.dir=${basedir}/src/test + +# +# the location of your xml data to load into ML +# +data.dir=${basedir}/data + +# +# the location of your marklogic configuration file +# +config.file=${basedir}/deploy/ml-config.xml + +# +# Admin username/password that will exist on the dev/cert/prod servers +# +user=admin +password=admin + +# +# Your Application's name +# +app-name=roxy +modules-root=/ + +# The role that is given permissions and execute privileges +app-role=${app-name}-role + +# +# The names of your databases. Forests are given the same names +# +app-modules-db=${app-name}-modules +content-db=${app-name}-content +modules-db=${app-name}-modules + +# +# Number of forests to create per host in the group for the content-db +# +content-forests-per-host=1 + +# +# A location on disk to store the forest data. "data directory" in the admin ui +# +# forest-data-dir= + +# Leave commented out for no test db +# turn it on if you are using the roxy unit tester +# test-content-db=${app-name}-content-test +# test-modules-db=${app-modules-db} + +# Leave commented out for default +# schemas-db=${app-name}-schemas + +# Leave commented out for default +# turn it on if you are using triggers or CPF +# triggers-db=${app-name}-triggers + +# +# the port that the Docs appserver is running on +# Docs appserver is required for boostrapping +# +bootstrap-port-five=8002 +bootstrap-port-four=8000 + +# +# The ports used by your application +# +app-port=8040 +xcc-port=8041 + +# Leave commented out for no test appserver +# turn it on if you are using the roxy unit tester +# test-port=8042 + +# +# The authentication used for your appserver +# +authentication-method=digest +default-user=${app-name}-user + +# +# The default values point to Roxy file +# +url-rewriter=/roxy/rewrite.xqy +error-handler=/roxy/error.xqy + +environments=local,dev,prod + +# +# The Major version of ML server across your environments (4 or 5). You can override +# this value in build.properties if all of your servers are the same version +# or override it in each ${env}.properties file if each server has a different +# version. +# +server-version=5 + +# +# the uris or IP addresses of your servers +# WARNING: if you are running these scripts on windows you may need to change localhost to 127.0.0.1 +# There have been reported issues with dns resolution when localhost wasn't in the hosts file. +# +local-server=localhost +#dev-server= +#cert-server= +#prod-server= diff --git a/deploy/test/test_server_config.rb b/deploy/test/test_server_config.rb index 5bf86c8c..35bc1e2c 100644 --- a/deploy/test/test_server_config.rb +++ b/deploy/test/test_server_config.rb @@ -3,12 +3,17 @@ require 'util' class TestProperties < Test::Unit::TestCase + + def teardown + @s.wipe if @s + end + def test_load_properties properties = ServerConfig.load_properties(File.expand_path("../data/ml6-properties/default.properties", __FILE__), "test.") assert(properties.is_a?(Hash)) - assert_equal('admin-user', properties['test.user']) - assert_equal('admin-user', properties['test.password']) - assert_equal('roxy-unit-tests', properties['test.app-name']) + assert_equal('admin', properties['test.user']) + assert_equal('admin', properties['test.password']) + assert_equal('roxy', properties['test.app-name']) end def test_substitute_properties @@ -32,30 +37,32 @@ def test_properties assert(properties.is_a?(Hash)) assert_equal('admin', properties['ml.user']) assert_equal('admin', properties['ml.password']) - assert_equal('roxy-unit-tests', properties['ml.app-name']) + assert_equal('roxy-deployer-tester', properties['ml.app-name']) end def test_build_config end - def test_bootstrap + def bootstrap_version(version) # cheat the local environment into the command line ARGV << "local" - properties = ServerConfig.properties(File.expand_path("../data/ml4-properties/", __FILE__)) - ServerConfig.logger.debug(properties) - s = ServerConfig.new({ - :config_file => File.expand_path("../data/ml4-config.xml", __FILE__), + properties = ServerConfig.properties(File.expand_path("../data/ml#{version}-properties/", __FILE__)) + @s = ServerConfig.new({ + :config_file => File.expand_path("../data/ml#{version}-config.xml", __FILE__), :properties => properties, :logger => Logger.new(STDOUT) }) - s.bootstrap - assert(s.validate_install, "Bootstrap passes validation") + assert(@s.bootstrap, "Boostrap should succeeded") + assert(@s.validate_install, "Bootstrap passes validation") - s.bootstrap - assert(s.validate_install, "Bootstrap passes validation") + assert(@s.bootstrap, "Boostrap should succeeded") + assert(@s.validate_install, "Bootstrap passes validation") + end - s.wipe + def test_bootstrap + version = ENV['ROXY_TEST_SERVER_VERSION'] || 4 + bootstrap_version version end end \ No newline at end of file