我目前正在构建自己的 Openidm连接器,以便使用基于ScriptedRest2DJ示例的 Groovy框架连接器来配置外部系统。
我正在实施 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,......但没有成功。
感谢您的帮助
答案 0 :(得分:2)
为了让您的SearchScript做的不仅仅是返回所有用户,您需要使用"过滤器"宾语。你已经在脚本中声明了它,但是你没有使用它 - 这个对象具有连接器需要知道的所有细节"搜索"这个脚本应该在后端进行(在这种情况下通过REST)。过滤器对象本质上是树结构,它们的预期用途基于" Visitor Pattern。"
您基于代码的scriptedrest2dj示例显示了CRESTFilterVisitor的使用,这是一个特殊的,对于使用OpenDJ(该示例的目标)特别有用。对于更通用的访问者实现,我建议查看sample3&#39的SearchScript.groovy。 Sample3是使用SQL后端的示例,但是那里显示的访问者可以用于生成任何类型的查询字符串(例如您可能传递给REST服务的字符串)。
从sample3的过滤器代码中,这将返回表示过滤器树的常规值映射:
def query = filter.accept(MapFilterVisitor.INSTANCE, null)
这是简单值的地图结构(例如,字段eq"值"):
[
"operation": "EQUALS|CONTAINS|STARTSWITH|ENDSWITH",
"not": "true|false",
"left": "fieldName",
"right": "value"
]
"左"和"对"这里可以被认为是等式的一部分。在以下情况下:' Id eq" bob"'左边将是" Id"并且权利将是" bob"。 "操作"将是" EQUALS"。
这是更复杂表达式的结构(例如simpleExpr和simpleExpr):
[
"operation": "AND|OR",
"left": "simpleExpression|complexExpression",
"right": "simpleExpression|complexExpression"
]
正如您在此处所看到的,您可以在此地图结构中显示任意复杂的布尔表达式。根据您在特定情况下需要支持的复杂程度,您可以选择支持完全递归的表达式构建器(如示例3中所示),或者您可以简单地支持核心案例。
以下是您的脚本应该能够处理的各种操作的一些示例:
GET /openidm/system/scriptedrest/account?_queryId=query-all-ids
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"