ImportTechnicalAccountsFromCSVExecutor

Long Running Task (LRT) that bulk-creates or updates Technical Accounts in CzechIdM by reading a semicolon-separated CSV file. Each CSV row represents one technical account. The task maps configurable column names to entity fields, supports dry-run mode, and never triggers unintended provisioning operations on existing accounts.

- The task reads the attached CSV file line by line (first line = header). - For each data row it looks up an existing Technical Account by the value in the identifier column (matched against code). - Depending on whether the account exists and which behaviour flags are set, the account is created, updated, or skipped. - Optional columns assign identity/role guarantors, link the account to a provisioning system, and associate it with a Technical Asset. - All item-level results are written to the LRT task log.

Property Value
Encoding UTF-8
Column separator ; (configurable)
First row Header with column names
Multi-values | by default (configurable)
Date format yyyy-MM-dd (ISO 8601)
Only the identifier column is mandatory. All other columns are optional — the task only reads a column when the corresponding parameter is configured and the column exists in the CSV header. Configuring a column name that is absent from the CSV header causes the task to fail immediately with a descriptive error listing the missing columns.
Parameter Type Required Default Description
importFile Attachment Yes CSV file to import
separator String No ; Column separator character
encoding String No utf-8 File encoding

Each parameter value is the exact name of a column in the CSV header (case-sensitive).

Parameter Description
identifiercolumn Required. Unique identifier for the account; stored as code. Used to look up existing accounts.
namecolumn Technical account name (maps to externalCode — the Name field in the UI).
descriptioncolumn Free-text description.
validfromcolumn Validity start date (yyyy-MM-dd). Blank cell leaves the field unchanged.
validtillcolumn Validity end date (yyyy-MM-dd). Blank cell leaves the field unchanged.
systemcolumn Name (codeable identifier) of the provisioning system. Required when creating new accounts.
mappingcolumn Provisioning mapping name. Must be a TECHNICAL_ACCOUNT PROVISIONING mapping on the system.
directidentitycolumn Identity guarantors — pipe-separated list of usernames.
guaranteerolecolumn Role guarantors — pipe-separated list of role codes.
technicalassetcolumn Code of the Technical Asset to associate with the account.
tiercolumn Tier value written to the linked AccAccount when a new account is created. Blank cell leaves the field unset.
zonecolumn Zone value written to the linked AccAccount when a new account is created. Blank cell leaves the field unset.
multivalueseparator Character used to separate multiple values in multi-value columns. Default: |.
Parameter Type Default Description
cancreate Boolean false Allow creating new Technical Accounts. When false, rows whose identifier is not found are logged as skipped.
canoverwrite Boolean false Allow overwriting fields (externalCode, description, validFrom, validTill) of existing accounts. When false, existing accounts are logged as skipped.
canchangeta Boolean false Allow assigning or changing the Technical Asset (technicalassetcolumn) on an account. When false, the asset column is ignored even if configured.
read identifier from identifiercolumn
  └─ find existing TechnicalAccount by code = identifier
       ├─ NOT FOUND + cancreate = false  →  log CSV_IMPORT_ACCOUNT_SKIPPED (EXCEPTION), stop
       ├─ FOUND + canoverwrite = false   →  log CSV_IMPORT_ACCOUNT_SKIPPED (EXCEPTION), stop
       ├─ NOT FOUND + cancreate = true   →  resolve system + mapping (mandatory), create new account
       └─ FOUND + canoverwrite = true    →  update account fields

(for new account: system and mapping must be resolved before save — see System Linking Rules)

(after save)
├─ assign identity guarantors  (directidentitycolumn)
├─ assign role guarantors      (guaranteerolecolumn)
├─ assign technical asset      (technicalassetcolumn, only when canchangeta = true)
└─ for existing accounts: optionally validate AccAccount consistency (systemcolumn + mappingcolumn)
Unknown references (identity username not found, role code not found, Technical Asset name not found) are logged as warnings and silently skipped — the account is still saved.

directidentitycolumn and guaranteerolecolumn can contain multiple values separated by the multi-value separator (default |). Whitespace around each value is trimmed.

Example cell value:

jnovak|pdvorak|mmaly

Each value is resolved independently. Values that cannot be resolved are skipped with a warning to console.

The task only adds new guarantors — it never removes existing ones. Guarantors that were assigned previously (manually or by an earlier import) are left untouched regardless of what the current CSV contains.

Every Technical Account must have exactly one AccAccount. The link is maintained via the TechnicalAccountAccount join entity.

When cancreate = true and the identifier is not found:

- systemcolumn is mandatory. If not configured or the system is not found in CzechIdM, the row fails with CSV_IMPORT_ACCOUNT_ERROR. - If mappingcolumn is configured: the named mapping must exist on the system and must be of type TECHNICAL_ACCOUNT PROVISIONING. Otherwise the row fails. - If mappingcolumn is not configured: the system must have exactly one TECHNICAL_ACCOUNT PROVISIONING mapping. Zero or more than one also causes the row to fail. - Once system and mapping are validated, a new AccAccount is created (uid = identifier) and linked via TechnicalAccountAccount.

Scenario Behaviour
systemcolumn not configured Error — row fails with CSV_IMPORT_ACCOUNT_ERROR.
System name not found in CzechIdM Error — row fails with CSV_IMPORT_ACCOUNT_ERROR.
Mapping specified, not found on system Error — row fails with CSV_IMPORT_ACCOUNT_ERROR.
Mapping specified, found but not TECHNICAL_ACCOUNT type Error — row fails with CSV_IMPORT_ACCOUNT_ERROR.
Mapping not specified, no TECHNICAL_ACCOUNT mapping on system Error — row fails with CSV_IMPORT_ACCOUNT_ERROR.
Mapping not specified, multiple TECHNICAL_ACCOUNT mappings on system Error — specify mapping explicitly; row fails with CSV_IMPORT_ACCOUNT_ERROR.
System and mapping resolved successfully New AccAccount (uid = identifier) created; TechnicalAccountAccount link saved.

When the account already exists, its AccAccount is never changed. The system and mapping columns are only used for optional consistency validation — mismatches are logged as warnings, not errors.

Scenario Behaviour
systemcolumn not configured System validation skipped.
System name not found in CzechIdM Warning logged, validation skipped.
AccAccount is on a different system than specified Warning logged; AccAccount is not changed.
mappingcolumn not configured Mapping validation skipped.
AccAccount uses a different mapping than specified Warning logged; AccAccount is not changed.
Why is the AccAccount never changed for existing accounts?
The import task assumes that if a Technical Account already exists in CzechIdM, its provisioning links were set up previously (either manually or by an earlier import run). Changing the AccAccount could trigger CzechIdM's provisioning engine to act on a live system.

The technicalassetcolumn column is only processed when canchangeta = true. When canchangeta = false the column is ignored even if it is present in the CSV and a matching Technical Asset exists in the system.

Technical assets are looked up by name (the Name field shown in the UI).

Scenario Behaviour
canchangeta = false Technical Asset column is ignored entirely.
canchangeta = true, asset found by name Account's technicalAsset reference is set.
canchangeta = true, asset name not found Warning logged, technicalAsset left unchanged.

The task supports CzechIdM's built-in dry-run flag. When dry-run is enabled:

* No Technical Accounts are created or updated. * No guarantors are assigned. * No AccAccounts or TechnicalAccountAccount links are created. * All rows (including new accounts) produce item-level log entries with state NOT_EXECUTED. * Would-be operations are written to the application log at INFO level (prefix [DRY-RUN]). * The task counter still increments so you can verify the row count.

To execute a dry run, enable the Dry run toggle when scheduling the task in the UI, or set dryRun = true on the IdmLongRunningTaskDto before calling LongRunningTaskManager.executeSync() in code.
Code State Counted as Description
CSV_IMPORT_ACCOUNT_CREATED EXECUTED successItemCount Technical account was created.
CSV_IMPORT_ACCOUNT_UPDATED EXECUTED successItemCount Technical account was updated.
CSV_IMPORT_ACCOUNT_SKIPPED EXCEPTION failedItemCount Row skipped (cancreate=false or canoverwrite=false).
CSV_IMPORT_ACCOUNT_ERROR EXCEPTION failedItemCount Row failed (system/mapping could not be resolved).

Only identifier and name columns — no system, guarantors, or asset.

identifiercolumn;namecolumn
svc-api-gateway;API Gateway
svc-db-reader;DB Reader
svc-batch-runner;Batch Runner

Task configuration:

Parameter Value
identifiercolumn identifiercolumn
namecolumn namecolumn
cancreate true
canoverwrite false
identifiercolumn;namecolumn;descriptioncolumn;validfromcolumn;validtillcolumn;systemcolumn;mappingcolumn;directidentitycolumn;guaranteerolecolumn;technicalassetcolumn
svc-ldap-reader;LDAP Reader;LDAP read-only service account;2024-01-01;;CMS AD - Users;AD users provisioning mapping tech.;jnovak|pdvorak;role-ldap-admin|role-infra-team;Core Infrastructure
svc-db-backup;DB Backup;Database backup service account;2024-01-01;2026-12-31;CMS AD - Users;AD users provisioning mapping tech.;mpolak;role-dba;Databases

Task configuration:

Parameter Value
identifiercolumn identifiercolumn
namecolumn namecolumn
descriptioncolumn descriptioncolumn
validfromcolumn validfromcolumn
validtillcolumn validtillcolumn
systemcolumn systemcolumn
mappingcolumn mappingcolumn
directidentitycolumn directidentitycolumn
guaranteerolecolumn guaranteerolecolumn
technicalassetcolumn technicalassetcolumn
multivalueseparator |
cancreate true
canoverwrite true
canchangeta true
A blank validtillcolumn cell (like the first row above) leaves the field unchanged — it does not clear an existing validTill date.
  • by cem