触发器无法运行(添加更多信息)

时间:2015-09-11 23:59:03

标签: triggers marklogic marklogic-8

我几个小时以来一直在修补这个触发器,我想我现在就确定了这个问题。

我已在ML8 documentation中设置了一个示例触发器。

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

问题似乎是我使用了一个在lib.xqy中保存我自己的函数的库模块。我在Query Console中测试了lib本身,所有函数运行正常。

警报操作本身也可以在QC中正常运行。

simpleTrigger工作正常。

如果我删除了使用我自己的lib的函数,那么运行得越复杂。

似乎触发器是由用户或无法找到我的模块的地方(在模块db中)运行的。我已将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'))

在这种情况下,权限应用程序用户会做什么?

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

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

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

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本地部署内容加载它,如操作之前所说的那样它将运行,因此动作文档本身的权限似乎没有问题。我不明白的是,当我尝试在操作中使用我自己的模块时,它无法找到模块或(请参阅注释David)对模块没有正确的权限。因此触发操作将无法运行...模块在/src/lib/lib.xqy

下加载了roxy

第二次编辑

我添加了所有触发器stuf以包含在roxy中,方法是将以下内容添加到app_specific.rb中:

  # 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

正如您所见,根路径现在是&#34; /&#34;在行

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

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

2 个答案:

答案 0 :(得分:0)

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

要创建触发器,请记住:

  1. 您插入触发器的触发器数据库必须是您在触发器中引用的内容数据库中定义的触发器数据库,并且
  2. trgr:trigger-module允许您定义模块数据库和要运行的模块。正确定义后,我无法看到如何找不到/lib/sccss-lib.xqy - 除非它是权限项...
  3. 现在转到问题中的另一项:您在查询控制台中测试内容。它具有该用户的角色 - 通常由人员作为管理员运行...... MarkLogic给出了一个未找到的用户#39;如果文档存在,也会显示消息 - 而您根本无法访问它。因此,模块数据库中的文档权限可能存在问题。

答案 1 :(得分:0)

触发器正常工作需要满足一些条件。大卫已经提到了部分内容。让我试着完成清单:

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

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

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

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

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

HTH!