Диаграммы последовательностей работы коннектора SCIM 2.0#

Данный документ содержит диаграммы последовательностей (PlantUML), описывающие алгоритмы работы коннектора SCIM 2.0 (IDMC Connector).

Тестирование подключения (test)#

@startuml
title Диаграмма последовательности: Тестирование подключения

participant "IDM Framework" as Framework
participant "ScimConnector" as Connector
participant "TestHandler" as TestH
participant "ScimClient" as Client
participant "SCIM Server" as Server

Framework -> Connector: test()
activate Connector

Connector -> TestH: test()
activate TestH

TestH -> Client: getServiceProviderConfig()
activate Client
Client -> Server: GET /ServiceProviderConfig
Server --> Client: ServiceProviderConfig JSON
Client --> TestH: OK
deactivate Client

alt проверка успешна
    TestH --> Connector: OK
else ошибка
    TestH -> TestH: processException()
    TestH --> Connector: ConnectorException
end

deactivate TestH
Connector --> Framework: OK
deactivate Connector
@enduml

Получение схемы (schema)#

@startuml
title Диаграмма последовательности: Получение схемы объектов

participant "IDM Framework" as Framework
participant "ScimConnector" as Connector
participant "SchemaHandler" as SchemaH
participant "ResourceTypesProvider" as RTP
participant "SchemasProvider" as SP
participant "TypeMappingRegistry" as Registry
participant "SchemaParser" as Parser
participant "SCIM Server" as Server

Framework -> Connector: schema()
activate Connector

Connector -> SchemaH: schema()
activate SchemaH

SchemaH -> RTP: getResourceTypes()
activate RTP
RTP -> Server: GET /ResourceTypes
Server --> RTP: ResourceTypeResource[]
RTP --> SchemaH: resourceTypes
deactivate RTP

SchemaH -> SP: getScimSchemas()
activate SP
SP -> Server: GET /Schemas
Server --> SP: SchemaResource[]
SP --> SchemaH: schemas
deactivate SP

SchemaH -> SchemaH: создать map schemas by id

SchemaH -> Registry: clear()
activate Registry

loop для каждого ResourceType
    SchemaH -> SchemaH: получить TypeMappingConfiguration
    SchemaH -> Parser: new SchemaParser(config)
    activate Parser
    
    SchemaH -> Parser: parse(baseSchema, extensionSchemas)
    activate Parser
    Parser -> Parser: распарсить атрибуты схемы
    Parser -> Parser: создать AttributeMapping для каждого атрибута
    Parser --> SchemaH: attributeInfos, attributeMappings
    deactivate Parser
    
    SchemaH -> SchemaH: создать ObjectClassInfo
    SchemaH -> Registry: putTypeInfo(typeName, typeMapping)
end

SchemaH --> Connector: Schema
deactivate SchemaH
Connector --> Framework: Schema
deactivate Connector
@enduml

Создание объекта (create)#

@startuml
title Диаграмма последовательности: Создание объекта (create)

participant "IDM Framework" as Framework
participant "ScimConnector" as Connector
participant "CreateHandler" as CreateH
participant "TypeMappingRegistry" as Registry
participant "ScimClient" as Client
participant "SCIM Server" as Server

Framework -> Connector: create(objectClass, attributes, options)
activate Connector

Connector -> CreateH: create(objectClass, attributes, options)
activate CreateH

CreateH -> Registry: getForObjectClass(objectClass)
Registry --> CreateH: TypeMapping

CreateH -> CreateH: получить attributeMappings из TypeMapping
CreateH -> CreateH: создать GenericScimResource (ObjectNode)

CreateH -> CreateH: добавить schemas в resource
loop для каждого AttributeMapping
    CreateH -> CreateH: найти Attribute по имени
    alt атрибут найден
        CreateH -> CreateH: setValueByPath(objectNode, attribute, mapping)
    end
end

alt sendNullValues == true
    CreateH -> CreateH: fillAttributesWithNullValues()
end

CreateH -> Registry: getResourceType().getEndpoint()
Registry --> CreateH: endpoint (например, "/Users")

CreateH -> Client: create(endpoint, scimResource)
activate Client
Client -> Server: POST {endpoint}\nContent-Type: application/scim+json\n{resource}
Server --> Client: Created Resource JSON (с id)
Client --> CreateH: created Resource
deactivate Client

CreateH -> CreateH: new Uid(created.getId())
CreateH --> Connector: Uid
deactivate CreateH
Connector --> Framework: Uid
deactivate Connector
@enduml

Поиск объектов (executeQuery)#

@startuml
title Диаграмма последовательности: Поиск объектов (executeQuery)

participant "IDM Framework" as Framework
participant "ScimConnector" as Connector
participant "SearchHandler" as SearchH
participant "TypeMappingRegistry" as Registry
participant "ScimClient" as Client
participant "SCIM Server" as Server
participant "ResultsHandler" as Handler

Framework -> Connector: executeQuery(objectClass, filter, handler, options)
activate Connector

Connector -> SearchH: executeQuery(objectClass, filter, handler, options)
activate SearchH

SearchH -> Registry: getForObjectClass(objectClass)
Registry --> SearchH: TypeMapping

SearchH -> SearchH: getSearchEvaluator()
alt isUidFilter(filter)
    SearchH -> SearchH: new UidSearchEvaluator()
else isPaginationOptionPresent(options)
    SearchH -> SearchH: new PaginatedSearchEvaluator()
else isUsernameFilter(filter)
    SearchH -> SearchH: new UsernameSearchEvaluator()
else
    SearchH -> SearchH: new DefaultSearchEvaluator()
end

SearchH -> SearchEvaluator: search()
activate SearchEvaluator

loop для каждой страницы
    SearchEvaluator -> SearchEvaluator: создать SearchRequest\n(filter, startIndex, count)
    SearchEvaluator -> Registry: getEndpoint()
    Registry --> SearchEvaluator: endpoint
    
    SearchEvaluator -> Client: search(endpoint, searchRequest)
    activate Client
    Client -> Server: GET {endpoint}?filter={filter}&startIndex={n}&count={k}
    Server --> Client: ListResponse JSON
    Client --> SearchEvaluator: ListResponse
    deactivate Client
    
    loop для каждого ресурса в ответе
        SearchEvaluator -> SearchEvaluator: преобразовать в ConnectorObject
        SearchEvaluator -> Handler: handle(connectorObject)
    end
    
    SearchEvaluator -> SearchEvaluator: проверить totalResults
    alt есть ещё страницы
        SearchEvaluator -> SearchEvaluator: увеличить startIndex
    else
        SearchEvaluator -> SearchEvaluator: завершить
    end
end

SearchEvaluator --> SearchH: OK
deactivate SearchEvaluator
SearchH --> Connector: OK
deactivate SearchH
Connector --> Framework: OK
deactivate Connector
@enduml

Поиск по UID (UidSearchEvaluator)#

@startuml
title Диаграмма последовательности: Поиск по UID (GET /{type}/{id})

participant "SearchHandler" as SearchH
participant "UidSearchEvaluator" as Evaluator
participant "ScimClient" as Client
participant "SCIM Server" as Server
participant "ResultsHandler" as Handler

SearchH -> Evaluator: search()
activate Evaluator

Evaluator -> Evaluator: извлечь id из filter (id eq "...")
Evaluator -> Registry: getEndpoint()
Registry --> Evaluator: endpoint

Evaluator -> Client: retrieve(endpoint, id)
activate Client
Client -> Server: GET {endpoint}/{id}
Server --> Client: Resource JSON
Client --> Evaluator: GenericScimResource
deactivate Client

Evaluator -> Evaluator: преобразовать в ConnectorObject
Evaluator -> Handler: handle(connectorObject)

Evaluator --> SearchH: OK
deactivate Evaluator
@enduml

Обновление объекта через PATCH (updateDelta)#

@startuml
title Диаграмма последовательности: Обновление через PATCH (updateDelta)

participant "IDM Framework" as Framework
participant "ScimConnector" as Connector
participant "PatchUpdateDeltaHandler" as DeltaH
participant "TypeMappingRegistry" as Registry
participant "ScimClient" as Client
participant "SCIM Server" as Server

Framework -> Connector: updateDelta(objectClass, uid, modifications, options)
activate Connector

Connector -> DeltaH: updateDelta(objectClass, uid, modifications, options)
activate DeltaH

DeltaH -> Registry: getForObjectClass(objectClass)
Registry --> DeltaH: TypeMapping
DeltaH -> Registry: getResourceType()
Registry --> DeltaH: ResourceTypeResource

DeltaH -> DeltaH: создать PatchRequest из modifications
loop для каждого AttributeDelta
    alt valuesToReplace != null
        DeltaH -> DeltaH: создать PatchOperation REPLACE
    else valuesToAdd != null
        DeltaH -> DeltaH: создать PatchOperation ADD
    else valuesToRemove != null
        DeltaH -> DeltaH: создать PatchOperation REMOVE
    end
end

DeltaH -> Client: update(endpoint, uid, patchRequest)
activate Client
Client -> Server: PATCH {endpoint}/{id}\nContent-Type: application/scim+json\n{patchRequest}
Server --> Client: Updated Resource JSON
Client --> DeltaH: updated Resource
deactivate Client

DeltaH --> Connector: empty Set<AttributeDelta>
deactivate DeltaH
Connector --> Framework: OK
deactivate Connector
@enduml

Обновление объекта через PUT (UpdateHandler - устаревший)#

@startuml
title Диаграмма последовательности: Обновление через PUT (UpdateHandler)

participant "IDM Framework" as Framework
participant "ScimConnector" as Connector
participant "UpdateHandler" as UpdateH
participant "TypeMappingRegistry" as Registry
participant "ScimClient" as Client
participant "SCIM Server" as Server

Framework -> Connector: update(objectClass, uid, attributes, options)
activate Connector

Connector -> UpdateH: update(objectClass, uid, attributes, options)
activate UpdateH

UpdateH -> Registry: getForObjectClass(objectClass)
Registry --> UpdateH: TypeMapping
UpdateH -> Registry: getResourceType().getEndpoint()
Registry --> UpdateH: endpoint

UpdateH -> Client: retrieve(endpoint, uid.getUidValue())
activate Client
Client -> Server: GET {endpoint}/{id}
Server --> Client: Existing Resource JSON
Client --> UpdateH: resource
deactivate Client

UpdateH -> UpdateH: получить objectNode из resource
UpdateH -> UpdateH: создать map атрибутов

loop для каждого AttributeMapping
    UpdateH -> UpdateH: найти атрибут для замены
    alt атрибут найден
        UpdateH -> UpdateH: setValueByPath(objectNode, attribute, mapping)
    end
end

UpdateH -> Client: update(endpoint, id, resource)
activate Client
Client -> Server: PUT {endpoint}/{id}\nContent-Type: application/scim+json\n{resource}
Server --> Client: Updated Resource JSON
Client --> UpdateH: updated Resource
deactivate Client

UpdateH -> UpdateH: new Uid(updated.getId())
UpdateH --> Connector: Uid
deactivate UpdateH
Connector --> Framework: Uid
deactivate Connector
@enduml

Удаление объекта (delete)#

@startuml
title Диаграмма последовательности: Удаление объекта (delete)

participant "IDM Framework" as Framework
participant "ScimConnector" as Connector
participant "DeleteHandler" as DeleteH
participant "TypeMappingRegistry" as Registry
participant "ScimClient" as Client
participant "SCIM Server" as Server

Framework -> Connector: delete(objectClass, uid, options)
activate Connector

Connector -> DeleteH: delete(objectClass, uid, options)
activate DeleteH

DeleteH -> Registry: getForObjectClass(objectClass)
Registry --> DeleteH: TypeMapping
DeleteH -> Registry: getResourceType().getEndpoint()
Registry --> DeleteH: endpoint

DeleteH -> Client: delete(endpoint, uid.getUidValue())
activate Client
Client -> Server: DELETE {endpoint}/{id}
Server --> Client: 204 No Content
Client --> DeleteH: OK
deactivate Client

DeleteH --> Connector: OK
deactivate DeleteH
Connector --> Framework: OK
deactivate Connector
@enduml

Управление ресурсами (ResourceTypesProvider)#

@startuml
title Диаграмма последовательности: Получение ResourceTypes

participant "SchemaHandler" as SchemaH
participant "RemoteResourceTypesProvider" as Provider
participant "ScimClient" as Client
participant "SCIM Server" as Server

SchemaH -> Provider: getResourceTypes()
activate Provider

Provider -> Client: getResourceTypes()
activate Client
Client -> Server: GET /ResourceTypes
Server --> Client: ResourceTypeResource[]
Client --> Provider: resourceTypes
deactivate Client

Provider --> SchemaH: ResourceTypeResource[]
deactivate Provider
@enduml

Конфигурация источников схемы#

@startuml
title Диаграмма последовательности: Выбор источника схемы

participant "SchemaHandler" as SchemaH
participant "SchemasProvider" as Provider
participant "ScimConnectorConfiguration" as Config
participant "RemoteSchemasProvider" as Remote
participant "FileSchemasProvider" as File
participant "PropertySchemasProvider" as Property
participant "ScimClient" as Client
participant "SCIM Server" as Server

SchemaH -> Provider: getScimSchemas()
activate Provider

alt schemasSource == "REMOTE"
    SchemaH -> Remote: new RemoteSchemasProvider(client)
    Remote -> Client: getSchemas()
    Client -> Server: GET /Schemas
    Server --> Client: SchemaResource[]
    Client --> Remote: schemas
    Remote --> SchemaH: schemas
else schemasSource == "FILE"
    SchemaH -> File: new FileSchemasProvider(config)
    File -> File: прочитать файл schemasFile
    File --> SchemaH: schemas
else schemasSource == "PROPERTY"
    SchemaH -> Property: new PropertySchemasProvider(config)
    Property -> Property: распарсить schemasJson
    Property --> SchemaH: schemas
end

deactivate Provider
@enduml