Loading…
Loading…
Manage DataPower instance configurations, including connection details, credentials, and auto-scan settings, via the underlying database repository.
The DataPowerInstanceRepository is a server-side component that manages the persistence of DataPower instance configurations. It provides an abstraction layer between the application services and the database, handling all Create, Read, Update, and Delete (CRUD) operations for DataPowerInstanceRecord objects stored in the s2r_datapower_instance table.
This repository is responsible for:
Services within the platform call methods on this repository to manage the lifecycle of DataPower instance definitions.
The repository uses JdbcTemplate to execute SQL queries against the s2r_datapower_instance database table. All operations are designed to be secure and tenant-aware.
Each DataPower instance is stored as a row in the s2r_datapower_instance table. All SQL operations executed by this repository—including reads, writes, and deletes—are explicitly scoped to the currently active tenant. This is achieved by appending a tenant-scoping SQL clause (AuditRepository.TENANT_SCOPE_SQL) to every query, preventing any possibility of cross-tenant data access at the database level.
When a new instance is created, its tenant_id is automatically set based on the application's current tenant context.
Passwords for DataPower instances are never stored in plaintext.
password field is encrypted using the CredentialsCipher component. The result is a CredentialsCipher envelope, which is what gets stored in the database.CredentialsCipher. The plaintext password is then available in the returned DataPowerInstanceRecord object for use by internal services (e.g., to establish an SSH or REST connection), but it is not exposed through administrative APIs that list instance configurations.encryptLegacyPlaintextSecrets() designed to be run at application startup. This idempotent method scans for any passwords stored in plaintext (a legacy format), encrypts them, and updates the database. It is safe to run concurrently and repeatedly.To prevent an API consumer from redirecting a stored credential to a different appliance, the repository enforces a password re-entry policy. When updating an existing DataPower instance, if the connection target is changed, the password field must be included in the update payload.
A connection target is considered changed if any of the following properties are modified:
connectModemanagementUrl (the host or endpoint)sshPortusernametlsInsecure (if changed from false to true)If the target changes and the password is not provided, the update operation will fail with an exception. This is a security measure implemented by CredentialTargetGuard.
The following diagram illustrates the logic flow for an update operation.
flowchart TD
subgraph Update Operation Flow
A[API consumer calls update(id, payload)] --> B{Fetch existing record by ID};
B --> C[Normalize update payload];
C --> D{Connection target changed?};
D -- Yes --> E{Password provided in payload?};
E -- No --> F[Throw Security Exception];
E -- Yes --> G[Encrypt password];
D -- No --> G;
G --> H[Update database record];
H --> I[Return updated record];
endIMPORTANT
When updating a DataPowerInstanceRecord, if you modify the connection endpoint, username, or security settings, you must re-submit the password in the same request. Leaving the password field blank will result in the update being rejected.
The repository provides methods to support automated scanning of DataPower instances.
updateAutoScan enables or disables auto-scanning for an instance and sets the scan interval.findDueForAutoScan queries for all instances that are enabled for auto-scan and are due for a new scan based on their configured auto_scan_interval_minutes and the auto_scan_last_triggered_at timestamp.markAutoScanTriggered updates the auto_scan_last_triggered_at timestamp for an instance after a scan has been initiated.The following SQL query is used by the findDueForAutoScan method to identify instances that need to be scanned. It selects instances that are enabled for scanning and where the time since the last scan exceeds the configured interval.
NOTE
The where i.tenant_id = ... clause is a representation of the actual tenant-scoping logic (AuditRepository.TENANT_SCOPE_SQL) that is applied to all queries.
select i.id,
i.instance_name,
i.cluster_id,
c.cluster_name,
i.enabled,
i.management_url,
i.ssh_port,
i.username,
i.password,
i.tls_insecure,
i.connect_mode,
i.domain_allow_list::text as domain_allow_list_text,
i.auto_scan_enabled,
i.auto_scan_interval_minutes,
i.auto_scan_last_triggered_at,
i.created_at,
i.updated_at,
i.updated_by
from s2r_datapower_instance i
left join s2r_datapower_cluster c on c.id = i.cluster_id and c.tenant_id = i.tenant_id
where i.tenant_id = <current_tenant_id>
and i.enabled = true
and i.auto_scan_enabled = true
and i.auto_scan_interval_minutes is not null
and (i.auto_scan_last_triggered_at is null
or i.auto_scan_last_triggered_at < (? - make_interval(mins => i.auto_scan_interval_minutes)))
The following table describes the fields for a DataPower instance configuration. These fields are provided in the payload for create and update operations.
| Field | Type | Default | Required | Description |
|---|---|---|---|---|
instanceName | String | — | Yes | A unique, human-readable name for the instance. |
clusterId | UUID | null | No | The ID of the s2r_datapower_cluster this instance belongs to. |
enabled | Boolean | true | No | If true, the instance is active and can be used for operations like scanning. |
managementUrl | String | — | Yes | The management endpoint. For connectMode: "ssh", this should be the hostname. For other modes, it is the full URL. |
sshPort | Integer | 22 | No | The TCP port for SSH connections. This is used for discovery regardless of the connectMode. Must be between 1 and 65535. |
username | String | — | Yes | The username for authenticating to the DataPower instance. |
password | String | — | Yes | The password for the specified username. Required on create. Required on update only if the connection target changes. |
tlsInsecure | Boolean | false | No | If true, TLS certificate validation is skipped for REST management connections. |
connectMode | String | "ssh" | No | The protocol to use for management connections. |
domainAllowList | Array of Strings | [] | No | A list of application domain names. If not empty, scans will be restricted to only these domains. |
autoScanEnabled | Boolean | — | No | If true, this instance is included in automated scans. Managed via updateAutoScan. |
autoScanIntervalMinutes | Integer | — | No | The interval in minutes between automated scans. Managed via updateAutoScan. |
id | UUID | (auto-generated) | Read-only | The unique identifier for the instance. |
clusterName | String | — | Read-only | The name of the cluster this instance belongs to, joined from the cluster table. |
autoScanLastTriggeredAt | Timestamp | — | Read-only | The timestamp of the last automated scan initiation. |
createdAt | Timestamp | — | Read-only | The timestamp when the instance was created. |
updatedAt | Timestamp | — | Read-only | The timestamp of the last update. |
updatedBy | String | — | Read-only | The identifier of the user or system that performed the last update. |
The DataPowerInstanceRepository class exposes the following public methods for internal application use.
| Method | Parameters | Returns | Description |
|---|---|---|---|
findAll() | — | List<DataPowerInstanceRecord> | Retrieves all DataPower instances for the current tenant, ordered by enabled status and name. |
findRequired(UUID id) | id: The UUID of the instance. | DataPowerInstanceRecord | Retrieves a single DataPower instance by its ID. Throws an exception if not found. |
create(Map<String, Object> payload, String actor) | payload: A map of instance properties. actor: The identifier for the user performing the action. | DataPowerInstanceRecord | Creates a new DataPower instance, encrypts the password, and persists it to the database. |
update(UUID id, Map<String, Object> payload, String actor) | id: The UUID of the instance. payload: A map of properties to update. actor: The identifier for the user. | DataPowerInstanceRecord | Updates an existing instance. Enforces password re-entry on target change. |
updateAutoScan(UUID id, boolean enabled, Integer intervalMinutes, String actor) | id, enabled, intervalMinutes, actor | DataPowerInstanceRecord | Updates the auto-scan configuration for an instance. |
markAutoScanTriggered(UUID id, OffsetDateTime triggeredAt) | id, triggeredAt | void | Updates the auto_scan_last_triggered_at timestamp for an instance. |
findDueForAutoScan(OffsetDateTime now) | now: The current timestamp. | List<DataPowerInstanceRecord> | Finds all instances due for an automated scan. |
setEnabled(UUID id, boolean enabled, String actor) | id, enabled, actor | DataPowerInstanceRecord | Sets the enabled status for an instance. |
encryptLegacyPlaintextSecrets() | — | int | Scans for and encrypts any legacy plaintext passwords. Returns the number of records migrated. |
delete(UUID id) | id: The UUID of the instance. | void | Deletes an instance from the database. |
When interacting with the repository, you may encounter the following exceptions:
| Exception | Cause |
|---|---|
IllegalArgumentException: DataPower instance not found: <id> | Thrown by findRequired when no instance with the specified UUID exists for the current tenant. |
IllegalArgumentException: DataPower instance payload is required | Thrown by create or update if the payload map is null. |
IllegalArgumentException: <fieldName> is required | A required field (e.g., instanceName, managementUrl, username, password) was missing or blank in the payload for a create or update operation. |
IllegalArgumentException: clusterId must be a valid UUID | The provided clusterId was not a valid UUID string. |
IllegalArgumentException: failed to serialize DataPower instance value | An error occurred while serializing the domain_allow_list to JSON. |
| (Security Exception) | An update was attempted that changed a connection target property without re-supplying the password in the payload. The source does not specify the exact exception type. |
CredentialsCipher component is used for securing passwords at rest.PerTenantJobRunner.