Skip to content

ATLAS-5425:Implement getEntitiesWithTagChanges for RDBMS audit repository - #785

Open
bhor-sanket wants to merge 2 commits into
apache:masterfrom
bhor-sanket:ATLAS-5425
Open

bhor-sanket wants to merge 2 commits into
apache:masterfrom
bhor-sanket:ATLAS-5425

Conversation

@bhor-sanket

@bhor-sanket bhor-sanket commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

Background

Apache Atlas supports multiple audit repository backends (HBase, RDBMS, InMemory, Cassandra, Noop). The REST API GET /api/atlas/v2/entity/bulk/headers?tagUpdateStartTime={epoch_ms} enables consumers to retrieve entities that had classification (tag) changes within a given time window. This API is used by ClassificationAssociator.Retriever to synchronize classification state across systems.

Problem Statement

  • Existing behavior: The API always returns an empty guidHeaderMap when Atlas is configured with the RDBMS audit backend
    (atlas.EntityAuditRepository.impl=org.apache.atlas.repository.audit.rdbms.RdbmsBasedAuditRepository).
  • Expected behavior: The API should return entity GUIDs that had classification changes (CLASSIFICATION_ADD, CLASSIFICATION_DELETE, CLASSIFICATION_UPDATE) within the specified time range, matching the HBase
    backend behavior.
  • Root cause: RdbmsBasedAuditRepository.getEntitiesWithTagChanges(fromTimestamp, toTimestamp) was a // TODO: stub returning Collections.emptySet().
  • Impact: Classification sync via the bulk headers API is completely non-functional on RDBMS-backed Atlas deployments.

How the patch resolves it

The implementation mirrors the HBase backend's behavior using JPA/JPQL against the atlas_entity_audit table.

  1. New JPA Named Query (janus-jpa_named_queries.xml)
  • DbEntityAudit.getDistinctEntityIdsByActionPrefixAndTimeRange — queries atlas_entity_audit for distinct entity IDs where operation LIKE 'CLASSIFICATION_%' within a half-open time range (fromTimestamp, toTimestamp)
  • Uses SELECT DISTINCT obj.entityId to avoid materializing full DbEntityAudit objects
  • LIKE 'CLASSIFICATION_%' matches CLASSIFICATION_ADD, CLASSIFICATION_DELETE, CLASSIFICATION_UPDATE but excludes PROPAGATED_CLASSIFICATION_* — exact parity with HBase's
    BinaryPrefixComparator("CLASSIFICATION_")
  • Half-open interval [from, to) matches HBase's Scan.setTimeRange() semantics
  1. New DAO Method (DbEntityAuditDao.java)
  • getDistinctEntityIdsByActionPrefixAndTimeRange(String actionPrefix, long fromTimestamp, long toTimestamp) — executes the named query with parameterized action prefix and time range
  • Returns List (entity GUIDs), follows existing error-handling convention
  1. Repository Implementation (RdbmsBasedAuditRepository.java)
  • Replaced the // TODO: stub with a working implementation using RdbmsTransaction + DbEntityAuditDao pattern (consistent with existing listEventsV2 method)
  • Passes "CLASSIFICATION_%" as the action prefix
  • Wraps result in HashSet<> to satisfy Set return type

How was this patch tested?

Setup :

  • Atlas 3.0.0-SNAPSHOT running with RDBMS (PostgreSQL) backend via Docker compose
  • API endpoint: GET /api/atlas/v2/entity/bulk/headers?tagUpdateStartTime={epoch_ms}

Use-cases validation :

  • Scenario 1: Classification Add — Added classification to an entity, called API with timestamp captured before the add. Entity GUID returned with classification in response. Passed.
  • Scenario 2: Classification Delete — Removed classification from an entity, called API with timestamp captured before the delete. Entity GUID returned in response (reflecting current state without the
    classification). Passed.
  • Scenario 3: Classification Update — Updated classification attributes, called API with timestamp before the update. Entity GUID returned with updated classification attributes. Passed.
  • Scenario 4: No classification changes (empty result) — Performed a non-classification attribute update, called API. Response returned empty guidHeaderMap. Passed.
  • Scenario 5: Time range boundary — Added classification, then called API with a timestamp after the add event. Entity excluded from results as expected. Passed.
  • Scenario 6: Multiple entities — Added/removed classifications on 3 different entities. All 3 GUIDs returned in a single API response. Passed.
  • Scenario 7: Deduplication — Multiple classification events (add + update) on the same entity. Entity GUID appeared exactly once. Passed.
  • Scenario 8: Propagated classification exclusion — Added classification with propagate=true to a parent entity linked via hive_process lineage. Parent entity (direct CLASSIFICATION_ADD) returned. Child
    entity (PROPAGATED_CLASSIFICATION_ADD) excluded — matches HBase behavior. Passed.

Unit testing

  • Test class: AuditRepositoryTestBase.java (executed via InMemoryAuditRepositoryTest)

  • Tests added:

    • testGetEntitiesWithTagChanges — verifies CLASSIFICATION_ADD, CLASSIFICATION_DELETE, CLASSIFICATION_UPDATE events within the time range return their entity GUIDs
    • testGetEntitiesWithTagChanges_emptyForNoMatchingTimeRange — verifies events outside the queried time window are excluded
    • testGetEntitiesWithTagChanges_deduplicatesEntities — verifies multiple classification events for the same entity produce only one GUID in the result set

@bhor-sanket bhor-sanket changed the title ATLAS-5425:Implement getEntitiesWithTagChanges for RDBMS audit reposi… ATLAS-5425:Implement getEntitiesWithTagChanges for RDBMS audit repository Oct 15, 2026
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