Skip to content

Introduce the device management component#8202

Open
kaviska wants to merge 6 commits into
wso2:masterfrom
kaviska:device-mgt
Open

Introduce the device management component#8202
kaviska wants to merge 6 commits into
wso2:masterfrom
kaviska:device-mgt

Conversation

@kaviska

@kaviska kaviska commented Jul 12, 2026

Copy link
Copy Markdown

Proposed changes in this pull request

This PR introduces a new component, org.wso2.carbon.identity.device.mgt, which provides a generic registry for user-owned devices. A device is identified by the public key of a key pair whose private key never leaves the device, so a device can later prove its identity by signing a challenge or a token. The component owns the storage, retrieval, lifecycle and auditing of these device records.

This is the base component. It intentionally contains only device persistence and lifecycle management —
the registration handshake (challenge generation and signature verification) and device policy evaluation are
separate components that consume this one and land in follow-up PRs.

The change adds a new aggregator module (components/device-mgt), registers it in the root POM, and adds the
device tables to the database scripts.

Database

Two tables are added to all supported database scripts (DB2, H2, MS SQL, MySQL, MySQL Cluster, Oracle,
Oracle RAC, PostgreSQL):

  • IDN_DEVICE — the device record: id, name, model, public key, status, registration time, metadata and
    tenant.
  • IDN_USER_DEVICE — the device-to-user mapping, so a user may own multiple devices.
  • Two supporting indexes: IDX_IDV_STATUS and IDX_IUD_USER_TENANT.

The component provides

  • DeviceManagementService — the OSGi service contract:
    • persistDevice(...) — store a verified device.
    • getDeviceById(...), getDevicesByUserId(...) — device lookup.
    • getDevices(tenantDomain, offset, limit) and getDeviceCount(...) — paginated tenant-wide listing for
      the REST API layer.
    • updateDeviceName(...) — rename a device.
    • activateDevice(...) / deactivateDevice(...) — device lifecycle transitions.
    • deleteDevice(...) — remove a device registration.
  • A DAO layer whose queries are portable across all six supported databases, including database-specific
    pagination dialects (default LIMIT/OFFSET, and variants for MS SQL, Oracle and DB2).
  • A cache layerCacheBackedDeviceManagementDAO decorates the DAO and caches Device objects by device
    id, following the same pattern as CacheBackedRuleManagementDAO in the rule management component. Lookup by
    id is the hot path (it is hit on every device-token validation), so it is read-through cached; the cache entry is invalidated on name update, status change and delete. Aggregate/list reads are not cached.
  • Audit logging for every state change (register, update, activate, deactivate, delete). The device owner
    is masked and the public key is reduced to a non-reversible fingerprint — the raw public key and the free-form metadata are never written to the audit log. Read operations are intentionally not audited.
  • A typed exception hierarchy (DeviceMgtException with client/server variants) and an ErrorMessage catalog, so callers get stable error codes rather than leaked lower-layer exceptions.

When should this PR be merged

No preconditions. The component is self-contained

Follow up actions

N/A

kaviska added 2 commits July 11, 2026 19:32
Introduce the standalone device registration/management backend bundle:
- New module components/device-mgt/org.wso2.carbon.identity.device.mgt with
  service, DAO, cache, audit logging and OSGi component.
- Register the module in the root and device-mgt aggregator POMs
  (7.11.153-SNAPSHOT).
- Add IDN_DEVICE and IDN_USER_DEVICE DDL to all central dbscripts.
- Remove the device registration protocol (initiate/verify, challenge cache
  and signature verification) from this component. It now lives with its only
  consumer in the device registration component.
- Introduce Device.Status (ACTIVE, INACTIVE) with activateDevice() and
  deactivateDevice(), replacing the hardcoded status string. Device listing by
  user now returns only active devices, while admin listings return all.
- Remove the unbounded getAllDevices(); the paginated getDevices() and
  getDeviceCount() pair covers the use case.
- Guard against a null device after the post-update re-fetch, so a device
  removed mid-operation surfaces as DEVICE_NOT_FOUND instead of an NPE.
- Add a cache layer (DeviceCache + CacheBackedDeviceManagementDAO) for device
  lookups by ID, with invalidation on update, status change and delete.
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a tenant-scoped device management module with public APIs, JDBC persistence, caching, audit logging, OSGi registration, database schemas for multiple platforms, and TestNG-based DAO, service, cache, and exception-handler coverage.

Changes

Device Management

Layer / File(s) Summary
API contracts and device model
components/device-mgt/.../api/*
Adds the immutable Device model, service interface, error definitions, and client/server exception hierarchy.
Persistence contract and database schema
components/device-mgt/.../internal/constant/*, components/device-mgt/.../internal/dao/DeviceManagementDAO.java, features/identity-core/.../dbscripts/*
Defines DAO SQL contracts and adds tenant-scoped device and user-device tables, foreign keys, and indexes across supported databases.
JDBC DAO and cache-backed access
components/device-mgt/.../internal/cache/*, components/device-mgt/.../internal/dao/impl/*, components/device-mgt/.../src/test/java/.../dao/*
Implements transactional CRUD, pagination, read-through caching, cache invalidation, tenant isolation, and DAO/cache tests.
Service orchestration and observability
components/device-mgt/.../internal/service/*, components/device-mgt/.../internal/util/*, components/device-mgt/.../internal/component/*, components/device-mgt/.../src/test/java/.../{service,util}/*
Adds tenant-aware service delegation, validation, exception mapping, lifecycle audit logging, OSGi registration, and service/utility tests.
Module build and test runtime
pom.xml, components/device-mgt/pom.xml, components/device-mgt/.../pom.xml, components/device-mgt/.../src/test/resources/*
Aggregates the module, configures the OSGi bundle and test tooling, and supplies TestNG, Carbon, Identity, and H2 test configuration.

Possibly related PRs

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the feature broadly, but it omits most required template sections such as Purpose, Goals, Approach, tests, and security checks. Fill in the required template sections, especially Purpose, Goals, Approach, User stories, Release note, Documentation, Automation tests, Security checks, and Test environment.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main change: introducing the device management component and related infrastructure.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

🚨 New Database Tables Detected

This PR introduces new database table(s). Please ensure that the corresponding resource cleanup scripts are updated accordingly.

New Tables:

  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql)

Required Actions:

  1. Update Resource Cleanup Scripts: Please update the cleanup scripts in the identity-organization-resource-cleanup repository:

  2. Test Cleanup Functionality:

    • Verify that the new table data is properly cleaned up during organization resource cleanup operations
    • Test across all supported database platforms
    • Ensure no orphaned data remains after cleanup
  3. Update Documentation: If applicable, update any related documentation regarding the cleanup process for the new tables

Database Support Checklist:

Please verify your new table(s) are compatible with all supported databases:

  • MySQL
  • PostgreSQL
  • Oracle
  • MS SQL Server
  • DB2
  • H2

This is an automated message. If this is a false positive or if you have questions, please reach out to the maintainers.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (4)
components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/api/service/DeviceManagementService.java (1)

31-37: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add @throws Javadoc tags for consistency.

activateDevice and deactivateDevice document @throws DeviceMgtException, but the other seven methods that declare throws DeviceMgtException omit the tag. Adding @throws to all methods ensures API consumers understand the failure contract uniformly.

📝 Example for persistDevice
      * `@param` device       The verified device to persist.
      * `@param` tenantDomain Tenant domain.
+     * `@throws` DeviceMgtException If persistence fails.
      */
     void persistDevice(Device device, String tenantDomain) throws DeviceMgtException;

Also applies to: 47-48, 58-59, 71-72, 81-82, 92-93, 124-125

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/api/service/DeviceManagementService.java`
around lines 31 - 37, Add `@throws` DeviceMgtException Javadoc tags to
persistDevice and the other seven DeviceManagementService methods that declare
this exception but currently omit the tag, matching the existing activateDevice
and deactivateDevice documentation.
components/device-mgt/org.wso2.carbon.identity.device.mgt/src/test/java/org/wso2/carbon/identity/device/mgt/dao/DeviceManagementDAOImplTest.java (1)

39-374: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test coverage is comprehensive.

The tests cover registration, retrieval, tenant isolation, status transitions, update/delete with wrong-tenant no-op, and full-field round-trip. Test ordering via priority and dependsOnMethods is correct, and each test uses unique UUIDs to avoid cross-test interference.

One minor gap: there is no test exercising actual pagination behavior (e.g., getDevices(tenantId, 1, 1) to verify offset/limit). Consider adding one if pagination correctness is a priority.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@components/device-mgt/org.wso2.carbon.identity.device.mgt/src/test/java/org/wso2/carbon/identity/device/mgt/dao/DeviceManagementDAOImplTest.java`
around lines 39 - 374, Add a focused pagination test alongside
testGetDevicesReturnsAllForTenant, invoking getDevices with a nonzero offset and
limited page size such as offset 1 and limit 1. Register multiple uniquely
identified devices for one tenant, then assert the returned page contains
exactly the expected single device, validating both offset and limit behavior.
components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/dao/impl/CacheBackedDeviceManagementDAO.java (1)

162-168: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Cache invalidation has a TOCTOU window.

The clear-before-write pattern (e.g., Line 164 clears the cache, then Line 168 performs the update) has a race window: a concurrent getDeviceById between the cache clear and the DAO write can read the old value from the DAO and repopulate the cache with stale data. This is a known trade-off of cache-aside and is typically acceptable, but if strict consistency is required, consider clearing the cache after the write succeeds as well (double-invalidate), or using a short TTL on cache entries as a safety net.

Also applies to: 185-189, 203-207

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/dao/impl/CacheBackedDeviceManagementDAO.java`
around lines 162 - 168, Update the cache invalidation in updateDeviceName and
the other identified device mutation methods to clear the deviceCache again
after deviceManagementDAO persistence succeeds, while retaining the existing
pre-write invalidation. Ensure post-write invalidation occurs only after a
successful DAO update so concurrent reads cannot leave the updated entry
permanently stale.
features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql (1)

2343-2344: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Consider adding a composite index on (TENANT_ID, REGISTERED_AT) for pagination performance.

The existing IDX_IDV_STATUS (STATUS, TENANT_ID) index supports status-filtered lookups, but the tenant-wide pagination query (GET_ALL_DEVICES_PAGINATED_MSSQL) filters by TENANT_ID and orders by REGISTERED_AT DESC without a matching index. The count query (GET_DEVICES_COUNT) also filters by TENANT_ID alone. For tenants with many devices, this will cause a full scan and sort. A composite index on (TENANT_ID, REGISTERED_AT) would enable an index range scan with sorted output, eliminating the sort step.

This applies to all database scripts (mssql, mysql, mysql-cluster, h2, postgresql, oracle, db2).

♻️ Proposed index addition for MSSQL
 CREATE INDEX IDX_IDV_STATUS ON IDN_DEVICE (STATUS, TENANT_ID);
 CREATE INDEX IDX_IUD_USER_TENANT ON IDN_USER_DEVICE (USER_ID, TENANT_ID);
+CREATE INDEX IDX_IDV_TENANT_REGISTERED ON IDN_DEVICE (TENANT_ID, REGISTERED_AT);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql`
around lines 2343 - 2344, Add a composite index on IDN_DEVICE covering TENANT_ID
and REGISTERED_AT in every database script variant: mssql, mysql, mysql-cluster,
h2, postgresql, oracle, and db2. Keep the existing IDX_IDV_STATUS index
unchanged and follow each script’s established index-creation syntax and naming
conventions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/cache/DeviceCacheKey.java`:
- Around line 38-41: Prevent null deviceId failures in DeviceCacheKey equality
and hashing by validating deviceId in the DeviceCacheKey constructor, or by
making equals() and hashCode() null-safe with Objects.equals and Objects.hash.
Preserve consistent equality and hash behavior for valid and null keys.

In
`@components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/dao/impl/DeviceManagementDAOImpl.java`:
- Around line 160-196: Cap the requested page size before it reaches the
paginated query in getDevices, using the project’s established maximum page-size
constant if available. Apply the cap alongside the existing limit validation and
use the bounded value for bindPaginationParams, while preserving the current
empty-result behavior for nonpositive limits.

In
`@components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/service/impl/DeviceManagementServiceImpl.java`:
- Around line 61-75: Update the missing userId validation in persistDevice to
call DeviceManagementExceptionHandler.handleClientException instead of
handleServerException, matching the existing validateRequiredField behavior.
Preserve the null/blank check and ERROR_USER_ID_REQUIRED error message.
- Around line 61-67: Update persistDevice to validate that the Device argument
is non-null and that id, userId, deviceName, publicKey, and status are all
present before calling deviceManagementDAO.registerDevice. Reject missing or
blank string fields with the existing clear validation-error mechanism, and
handle null status without dereferencing it; only invoke the DAO after all
required fields pass validation.
- Around line 95-99: Update getDevices to validate offset and limit before
calling deviceManagementDAO.getDevices: reject negative offset values and
non-positive limit values, using the service’s established DeviceMgtException
pattern for invalid input. Preserve the existing tenant ID resolution and DAO
invocation for valid pagination parameters.

In
`@features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql`:
- Around line 3341-3352: Update the IDN_DEVICE.PUBLIC_KEY and
IDN_DEVICE.METADATA column definitions in the Oracle schema to match the shared
4096-byte contract used by the other database scripts, ensuring values up to
that limit are accepted consistently.
- Around line 3361-3364: Update the Oracle schema near IDX_IDV_STATUS to add an
index on IDN_DEVICE covering TENANT_ID and REGISTERED_AT, matching the
tenant-scoped ordering used by DeviceManagementDAO.getDevices. Preserve the
existing indexes and use the repository’s standard index naming and SQL
terminator conventions.

---

Nitpick comments:
In
`@components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/api/service/DeviceManagementService.java`:
- Around line 31-37: Add `@throws` DeviceMgtException Javadoc tags to
persistDevice and the other seven DeviceManagementService methods that declare
this exception but currently omit the tag, matching the existing activateDevice
and deactivateDevice documentation.

In
`@components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/dao/impl/CacheBackedDeviceManagementDAO.java`:
- Around line 162-168: Update the cache invalidation in updateDeviceName and the
other identified device mutation methods to clear the deviceCache again after
deviceManagementDAO persistence succeeds, while retaining the existing pre-write
invalidation. Ensure post-write invalidation occurs only after a successful DAO
update so concurrent reads cannot leave the updated entry permanently stale.

In
`@components/device-mgt/org.wso2.carbon.identity.device.mgt/src/test/java/org/wso2/carbon/identity/device/mgt/dao/DeviceManagementDAOImplTest.java`:
- Around line 39-374: Add a focused pagination test alongside
testGetDevicesReturnsAllForTenant, invoking getDevices with a nonzero offset and
limited page size such as offset 1 and limit 1. Register multiple uniquely
identified devices for one tenant, then assert the returned page contains
exactly the expected single device, validating both offset and limit behavior.

In
`@features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql`:
- Around line 2343-2344: Add a composite index on IDN_DEVICE covering TENANT_ID
and REGISTERED_AT in every database script variant: mssql, mysql, mysql-cluster,
h2, postgresql, oracle, and db2. Keep the existing IDX_IDV_STATUS index
unchanged and follow each script’s established index-creation syntax and naming
conventions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 25eccfe1-1f33-426b-82e3-9647a09d76ea

📥 Commits

Reviewing files that changed from the base of the PR and between d038569 and c94a008.

📒 Files selected for processing (36)
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/pom.xml
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/api/constant/ErrorMessage.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/api/exception/DeviceMgtClientException.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/api/exception/DeviceMgtException.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/api/exception/DeviceMgtServerException.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/api/model/Device.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/api/service/DeviceManagementService.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/cache/DeviceCache.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/cache/DeviceCacheEntry.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/cache/DeviceCacheKey.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/component/DeviceMgtServiceComponent.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/constant/DeviceMgtSQLConstants.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/dao/DeviceManagementDAO.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/dao/impl/CacheBackedDeviceManagementDAO.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/dao/impl/DeviceManagementDAOImpl.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/service/impl/DeviceManagementServiceImpl.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/util/DeviceManagementAuditLogger.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/util/DeviceManagementExceptionHandler.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/test/java/org/wso2/carbon/identity/device/mgt/dao/CacheBackedDeviceManagementDAOTest.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/test/java/org/wso2/carbon/identity/device/mgt/dao/DeviceManagementDAOImplTest.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/test/java/org/wso2/carbon/identity/device/mgt/service/DeviceManagementServiceImplTest.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/test/java/org/wso2/carbon/identity/device/mgt/util/DeviceManagementExceptionHandlerTest.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/test/resources/dbscripts/h2.sql
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/test/resources/repository/conf/carbon.xml
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/test/resources/repository/conf/identity/identity.xml
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/test/resources/testng.xml
  • components/device-mgt/pom.xml
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql
  • pom.xml

@codecov

codecov Bot commented Jul 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 53.54%. Comparing base (d038569) to head (8c574ea).

Additional details and impacted files
@@             Coverage Diff              @@
##             master    #8202      +/-   ##
============================================
+ Coverage     52.81%   53.54%   +0.72%     
+ Complexity    21555    21319     -236     
============================================
  Files          2199     2199              
  Lines        134728   130251    -4477     
  Branches      20723    19878     -845     
============================================
- Hits          71154    69740    -1414     
+ Misses        54776    52016    -2760     
+ Partials       8798     8495     -303     
Flag Coverage Δ
unit 38.45% <ø> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

The caller supplied page size was passed to the database unchanged, so a large
limit could load an unbounded number of devices into memory - the same problem
the removal of getAllDevices was meant to avoid.

Validate the limit at the service boundary against IdentityUtil.getMaximumItemPerPage(),
capping an oversized page size to the configured maximum, and rejecting a negative
page size as a client error instead of silently returning an empty list.
@github-actions

Copy link
Copy Markdown

🚨 New Database Tables Detected

This PR introduces new database table(s). Please ensure that the corresponding resource cleanup scripts are updated accordingly.

New Tables:

  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql)

Required Actions:

  1. Update Resource Cleanup Scripts: Please update the cleanup scripts in the identity-organization-resource-cleanup repository:

  2. Test Cleanup Functionality:

    • Verify that the new table data is properly cleaned up during organization resource cleanup operations
    • Test across all supported database platforms
    • Ensure no orphaned data remains after cleanup
  3. Update Documentation: If applicable, update any related documentation regarding the cleanup process for the new tables

Database Support Checklist:

Please verify your new table(s) are compatible with all supported databases:

  • MySQL
  • PostgreSQL
  • Oracle
  • MS SQL Server
  • DB2
  • H2

This is an automated message. If this is a false positive or if you have questions, please reach out to the maintainers.

@github-actions

Copy link
Copy Markdown

🚨 New Database Tables Detected

This PR introduces new database table(s). Please ensure that the corresponding resource cleanup scripts are updated accordingly.

New Tables:

  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql)

Required Actions:

  1. Update Resource Cleanup Scripts: Please update the cleanup scripts in the identity-organization-resource-cleanup repository:

  2. Test Cleanup Functionality:

    • Verify that the new table data is properly cleaned up during organization resource cleanup operations
    • Test across all supported database platforms
    • Ensure no orphaned data remains after cleanup
  3. Update Documentation: If applicable, update any related documentation regarding the cleanup process for the new tables

Database Support Checklist:

Please verify your new table(s) are compatible with all supported databases:

  • MySQL
  • PostgreSQL
  • Oracle
  • MS SQL Server
  • DB2
  • H2

This is an automated message. If this is a false positive or if you have questions, please reach out to the maintainers.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/service/impl/DeviceManagementServiceImpl.java (1)

69-72: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Avoid logging userId in the debug statement; use deviceId for consistency and PII safety.

The debug log at line 70 includes device.getUserId(), which may be an email or username depending on the WSO2 deployment. The LOG_ENHANCEMENT_GUIDELINES explicitly prohibit logging emails/PII. All other debug logs in this class (activate, deactivate, delete) use only deviceId and tenantDomain, and the audit logger already masks the owner. The deviceId is already present on line 71, so removing the userId portion aligns with both the PII guideline and the established pattern.

🔒️ Proposed fix
         if (LOG.isDebugEnabled()) {
-            LOG.debug("Device persisted for user: " + device.getUserId() +
-                    " in tenant: " + tenantDomain + " with device ID: " + device.getId());
+            LOG.debug("Device persisted with ID: " + device.getId() +
+                    " in tenant: " + tenantDomain);
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/service/impl/DeviceManagementServiceImpl.java`
around lines 69 - 72, Update the debug log in the device persistence flow to
remove device.getUserId() and retain only the non-PII deviceId and tenantDomain
details, matching the existing activate, deactivate, and delete logging pattern.

Source: Path instructions

features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql (1)

3341-3364: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Enforce unique device public keys
The DAO/service only validate that publicKey is present; duplicate keys can still be stored. Add a unique constraint/index on PUBLIC_KEY (or (PUBLIC_KEY, TENANT_ID) if uniqueness is tenant-scoped) in every supported DB script.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql`
around lines 3341 - 3364, Add a uniqueness constraint or unique index for
IDN_DEVICE.PUBLIC_KEY in this Oracle schema, using the tenant-scoped key
(PUBLIC_KEY, TENANT_ID) if device keys are intended to be unique per tenant;
apply the equivalent change consistently across every supported database script.

Source: Learnings

🧹 Nitpick comments (2)
components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/service/impl/DeviceManagementServiceImpl.java (2)

75-104: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add debug-level entry logs to read methods that perform DB calls.

getDeviceById, getDevicesByUserId, getDevices, and getDeviceCount all perform database lookups but have no log statements. Per the logging guidelines, significant operations (DB calls) should include log statements. Consider adding guarded debug logs at entry to aid troubleshooting, consistent with the pattern used by the mutation methods.

💡 Example for getDeviceById
 public Device getDeviceById(String deviceId, String tenantDomain)
         throws DeviceMgtException {

+    if (LOG.isDebugEnabled()) {
+        LOG.debug("Retrieving device with ID: " + deviceId + " in tenant: " + tenantDomain);
+    }
     validateRequiredField(deviceId, "deviceId");
     return deviceManagementDAO.getDeviceById(
             deviceId, IdentityTenantUtil.getTenantId(tenantDomain));
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/service/impl/DeviceManagementServiceImpl.java`
around lines 75 - 104, Add guarded debug-level entry logs to getDeviceById,
getDevicesByUserId, getDevices, and getDeviceCount before their DAO calls,
following the existing logging pattern used by mutation methods. Include
relevant method inputs while avoiding sensitive data, and preserve the current
validation and database-call behavior.

Source: Path instructions


107-124: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a debug log to updateDeviceName for consistency with other mutation methods.

persistDevice, activateDevice, deactivateDevice, and deleteDevice all emit guarded debug logs after their DAO operations. updateDeviceName is the only mutation method that omits one, despite performing a significant DB update. Adding a debug log keeps the observability surface consistent across all write paths.

💡 Proposed addition
         AUDIT_LOGGER.printAuditLog(DeviceManagementAuditLogger.Operation.UPDATE, updated);
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Device name updated for ID: " + deviceId + " in tenant: " + tenantDomain);
+        }
         return updated;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/service/impl/DeviceManagementServiceImpl.java`
around lines 107 - 124, Add a guarded debug log in updateDeviceName immediately
after the successful deviceManagementDAO.updateDeviceName operation, consistent
with the existing post-DAO debug logging in persistDevice, activateDevice,
deactivateDevice, and deleteDevice. Include the relevant device update context
without changing validation, error handling, audit logging, or return behavior.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In
`@components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/service/impl/DeviceManagementServiceImpl.java`:
- Around line 69-72: Update the debug log in the device persistence flow to
remove device.getUserId() and retain only the non-PII deviceId and tenantDomain
details, matching the existing activate, deactivate, and delete logging pattern.

In
`@features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql`:
- Around line 3341-3364: Add a uniqueness constraint or unique index for
IDN_DEVICE.PUBLIC_KEY in this Oracle schema, using the tenant-scoped key
(PUBLIC_KEY, TENANT_ID) if device keys are intended to be unique per tenant;
apply the equivalent change consistently across every supported database script.

---

Nitpick comments:
In
`@components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/service/impl/DeviceManagementServiceImpl.java`:
- Around line 75-104: Add guarded debug-level entry logs to getDeviceById,
getDevicesByUserId, getDevices, and getDeviceCount before their DAO calls,
following the existing logging pattern used by mutation methods. Include
relevant method inputs while avoiding sensitive data, and preserve the current
validation and database-call behavior.
- Around line 107-124: Add a guarded debug log in updateDeviceName immediately
after the successful deviceManagementDAO.updateDeviceName operation, consistent
with the existing post-DAO debug logging in persistDevice, activateDevice,
deactivateDevice, and deleteDevice. Include the relevant device update context
without changing validation, error handling, audit logging, or return behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 6ac18333-2ea0-4923-bb48-3d611ad40fc5

📥 Commits

Reviewing files that changed from the base of the PR and between edd6c65 and c002fce.

📒 Files selected for processing (12)
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/api/constant/ErrorMessage.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/service/impl/DeviceManagementServiceImpl.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/test/java/org/wso2/carbon/identity/device/mgt/service/DeviceManagementServiceImplTest.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/test/resources/dbscripts/h2.sql
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql
🚧 Files skipped from review as they are similar to previous changes (7)
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/api/constant/ErrorMessage.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/test/resources/dbscripts/h2.sql
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql
  • features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/test/java/org/wso2/carbon/identity/device/mgt/service/DeviceManagementServiceImplTest.java

@github-actions

Copy link
Copy Markdown

🚨 New Database Tables Detected

This PR introduces new database table(s). Please ensure that the corresponding resource cleanup scripts are updated accordingly.

New Tables:

  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql)

Required Actions:

  1. Update Resource Cleanup Scripts: Please update the cleanup scripts in the identity-organization-resource-cleanup repository:

  2. Test Cleanup Functionality:

    • Verify that the new table data is properly cleaned up during organization resource cleanup operations
    • Test across all supported database platforms
    • Ensure no orphaned data remains after cleanup
  3. Update Documentation: If applicable, update any related documentation regarding the cleanup process for the new tables

Database Support Checklist:

Please verify your new table(s) are compatible with all supported databases:

  • MySQL
  • PostgreSQL
  • Oracle
  • MS SQL Server
  • DB2
  • H2

This is an automated message. If this is a false positive or if you have questions, please reach out to the maintainers.

@sonarqubecloud

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/constant/DeviceMgtSQLConstants.java`:
- Around line 144-180: Update GET_ALL_DEVICES_PAGINATED_BY_USER and its MSSQL,
ORACLE, and DB2 variants to order tied REGISTERED_AT values deterministically
with D.ID DESC after the existing timestamp ordering. In
GET_ALL_DEVICES_PAGINATED_BY_USER_ORACLE and
GET_ALL_DEVICES_PAGINATED_BY_USER_DB2, add final outer ordering by rnum and rn
respectively, preserving newest-first pagination across all dialects.

In
`@components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/dao/impl/DeviceManagementDAOImpl.java`:
- Line 201: In DeviceManagementDAOImpl, update getDevices at
components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/dao/impl/DeviceManagementDAOImpl.java:201-201
to conditionally emit a debug log with the retrieved device count before
returning, and update getDeviceCount at the same file:234-234 with the
equivalent guarded count log. Preserve the existing return behavior and avoid
logging when debug logging is disabled.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 1c87ad13-be81-44c8-b755-78b94b20f5d2

📥 Commits

Reviewing files that changed from the base of the PR and between 8c574ea and 05a71ea.

📒 Files selected for processing (10)
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/api/service/DeviceManagementService.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/constant/DeviceMgtSQLConstants.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/dao/DeviceManagementDAO.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/dao/impl/CacheBackedDeviceManagementDAO.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/dao/impl/DeviceManagementDAOImpl.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/service/impl/DeviceManagementServiceImpl.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/util/DeviceManagementAuditLogger.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/test/java/org/wso2/carbon/identity/device/mgt/dao/CacheBackedDeviceManagementDAOTest.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/test/java/org/wso2/carbon/identity/device/mgt/dao/DeviceManagementDAOImplTest.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/test/java/org/wso2/carbon/identity/device/mgt/service/DeviceManagementServiceImplTest.java
🚧 Files skipped from review as they are similar to previous changes (4)
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/test/java/org/wso2/carbon/identity/device/mgt/dao/CacheBackedDeviceManagementDAOTest.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/dao/impl/CacheBackedDeviceManagementDAO.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/util/DeviceManagementAuditLogger.java
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/service/impl/DeviceManagementServiceImpl.java

Comment on lines +144 to +180
public static final String GET_ALL_DEVICES_PAGINATED_BY_USER =
"SELECT D.ID, UD.USER_ID, D.DEVICE_NAME, D.DEVICE_MODEL, D.PUBLIC_KEY, D.STATUS, " +
"D.REGISTERED_AT, D.METADATA, D.TENANT_ID " +
"FROM IDN_DEVICE D " +
"INNER JOIN IDN_USER_DEVICE UD ON D.ID = UD.DEVICE_ID AND D.TENANT_ID = UD.TENANT_ID " +
"WHERE D.TENANT_ID = :TENANT_ID; AND UD.USER_ID = :USER_ID; " +
"ORDER BY D.REGISTERED_AT DESC LIMIT :LIMIT; OFFSET :OFFSET;";

// MS SQL Server.
public static final String GET_ALL_DEVICES_PAGINATED_BY_USER_MSSQL =
"SELECT D.ID, UD.USER_ID, D.DEVICE_NAME, D.DEVICE_MODEL, D.PUBLIC_KEY, D.STATUS, " +
"D.REGISTERED_AT, D.METADATA, D.TENANT_ID " +
"FROM IDN_DEVICE D " +
"INNER JOIN IDN_USER_DEVICE UD ON D.ID = UD.DEVICE_ID AND D.TENANT_ID = UD.TENANT_ID " +
"WHERE D.TENANT_ID = :TENANT_ID; AND UD.USER_ID = :USER_ID; " +
"ORDER BY D.REGISTERED_AT DESC OFFSET :OFFSET; ROWS FETCH NEXT :LIMIT; ROWS ONLY";

// Oracle.
public static final String GET_ALL_DEVICES_PAGINATED_BY_USER_ORACLE =
"SELECT ID, USER_ID, DEVICE_NAME, DEVICE_MODEL, PUBLIC_KEY, STATUS, REGISTERED_AT, " +
"METADATA, TENANT_ID FROM (SELECT ID, USER_ID, DEVICE_NAME, DEVICE_MODEL, PUBLIC_KEY, " +
"STATUS, REGISTERED_AT, METADATA, TENANT_ID, rownum AS rnum FROM " +
"(SELECT D.ID, UD.USER_ID, D.DEVICE_NAME, D.DEVICE_MODEL, D.PUBLIC_KEY, D.STATUS, " +
"D.REGISTERED_AT, D.METADATA, D.TENANT_ID FROM IDN_DEVICE D " +
"INNER JOIN IDN_USER_DEVICE UD ON D.ID = UD.DEVICE_ID AND D.TENANT_ID = UD.TENANT_ID " +
"WHERE D.TENANT_ID = :TENANT_ID; AND UD.USER_ID = :USER_ID; ORDER BY D.REGISTERED_AT DESC) " +
"WHERE rownum <= :UPPER_BOUND;) WHERE rnum > :OFFSET;";

// DB2.
public static final String GET_ALL_DEVICES_PAGINATED_BY_USER_DB2 =
"SELECT ID, USER_ID, DEVICE_NAME, DEVICE_MODEL, PUBLIC_KEY, STATUS, REGISTERED_AT, " +
"METADATA, TENANT_ID FROM (SELECT ROW_NUMBER() OVER(ORDER BY D.REGISTERED_AT DESC) AS rn, " +
"D.ID, UD.USER_ID, D.DEVICE_NAME, D.DEVICE_MODEL, D.PUBLIC_KEY, D.STATUS, " +
"D.REGISTERED_AT, D.METADATA, D.TENANT_ID FROM IDN_DEVICE D " +
"INNER JOIN IDN_USER_DEVICE UD ON D.ID = UD.DEVICE_ID AND D.TENANT_ID = UD.TENANT_ID " +
"WHERE D.TENANT_ID = :TENANT_ID; AND UD.USER_ID = :USER_ID;) " +
"WHERE rn BETWEEN :LOWER_BOUND; AND :UPPER_BOUND;";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Make pagination ordering deterministic across all dialects.

Ordering only by REGISTERED_AT can duplicate or omit records between pages when timestamps tie. Add a stable tiebreaker such as D.ID DESC; Oracle and DB2 also need final outer ordering by rnum/rn to guarantee the documented newest-first result order.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/constant/DeviceMgtSQLConstants.java`
around lines 144 - 180, Update GET_ALL_DEVICES_PAGINATED_BY_USER and its MSSQL,
ORACLE, and DB2 variants to order tied REGISTERED_AT values deterministically
with D.ID DESC after the existing timestamp ordering. In
GET_ALL_DEVICES_PAGINATED_BY_USER_ORACLE and
GET_ALL_DEVICES_PAGINATED_BY_USER_DB2, add final outer ordering by rnum and rn
respectively, preserving newest-first pagination across all dialects.

}
bindPaginationParams(preparedStatement, style, safeOffset, limit);
}));
return devices != null ? devices : Collections.emptyList();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add debug logging for database retrieval operations.

As per path instructions, functions that perform significant operations such as database calls should include log statements where possible. Adding a debug log for the successfully retrieved data improves observability without spamming the logs.

  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/dao/impl/DeviceManagementDAOImpl.java#L201-L201: Guard and log the count of retrieved devices before returning.
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/dao/impl/DeviceManagementDAOImpl.java#L234-L234: Guard and log the retrieved device count before returning.
📝 Proposed fixes

For getDevices (around line 201):

-            return devices != null ? devices : Collections.emptyList();
+            List<Device> result = devices != null ? devices : Collections.emptyList();
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Retrieved " + result.size() + " devices for tenant ID: " + tenantId);
+            }
+            return result;

For getDeviceCount (around line 234):

-            return count != null ? count : 0;
+            int result = count != null ? count : 0;
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Retrieved device count: " + result + " for tenant ID: " + tenantId);
+            }
+            return result;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return devices != null ? devices : Collections.emptyList();
List<Device> result = devices != null ? devices : Collections.emptyList();
if (LOG.isDebugEnabled()) {
LOG.debug("Retrieved " + result.size() + " devices for tenant ID: " + tenantId);
}
return result;
Suggested change
return devices != null ? devices : Collections.emptyList();
int result = count != null ? count : 0;
if (LOG.isDebugEnabled()) {
LOG.debug("Retrieved device count: " + result + " for tenant ID: " + tenantId);
}
return result;
📍 Affects 1 file
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/dao/impl/DeviceManagementDAOImpl.java#L201-L201 (this comment)
  • components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/dao/impl/DeviceManagementDAOImpl.java#L234-L234
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/dao/impl/DeviceManagementDAOImpl.java`
at line 201, In DeviceManagementDAOImpl, update getDevices at
components/device-mgt/org.wso2.carbon.identity.device.mgt/src/main/java/org/wso2/carbon/identity/device/mgt/internal/dao/impl/DeviceManagementDAOImpl.java:201-201
to conditionally emit a debug log with the retrieved device count before
returning, and update getDeviceCount at the same file:234-234 with the
equivalent guarded count log. Preserve the existing return behavior and avoid
logging when debug logging is disabled.

Source: Path instructions

@github-actions

Copy link
Copy Markdown

🚨 New Database Tables Detected

This PR introduces new database table(s). Please ensure that the corresponding resource cleanup scripts are updated accordingly.

New Tables:

  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/db2.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/h2.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mssql.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql-cluster.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/mysql.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/oracle_rac.sql)
  • IDN_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql)
  • IDN_USER_DEVICE (in features/identity-core/org.wso2.carbon.identity.core.server.feature/resources/dbscripts/postgresql.sql)

Required Actions:

  1. Update Resource Cleanup Scripts: Please update the cleanup scripts in the identity-organization-resource-cleanup repository:

  2. Test Cleanup Functionality:

    • Verify that the new table data is properly cleaned up during organization resource cleanup operations
    • Test across all supported database platforms
    • Ensure no orphaned data remains after cleanup
  3. Update Documentation: If applicable, update any related documentation regarding the cleanup process for the new tables

Database Support Checklist:

Please verify your new table(s) are compatible with all supported databases:

  • MySQL
  • PostgreSQL
  • Oracle
  • MS SQL Server
  • DB2
  • H2

This is an automated message. If this is a false positive or if you have questions, please reach out to the maintainers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant