1

xdmp:invoke 呼び出しを使用して、セキュリティ データベースに新しいロールを作成しています。インボーク呼び出しのオプションとして、次のオプションを指定しました。

<options xmlns="xdmp:eval">
  <database>{ xdmp:security-database() }</database>
  <transaction-mode>update</transaction-mode>
  <isolation>different-transaction</isolation>
  <prevent-deadlocks>false</prevent-deadlocks>
</options>

私の考えでは、これは別のトランザクションで実行され、この呼び出しに続くコードの変更にアクセスできるようになります。しかし、作成したばかりのロールの名前を使用して xdmp:permission() をすべて作成すると、Role Does Not Exist エラーが発生します。

これを解決する方法はありますか?

アップデート

次のスニペットは機能します。したがって、より複雑なコードに他の問題があるかどうかを確認するために、さらにトラブルシューティングを行います。

xquery version "1.0-ml";

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

let $create_role :=
  xdmp:invoke-function(
    function() {
      sec:create-role(
        'sec_test',
        'Security Test Role',
        (),
        (),
        ()
      )
    },
    <options xmlns="xdmp:eval">
      <database>{xdmp:security-database()}</database>
      <transaction-mode>update-auto-commit</transaction-mode>
      <isolation>different-transaction</isolation>
    </options>
  )

return xdmp:permission('sec_test', 'read')

2回目の更新

create-role を実行するために呼び出している関数が別の xqy ファイルにある場合、ロールが見つからないというエラーで失敗するようです。たとえば、security-util.xqy に次のモジュールがあります。

xquery version "1.0-ml";
module namespace asu = "http://ir.abbvie.com/marklogic/authorization/lib/security-util";

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

declare option xdmp:mapping "false";

declare function asu:create-role-2(
  $role_name as xs:string
)
{
  xdmp:invoke-function(
    function() {
      sec:create-role(
        $role_name,
        "Role auto created by AbbVie authorization library.",
        (),
        (),
        ()
      )
    },
    <options xmlns="xdmp:eval">
      <database>{ xdmp:security-database() }</database>
      <transaction-mode>update-auto-commit</transaction-mode>
      <isolation>different-transaction</isolation>
    </options>
  )
};

そして、クエリコンソールから呼び出すと:

xquery version "1.0-ml";

import module namespace asu =    "http://ir.abbvie.com/marklogic/authorization/lib/security-util"
  at "security-util.xqy";

asu:create-role-2('sec_test7'), xdmp:permission('sec_test7', 'read')

それはエラーになりますが、次のようにするとうまくいきます:

xquery version "1.0-ml";

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

declare function local:create-role(
  $role_name as xs:string
)
{
  xdmp:invoke-function(
    function() {
      sec:create-role(
        $role_name,
        "Security Test Role",
        (),
        (),
        ()
      )
    },
    <options xmlns="xdmp:eval">

      <database>{ xdmp:security-database() }</database>
      <transaction-mode>update-auto-commit</transaction-mode>
      <isolation>different-transaction</isolation>
    </options>
  )
};

local:create-role('sec_test8'), xdmp:permission('sec_test8', 'read')
4

2 に答える 2

5

同様に、invoke-function を介してパーミッションを取得することを検討してください。別のトランザクションでロールを作成しているため、現在のリクエストはそのコミット前のデータベースの状態を調べている可能性があります。これは、非ロック クエリ モードをサポートするために MarkLogic が使用する MVCC モデルの一部です。

また、遅延評価がコードを妨害している可能性もあります。シーケンス内のサブ式 (コンマ区切りなど) は並列で実行できます。FLWOR から let-return を使用して順序を強制します。

チッ!

于 2016-02-10T09:29:24.070 に答える
1

実際にロールが作成されたことを確認しましたか? 実際に作成されていない場合は、トランザクション モードを「update-auto-commit」に変更してみてください。ロールを追加するトランザクションが実際にはコミットされていないと思われます。

また、ロールを作成するだけの場合は、次のようなものを使用する方が簡単な場合があります。これにより、小さなコードに対して別の .xqy を定義する必要がなくなります。

xdmp:invoke-function(
  function() { sec:create-role(...) },
  <options xmlns="xdmp:eval">
    <database>{xdmp:security-database()}</database>
    <transaction-mode>update-auto-commit</transaction-mode>
    <isolation>different-transaction</isolation>
  </options>)
于 2016-02-10T05:24:34.840 に答える