Skip to content

Allow MVA→SVA import attribute flow with first-value selection and RPEI warning #435

@JayVDZ

Description

@JayVDZ

Summary

When an RFC-compliant LDAP directory (e.g., OpenLDAP) is used as a source system, many standard attributes (uid, givenName, sn, departmentNumber, mail) are multi-valued per RFC 4512/4519 — they lack the SINGLE-VALUE keyword. JIM currently rejects direct attribute mappings from these multi-valued source attributes to single-valued Metaverse attributes at mapping creation time (both in the UI and API), forcing administrators to use expression mappings as a workaround.

This is unnecessarily clunky. In practice, these attributes almost always contain a single value. JIM should allow the mapping and handle the edge case gracefully at runtime.

Current Behaviour

Three layers enforce the MVA→SVA restriction:

1. UI — attribute flow target dropdowns (SyncRuleDetail.razor)

  • Import rules (line 1349-1352): IsAttributeFlowTargetDisabled() disables SVA metaverse attributes when the source CS attribute is multi-valued
  • Export rules (line 1374-1377): Same logic in reverse — disables SVA CS attributes when the source MV attribute is multi-valued
  • Matching rules (lines 341-342, 357-358): Only show SVA attributes — this is correct and should remain unchanged (join matching requires deterministic single values)

2. API — mapping validation (ConnectedSystemServer.cs)

  • ValidateMappingTypeCompatibility() (line 3620) throws ArgumentException when a multi-valued source is mapped to a single-valued target
  • Expression-based mappings skip this validation (line 3568)

3. Runtime — attribute flow (SyncEngine.AttributeFlow.cs)

  • ProcessTextAttribute() etc. iterate over ALL CSO attribute values and add ALL to the MVO — no plurality guard at runtime
  • BuildCsoAttributeDictionary() (line 554) silently takes the first value for expressions (if (!attributes.ContainsKey(attributeName)))

Proposed Behaviour

1. Relax UI validation

In SyncRuleDetail.razor, remove the MVA→SVA disabled logic from IsAttributeFlowTargetDisabled() for both import and export attribute flow rules. Optionally show a visual hint (e.g., info icon/tooltip) when an MVA source is mapped to an SVA target, explaining that the first value will be used.

Matching rules should remain SVA-only — join matching requires deterministic single values.

2. Relax API validation

In ConnectedSystemServer.ValidateMappingTypeCompatibility(), remove the ArgumentException throw for MVA→SVA. SVA→MVA is already allowed.

3. Runtime first-value selection with RPEI warning

In the attribute flow methods (ProcessTextAttribute, ProcessNumberAttribute, etc. in SyncEngine.AttributeFlow.cs):

  • When the source attribute has multiple values and the target is single-valued, take the first value
  • Return a warning to the caller so it can be surfaced as a low-severity RPEI

4. RPEI warning visibility

Thread warnings from the pure domain layer (SyncEngine) back to the caller (SyncTaskProcessorBase) so they can be surfaced as low-severity RPEIs:

  • Add a new ActivityRunProfileExecutionItemErrorType value (e.g., MultiValuedAttributeTruncated) for informational warnings
  • The RPEI should include: attribute name, value count, which value was selected
  • This is informational — the sync succeeded, but the administrator should be aware in case the wrong value was selected

SyncEngine.FlowInboundAttributes is currently void. To surface warnings, either:

  • Change return type to List<AttributeFlowWarning> (or similar)
  • Or add a warnings collection parameter that the method populates

The caller in SyncTaskProcessorBase would then map warnings to RPEIs.

Confirming imports — no change needed

Confirming imports (reading back exported values after export) are already safe for MVA targets. ValueExistsOnCso() in SyncEngine.Reconciliation.cs uses .Any() to check if the exported value exists anywhere in the CSO's attribute value list, regardless of ordering or additional values.

Files to modify

UI:

  • src/JIM.Web/Pages/Admin/SyncRuleDetail.razor — remove MVA→SVA disabled logic from IsAttributeFlowTargetDisabled() (both import and export overloads); optionally add info tooltip

API:

  • src/JIM.Application/Servers/ConnectedSystemServer.cs — relax ValidateMappingTypeCompatibility() to allow MVA→SVA

Runtime:

  • src/JIM.Application/Servers/SyncEngine.AttributeFlow.cs — add plurality check and first-value selection in ProcessTextAttribute, ProcessNumberAttribute, etc.
  • src/JIM.Application/Servers/SyncEngine.cs — change FlowInboundAttributes to return/populate warnings
  • src/JIM.Application/Interfaces/ISyncEngine.cs — update interface

Worker:

  • src/JIM.Worker/Processors/SyncTaskProcessorBase.cs — consume warnings from SyncEngine, create RPEIs

Models:

  • src/JIM.Models/Activities/ActivityRunProfileExecutionItemErrorType.cs — new warning type

Tests:

  • test/JIM.Web.Api.Tests/ConnectedSystemServerMappingValidationTests.cs — update validation tests (MVA→SVA should now pass)
  • test/JIM.Worker.Tests/ — unit tests for first-value selection and warning generation

Context

Discovered during OpenLDAP integration testing (#72, Phase 6). OpenLDAP's RFC 4512 schema marks uid, givenName, sn, departmentNumber, and mail as multi-valued. Only displayName and employeeNumber have SINGLE-VALUE. The current validation prevented creating import sync rules for the majority of standard person attributes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions