bhor-sanket opened a new pull request, #791:
URL: https://github.com/apache/atlas/pull/791

   ## 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().             
                                               
   - I**mpact**: 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        
                                                                                
          
   2. **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<String> (entity GUIDs), follows existing error-handling 
convention                                                                      
                                                        
   
   3. **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<String> 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


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to