触发器不会运行(补充更多信息)

Trigger will not run (added more information)

我已经对这个触发器进行了数小时的修改,我想我现在已经找到了问题所在。

我已经设置了一个示例触发器,如 ML8 documentation

现在我已经将其修改为更真实的动作。

问题似乎是我使用的库模块在 lib.xqy 中包含我自己的函数。我已经在查询控制台中测试了 lib 本身,所有功能 运行 都很好。

警报操作本身在 QC 中也 运行 没问题。

simpleTrigger 工作正常。

更复杂的 运行s 如果我删除使用我自己的库的函数。

似乎触发器是由用户 运行 或来自无法找到我的模块(在模块数据库中)的地方。我已将触发器数据库设置为指向内容数据库。

触发器查看新文档的目录(文档创建)。

如果我想使用我自己的库函数,抛出的错误是:

[1.0-ml] XDMP-MODNOTFOUND: (err:XQST0059) xdmp:eval("xquery version 
"1.0-ml";

let $uri := '/marklo...", (), 
<options xmlns="xdmp:eval"><database>12436607035003930594</database>
   <modules>32519102440328...</options>) 
-- Module /lib/sccss-lib.xqy not found

该模块在 modules-db 中...

另一件困扰我的事情是 ML 文档中的示例做了

xdmp:document-insert("/modules/log.xqy", 
  text{ "
xquery version '1.0-ml';
..."
}, xdmp:permission('app-user', 'execute'))

权限应用用户在这种情况下做什么?

无论如何主要问题:如果我在触发器操作中使用自定义模块,为什么触发器不 运行?

我看过 并认为它是相关的,但我不明白那里的答案...

编辑开始,有关触发器创建语句的更多信息:

xquery version "1.0-ml";
import module namespace trgr="http://marklogic.com/xdmp/triggers" 
   at "/MarkLogic/triggers.xqy";

trgr:create-trigger("sensorTrigger", "Simple trigger for connection systems sensor, the action checks how long this device is around the sensor", 
  trgr:trigger-data-event(
      trgr:directory-scope("/marklogic.solutions.obi/source/", "1"),
      trgr:document-content("create"),
      trgr:post-commit()),
  trgr:trigger-module(xdmp:database("cluey-app-content"), "/triggers/", "check-time-at-sensor.xqy"),
  fn:true(), xdmp:default-permissions() )

此外,触发器确实是从 QC 创建的,因此确实是作为管理员创建的(我还必须弄清楚如何将代码添加到 app-specific.rb)。并且触发器操作是从 QC 加载的,带有与文档中的触发器示例等效的文档插入语句。

为了完整起见,我根据 Geert

的建议将其添加到 app-specific.rb
  alias_method :original_deploy_modules, :deploy_modules
  def deploy_modules()
    original_deploy_modules

    # and apply correct permissions
    r = execute_query %Q{
      xquery version "1.0-ml";

      for $uri in cts:uris()
      return (
        $uri,
        xdmp:document-set-permissions($uri, (
          xdmp:permission("#{@properties["ml.app-name"]}-role", "read"),
          xdmp:permission("#{@properties["ml.app-name"]}-role", "execute")
        ))
      )
    },
    { :db_name => @properties["ml.modules-db"] }
  end

为了测试,我还将它作为内容的一部分加载(使用 ./ml local deploy content 来加载它,正如之前所说的那样,它会 运行 所以权限似乎没有问题动作文档本身。我不明白的是,一旦我尝试在动作中使用我自己的模块,它就找不到模块或者(见评论大卫)没有模块的正确权限。所以触发动作会失败运行 ... 模块在/src/lib/lib.xqy

下加载roxy

第二次编辑

我通过将以下内容添加到 app_specific.rb 来添加所有触发器 stuf 以包含在 roxy 中:

  # HK voor gebruik modules die geen REST permissies hebben in een rest extension
  alias_method :original_deploy_modules, :deploy_modules
  def deploy_modules()
    original_deploy_modules

    # Create triggers
    r = execute_query(%Q{
        xquery version "1.0-ml";

        import module namespace trgr="http://marklogic.com/xdmp/triggers" 
           at "/MarkLogic/triggers.xqy";

        xdmp:log("Installing triggers.."),

        try {
          trgr:remove-trigger("sensorTrigger")
        } catch ($ignore) {
        };


        xquery version "1.0-ml";

        import module namespace trgr="http://marklogic.com/xdmp/triggers" 
           at "/MarkLogic/triggers.xqy";

        trgr:create-trigger("sensorTrigger", "Trigger to check duration at sensor", 
          trgr:trigger-data-event(
            trgr:directory-scope("/marklogic.solutions.obi/source/", "1"),
            trgr:document-content("create"),
            trgr:post-commit()
          ),
          trgr:trigger-module(xdmp:modules-database(), "/", "/triggers/check-time-at-sensor.xqy"),
          fn:true(),
          xdmp:default-permissions(),
          fn:false()
        )
      },
      ######## THIRD EDIT ###############
      #{ :app_name => @properties["ml.app-name"] }
      { :db_name => @properties["ml.modules-db"] }
    )

    # and apply correct permissions
    r = execute_query %Q{
      xquery version "1.0-ml";

      for $uri in cts:uris()
      return (
        $uri,
        xdmp:document-set-permissions($uri, (
          xdmp:permission("#{@properties["ml.app-name"]}-role", "read"),
          xdmp:permission("#{@properties["ml.app-name"]}-role", "execute")
        ))
      )
    },
    { :db_name => @properties["ml.modules-db"] }
  end

如您所见,根路径现在是行中的“/”

trgr:trigger-module(xdmp:modules-database(), "/", "/triggers/check-time-at-sensor.xqy")

我也手动添加了权限,但是只要我添加指向 sccs-lib.xqy 的行,我的触发器就会失败...

能否提供更多信息 - 比如整个触发器创建语句?

创建触发器时,请记住:

  1. 您插入触发器的触发器数据库必须是您在触发器中引用的内容数据库中定义的数据库,并且
  2. trgr:trigger-module允许您定义模块数据库和模块到运行。正确定义后,我看不出如何找不到 /lib/sccss-lib.xqy - 除非它是一个权限项...

现在谈谈您问题中的另一项:您在查询控制台中测试内容。它具有该用户的角色 - 通常 运行 作为管理员...如果文档存在,MarkLogic 也会给出 'not found' 消息 - 而你根本无权访问它。所以,有可能是你的modules数据库中的文档权限有问题。

要使触发器正常工作,需要满足许多条件。大卫已经提到了其中的一部分。让我尝试完成列表:

  • 您需要一个包含触发器定义的数据库。那是执行 trgr:create-trigger 的数据库。通常 Triggers 或一些 app-triggers.
  • 需要将该触发器数据库指定为内容数据库的触发器数据库(而不是相反!)。
  • 您指向一个触发器模块,其中包含将在触发事件发生时立即执行的代码。 trgr:trigger-module 明确指向模块的 uri,以及包含它的数据库。
  • 该触发器模块使用的任何库都需要与触发器模块位于同一数据库中。通常触发器模块和相关库都存储在 Modules 或某些 app-modules.

关于权限,以下内容适用:

  • 首先,您需要插入文档(uri 和集合)的权限。
  • 然后,为了能够执行触发器,执行插入的用户需要具有对触发器模块以及所有模块具有读取和执行权限的角色(直接、继承或通过 amps)相关图书馆。
  • 然后同一用户需要有权限来执行触发器模块需要执行的任何操作。

查看您的创建触发器语句,我注意到触发器模块指向应用程序内容数据库。这意味着它也会在应用程序内容数据库中寻找库。我建议将触发器模块和库放在应用程序模块数据库中。

此外,关于 app-user 执行权限:这只是一个约定。 nobody 用户具有 app-user 角色。这通常用于允许 nobody 用户 运行 重写代码。

HTH!