1

我已经修补这个触发器几个小时了,我想我现在已经查明了这个问题。

我在ML8 文档中设置了一个示例触发器。

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

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

警报操作本身在 QC 中也运行良好。

simpleTrigger 工作正常。

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

似乎触发器是由用户运行或从找不到我的模块的地方(在模块数据库中)运行的。我已将 trigger-db 设置为指向 content-db。

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

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

[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 doc 中的示例

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 加载的,其中包含与文档中的触发器示例等效的 doc insert 语句。

为了完整起见,我根据 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 本地部署内容来加载它,正如在操作之前所说的那样,它将运行,因此操作文档本身的权限似乎没有问题。我做什么不明白的是,一旦我尝试在操作中使用我自己的模块,它就找不到模块,或者(见评论大卫)对模块没有正确的权限。所以触发操作将无法运行......该模块在 /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 的行,我的触发器就会失败......

4

2 回答 2

0

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

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

关于权限,以下适用:

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

查看您的 create-triggers 语句,我注意到触发器模块指向 app-content 数据库。这意味着它也会在 app-content 数据库中寻找库。我建议将触发器模块和库放在 app-modules 数据库中。

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

于 2015-09-14T07:13:46.820 回答
0

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

要创建触发器,请记住:

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

现在转到您问题中的另一项:您在查询控制台中测试内容。这具有该用户的角色 - 通常由人们以管理员身份运行......如果文档存在,MarkLogic 也会给出“未找到”消息 - 而您根本无法访问它。因此,您的模块数据库中的文档的权限可能存在问题。

于 2015-09-12T00:29:56.820 回答