1

私は現在、ScriptedRest2DJ サンプルに基づくGroovy フレームワーク コネクタを使用して、外部システムをプロビジョニングするための独自のOpenidm コネクタを構築しています。

ターゲット システムでリソース (ユーザー) を検索するためにsearchScript.groovyファイルを実装しており、リクエストでソース システムの現在のユーザー UID を渡したいと考えています。

SearchScript.groovy のソース コードは次のとおりです。

import groovyx.net.http.RESTClient
import org.apache.http.client.HttpClient
import org.forgerock.openicf.connectors.scriptedrest.ScriptedRESTConfiguration
import org.forgerock.openicf.misc.scriptedcommon.OperationType
import org.identityconnectors.common.logging.Log
import org.identityconnectors.framework.common.objects.Attribute
import org.identityconnectors.framework.common.objects.AttributeUtil
import org.identityconnectors.framework.common.objects.Name
import org.identityconnectors.framework.common.objects.ObjectClass
import org.identityconnectors.framework.common.objects.OperationOptions
import org.identityconnectors.framework.common.objects.SearchResult
import org.identityconnectors.framework.common.objects.Uid
import org.identityconnectors.framework.common.objects.filter.Filter
import org.identityconnectors.framework.common.objects.AttributesAccessor

import static groovyx.net.http.Method.GET
import static groovyx.net.http.ContentType.JSON;

// imports used for CREST based REST APIs
import org.forgerock.openicf.misc.crest.CRESTFilterVisitor
import org.forgerock.openicf.misc.crest.VisitorParameter

def operation = operation as OperationType
def configuration = configuration as ScriptedRESTConfiguration
def httpClient = connection as HttpClient
def connection = customizedConnection as RESTClient
def filter = filter as Filter
def log = log as Log
def objectClass = objectClass as ObjectClass
def options = options as OperationOptions
def resultHandler = handler

log.info("Entering " + operation + " Script")

switch (objectClass) {
    case ObjectClass.ACCOUNT:
        // Search for a specific user in Alfresco
        // http://docs.alfresco.com/community/references/RESTful-PersonPersonGet.html
        def searchResult = connection.request(GET, JSON) { req ->
            uri.path = 'people'

            headers.Accept = 'application/json'

            response.success = { resp, json ->
                json.people.each() { value ->
                    resultHandler {
                        uid value.userName
                        id value.userName
                        attribute 'email', value?.email
                        attribute 'lastName', value?.lastName
                        attribute 'userName', value?.userName
                        attribute 'firstName', value?.firstName
                        attribute 'enabled', value?.enabled
                        //attribute ('groups', *(value?.groups))
                    }
                }
                json
            }
        }

        return new SearchResult(null, -1) // no remaining results
}

スクリプト内のソース値にどのようにアクセスできますか? Uid、Id、Name などをテストしましたが、成功しませんでした。

助けてくれてありがとう

4

1 に答える 1

2

SearchScript が単純にすべてのユーザーを返す以上のことを行うには、「フィルター」オブジェクトを利用する必要があります。スクリプトで宣言していますが、使用していません。これは、コネクタがこのスクリプトがバックエンドで実行する必要がある「検索」の種類を知るために必要なすべての詳細を含むオブジェクトです (このスクリプトの REST を介して)場合)。フィルタ オブジェクトは本質的にツリー構造であり、その用途は「訪問者パターン」に基づいています。

コードのベースとなる scriptedrest2dj サンプルは、CRESTFilterVisitor の使用法を示しています。これは、OpenDJ (そのサンプルのターゲット) での作業に特に役立つ特別なものです。より汎用的なビジターの実装については、sample3 の SearchScript.groovy を参照することをお勧めします。Sample3 は SQL バックエンドを操作する例ですが、そこに示されているビジターを使用して、任意のタイプのクエリ文字列 (REST サービスに渡すものなど) を生成できます。

sample3 のフィルター コードから、これはフィルター ツリーを表す通常の値のマップを返します。

def query = filter.accept(MapFilterVisitor.INSTANCE, null)

単純な値のこのマップの構造は次のとおりです (例: field eq "value") :

[ 
    "operation": "EQUALS|CONTAINS|STARTSWITH|ENDSWITH",
    "not": "true|false",
    "left": "fieldName",
    "right": "value"
]

ここでの「左」と「右」は、方程式の辺と考えることができます。'Id eq "bob"' の場合、左が「Id」、右が「bob」になります。「操作」は「EQUALS」になります。

さらに複雑な式の構造は次のとおりです (例: simpleExpr AND simpleExpr):

[ 
    "operation": "AND|OR",
    "left": "simpleExpression|complexExpression",
    "right": "simpleExpression|complexExpression"
]

ここでわかるように、このマップ構造内で任意に複雑なブール式を表すことができます。特定のケースでサポートしたい複雑さに応じて、完全に再帰的な式ビルダー (サンプル 3 に示されているものなど) をサポートするか、コア ケースのみをサポートするかを選択できます。

スクリプトで処理できる操作の種類の例を次に示します。

GET /openidm/system/scriptedrest/account?_queryId=query-all-ids

  • これは基本的にあなたが今持っているものです。この操作を行うと、「フィルター」オブジェクトは null になるため、何もフィルタリングする必要はありません。

GET /openidm/system/scriptedrest/account/bob

  • これは「読み取り」操作ですが、SearchScript によっても実装されます。__UID__「読み取り」は、特定の値に対する単純なフィルターとまったく同じです。これを実現する手っ取り早い方法は、(前述のように) フィルター オブジェクトをマップに変換し、次の__UID__ように特定の を検索するフィルターのみがマップに含まれると想定することです。

    def uid = query.get('right')

次に、これを REST 呼び出しに渡すことができます (おそらく、それを uri.path 変数に追加することによって)。

理想的には、検索スクリプトは次のようなより複雑なフィルターを処理できる必要があります。

GET /openidm/system/scriptedrest/account?_queryFilter=/email eq "bob@bob.com"

  • これは、特定の値を持つレコードのより一般的な検索です。REST バックエンドはそのようなことをサポートする必要があり、フィルター クエリ ビルダーは適切なクエリ文字列を構築するためにツリーをたどることができる必要があります。このコネクタで何をする必要があるかによっては、必要ない場合があります。
于 2015-03-24T19:07:53.447 に答える