Domain Protocols
Relevant source files
The following files were used as context for generating this wiki page:
Domain Protocols in the flext-target-ldap project define the structured interaction between Singer-formatted input data and the target LDAP directory. The project utilizes a tiered architecture where generic Singer protocols are specialized into LDAP-specific operations through a series of "Sinks." These protocols ensure that incoming data records—representing users, groups, or organizational units—are correctly transformed into LDAP entries with valid Distinguished Names (DNs) and attributes.
The system relies on a facade pattern, primarily implemented in FlextTargetLdap, to orchestrate the lifecycle of these protocols, including setup, record processing, and teardown. It leverages the flext-core and flext-ldap libraries to enforce strict typing and unified domain models.
Sources: src/flext_target_ldap/api.py:33-40, src/flext_target_ldap/models.py:27-32, README.md:14-16
Protocol Architecture and Sinks
The core of the domain protocol is the Sink hierarchy. Each Sink is responsible for handling a specific stream of data (e.g., "users" or "groups") and translating Singer RECORD messages into LDAP operations.
Sink Hierarchy
The architecture follows a specialized inheritance pattern:
- FlextTargetLdapSink: The base interface providing Singer protocol compatibility.
- FlextTargetLdapBaseSink: Provides common LDAP functionality, such as client setup, batch processing, and entry persistence logic.
- Specialized Sinks:
FlextTargetLdapUsersSink,FlextTargetLdapGroupsSink, andFlextTargetLdapOrganizationalUnitsSinkimplement stream-specific logic for DN construction and attribute mapping.
The diagram shows the inheritance structure used to specialize Singer record processing for different LDAP entry types.
Sources: src/flext_target_ldap/_models/sinks.py:22-262, src/flext_target_ldap/api.py:77-90
Record Processing Logic
Processing a record involves a multi-step protocol: validating the incoming JSON, determining the target stream, constructing a DN, and executing an LDAP add or modify operation.
Data Flow for RECORD Messages
When the CLI receives a message, it follows this sequence:
- Validation: Validates the JSON against
t.Cli.JSON_MAPPING_ADAPTER. - DN Construction: If the record lacks an explicit
dnfield, the protocol constructs one using a template (e.g.,uid={value},{base_dn}). - Persistence Strategy: The protocol checks if the entry exists. If
update_existing_entriesis enabled, it performs amodifyon conflict; otherwise, it attempts anadd. - Deletions: If the
_sdc_deleted_atfield is present, the protocol triggers adelete_entrycall.
This flowchart illustrates the logic used within FlextTargetLdap._process_record_message and individual Sinks to manage LDAP entry lifecycles.
Sources: src/flext_target_ldap/api.py:161-196, src/flext_target_ldap/_models/sinks.py:162-180, tests/unit/test_integration.py:117-130
Domain Models and Validation
The project defines strict models for LDAP entities to ensure data integrity before transmission to the server.
Key Domain Entities
| Entity | Purpose | Key Fields |
|---|---|---|
| AttributeMapping | Defines field transformations from Singer to LDAP. | singer_field_name, ldap_attribute_name, transformation_rule |
| Entry | Represents a complete LDAP object. | distinguished_name, object_classes, attributes |
| TransformationRule | Regex-based data cleaning. | pattern, replacement, enabled |
Business Rule Validation
The Entry model implements a validate_business_rules protocol:
- DN Format: Must contain
attribute=valuepairs. - Object Classes: Must include
top. - Required Attributes: Person entries must have
snandcn; Groups must havecnandmember.
Sources: src/flext_target_ldap/models.py:38-164, src/flext_target_ldap/_models/sinks.py:182-200
Configuration Protocol
The configuration is managed via FlextTargetLdapSettings, which implements a normalization protocol to convert flat Singer-style configuration into nested, validated Pydantic objects.
# Example of normalization logic in settings.py
@u.model_validator(mode="before")
@classmethod
def normalize_flat_settings(cls, data):
# Converts top-level "host", "port", "bind_dn"
# into a nested "connection" object
if "connection" in data:
return data
# ... extraction logic ...
return normalized
Sources: src/flext_target_ldap/settings.py:34-85
Connection Settings
The protocol requires specific parameters to establish the LDAP connection:
| Parameter | Default | Source |
|---|---|---|
host | localhost | c.LOCALHOST |
port | 389 | c.Ldap.PORT |
use_ssl | False | c.Ldap.DEFAULT_USE_SSL |
search_scope | SUBTREE | c.Ldap.DEFAULT_SCOPE |
| Sources: src/flext_target_ldap/settings.py:97-128, src/flext_target_ldap/_utilities/settings.py:39-50 |
Summary
Domain Protocols in flext-target-ldap provide a structured bridge between stream-based data integration and hierarchical LDAP directories. By utilizing a specialized Sink hierarchy, the system ensures that different data types (Users, Groups, OUs) are processed with specific DN construction and attribute mapping rules while maintaining a consistent overall execution flow through the FlextTargetLdap facade.