We're in the process of upgrading from MarkLogic 6 to 8 and have run into some problems calling library modules. We have xquery library modules that are called both from custom REST extensions and from non-REST xquery.
MarkLogic's documentation says that REST endpoints can use libraries installed either with their new /ext endpoint or libraries installed the old way (placed somewhere else in the modules database). However, when the library module is using, for example, the functx package that comes with MarkLogic, I can't get the cross-over to work.
Say I have two identical library modules, one installed via /ext
and one not:
xquery version "1.0-ml";
module namespace test = "test/lib";
import module namespace functx = "http://www.functx.com" at "/MarkLogic/functx/functx-1.0-nodoc-2007-01.xqy";
declare function test:stuff() {
<foo/>
};
The first is installed using this command, in case it matters:
curl --anyauth --user user:pwd -X PUT -i -d @".\\module\\testlib-ext.xqy" -H "Content-type: application/xquery" "http://host:8020/v1/ext/test/testlib-ext.xqy?perm:rest-reader=execute"
I have rest endpoints that use each module (the only difference is the namespace and import):
xquery version "1.0-ml";
module namespace te = "http://marklogic.com/rest-api/resource/test-ext-to-ext";
import module namespace test = "test/lib" at "/ext/test/testlib-ext.xqy";
declare function te:get($context as map:map, $params as map:map) as document-node()* {
document { test:stuff() }
};
The one using the library installed using /ext
works. The one using the module that's simply placed in the modules database installs without errors but gives me an error when called by a non-admin user (it works when called by admin):
RESTAPI-INVALIDREQ: (err:FOER0000) Invalid request: reason: Extension test-ext-to-lib does not exist.
I'd just install them all using /ext
, but then xquery that uses xdmp:invoke
breaks. It's a different error, but it seems to be the same underlying issue. Invoking a module using the library placed in the modules database works. Invoking a module using the library installed via /ext
fails with this error:
XDMP-MODNOTFOUND: (err:XQST0059) xdmp:invoke("/test/test-module-to-ext.xqy", (), ()) -- Module C:\Program Files\MarkLogic\Modules\MarkLogic\functx\functx-1.0-nodoc-2007-01.xqy not found
If I add the admin
role to the calling user, all of them work. They also work even without the admin role if I take the functx import out.
It looks like a permission problem, but I can't find a role or permission that will fix it. The user has a role with every checkbox except admin itself checked. Checking that last checkbox is the only thing I've found that makes this work, and that's obviously not a viable solution.
We don't really care how the libraries are installed, but we don't want to duplicate code. How can we make these imports work with both REST and non-REST xquery?
For the permissions to work, the main module and each library in the dependency chain must be executable by at least one role assigned to the user (where assignment includes inheritance and amping).
The REST API sets the
rest-extension-user
role on modules that it installs under/ext
.So, a user who has the
rest-extension-user
role should be able to invoke a module installed by the REST API under/ext
.More generally, any module (regardless of how it is installed) that is executable by the
rest-extension-user
role should be able to have dependencies on libraries installed by the REST API under/ext
(assuming, of course, that all paths are correct).