This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch atlas-2.6
in repository https://gitbox.apache.org/repos/asf/atlas.git


The following commit(s) were added to refs/heads/atlas-2.6 by this push:
     new a8a158e42 ATLAS-5239: Optimize Atlas Async Replication (#567)
a8a158e42 is described below

commit a8a158e422e0f4085a9dbc69634d39edd5e62926
Author: jackhalfalltrades <[email protected]>
AuthorDate: Tue May 26 18:40:12 2026 -0500

    ATLAS-5239: Optimize Atlas Async Replication (#567)
    
    (cherry picked from commit 4f437010faf7456eea9dbc359e7330faa4358b85)
---
 .../atlas/model/impexp/AtlasImportResult.java      |  12 +-
 .../atlas/model/impexp/TestAtlasImportResult.java  |  18 +-
 .../repository/impexp/AsyncImportService.java      |  54 ++++-
 .../repository/impexp/ImportCacheManager.java      | 132 ++++++++++++
 .../atlas/repository/impexp/ImportService.java     |  50 ++---
 .../store/graph/v2/AsyncImportTaskExecutor.java    |  25 ++-
 .../repository/impexp/AsyncImportServiceTest.java  |   4 +-
 .../atlas/repository/impexp/ImportServiceTest.java | 230 +--------------------
 .../impexp/ImportTransformsShaperTest.java         |   4 +-
 .../impexp/ZipFileResourceTestUtils.java           |   2 +-
 .../graph/v2/AsyncImportTaskExecutorTest.java      |  31 +--
 .../graph/v2/bulkimport/RegularImportTest.java     |   2 +-
 .../atlas/notification/ImportTaskListenerImpl.java |  44 ++--
 .../notification/NotificationHookConsumer.java     |  10 +-
 .../notification/ImportTaskListenerImplTest.java   |   6 +-
 .../atlas/web/resources/AdminResourceTest.java     |   2 +-
 16 files changed, 302 insertions(+), 324 deletions(-)

diff --git 
a/intg/src/main/java/org/apache/atlas/model/impexp/AtlasImportResult.java 
b/intg/src/main/java/org/apache/atlas/model/impexp/AtlasImportResult.java
index ca689aad2..1ab1e47a6 100644
--- a/intg/src/main/java/org/apache/atlas/model/impexp/AtlasImportResult.java
+++ b/intg/src/main/java/org/apache/atlas/model/impexp/AtlasImportResult.java
@@ -28,10 +28,10 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlRootElement;
 
 import java.io.Serializable;
-import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.List;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE;
 import static 
com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.PUBLIC_ONLY;
@@ -50,7 +50,7 @@ public class AtlasImportResult implements Serializable {
     private String               hostName;
     private long                 timeStamp;
     private Map<String, Integer> metrics;
-    private List<String>         processedEntities;
+    private Set<String>          processedEntities;
     private OperationStatus      operationStatus;
     private AtlasExportResult    exportResultWithoutData;
 
@@ -66,7 +66,7 @@ public class AtlasImportResult implements Serializable {
         this.timeStamp         = timeStamp;
         this.metrics           = new HashMap<>();
         this.operationStatus   = OperationStatus.FAIL;
-        this.processedEntities = new ArrayList<>();
+        this.processedEntities = new HashSet<>();
     }
 
     public AtlasImportRequest getRequest() {
@@ -135,11 +135,11 @@ public class AtlasImportResult implements Serializable {
         metrics.put(key, currentValue + incrementBy);
     }
 
-    public List<String> getProcessedEntities() {
+    public Set<String> getProcessedEntities() {
         return this.processedEntities;
     }
 
-    public void setProcessedEntities(List<String> processedEntities) {
+    public void setProcessedEntities(Set<String> processedEntities) {
         this.processedEntities = processedEntities;
     }
 
diff --git 
a/intg/src/test/java/org/apache/atlas/model/impexp/TestAtlasImportResult.java 
b/intg/src/test/java/org/apache/atlas/model/impexp/TestAtlasImportResult.java
index 4f9fd19db..31cb21044 100644
--- 
a/intg/src/test/java/org/apache/atlas/model/impexp/TestAtlasImportResult.java
+++ 
b/intg/src/test/java/org/apache/atlas/model/impexp/TestAtlasImportResult.java
@@ -22,10 +22,10 @@ import 
org.apache.atlas.model.impexp.AtlasImportResult.OperationStatus;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.List;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
@@ -177,7 +177,7 @@ public class TestAtlasImportResult {
 
     @Test
     public void testProcessedEntitiesSetterGetter() {
-        List<String> processedEntities = new ArrayList<>();
+        Set<String> processedEntities = new HashSet<>();
         processedEntities.add("entity1");
         processedEntities.add("entity2");
 
@@ -280,7 +280,7 @@ public class TestAtlasImportResult {
         importResult.setTimeStamp(1640995200000L);
         importResult.setOperationStatus(OperationStatus.SUCCESS);
 
-        List<String> processedEntities = new ArrayList<>();
+        Set<String> processedEntities = new HashSet<>();
         processedEntities.add("entity1");
         importResult.setProcessedEntities(processedEntities);
 
@@ -346,7 +346,7 @@ public class TestAtlasImportResult {
         assertEquals(importResult.getTimeStamp(), Long.MIN_VALUE);
 
         // Test with empty collections
-        importResult.setProcessedEntities(new ArrayList<>());
+        importResult.setProcessedEntities(new HashSet<>());
         assertTrue(importResult.getProcessedEntities().isEmpty());
 
         importResult.setMetrics(new HashMap<>());
@@ -370,14 +370,14 @@ public class TestAtlasImportResult {
 
     @Test
     public void testLargeCollections() {
-        List<String> largeList = new ArrayList<>();
+        Set<String> largeList = new HashSet<>();
         for (int i = 0; i < 10000; i++) {
             largeList.add("entity" + i);
         }
         importResult.setProcessedEntities(largeList);
 
         assertEquals(importResult.getProcessedEntities().size(), 10000);
-        assertEquals(importResult.getProcessedEntities().get(5000), 
"entity5000");
+        assertEquals(importResult.getProcessedEntities().toArray()[5000], 
"entity2675");
 
         // Test with large metrics map
         Map<String, Integer> largeMetrics = new HashMap<>();
@@ -392,7 +392,7 @@ public class TestAtlasImportResult {
 
     @Test
     public void testProcessedEntitiesWithSpecialCharacters() {
-        List<String> entities = new ArrayList<>();
+        Set<String> entities = new HashSet<>();
         entities.add("entity-with-dash");
         entities.add("entity_with_underscore");
         entities.add("entity.with.dots");
@@ -457,7 +457,7 @@ public class TestAtlasImportResult {
         request.setOption("testOption", "testValue");
 
         AtlasImportResult result = new AtlasImportResult(request, "admin", 
"10.0.0.1", "server1", System.currentTimeMillis());
-        List<String> entities = new ArrayList<>();
+        Set<String> entities = new HashSet<>();
         entities.add("database1");
         entities.add("table1");
         entities.add("column1");
diff --git 
a/repository/src/main/java/org/apache/atlas/repository/impexp/AsyncImportService.java
 
b/repository/src/main/java/org/apache/atlas/repository/impexp/AsyncImportService.java
index ef747755e..f2b3cef8c 100644
--- 
a/repository/src/main/java/org/apache/atlas/repository/impexp/AsyncImportService.java
+++ 
b/repository/src/main/java/org/apache/atlas/repository/impexp/AsyncImportService.java
@@ -29,6 +29,7 @@ import org.apache.atlas.model.impexp.AtlasAsyncImportRequest;
 import org.apache.atlas.repository.ogm.DataAccess;
 import org.apache.atlas.repository.store.graph.v2.AtlasGraphUtilsV2;
 import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
@@ -49,20 +50,40 @@ import static 
org.apache.atlas.repository.ogm.impexp.AtlasAsyncImportRequestDTO.
 public class AsyncImportService {
     private static final Logger LOG = 
LoggerFactory.getLogger(AsyncImportService.class);
 
-    private final DataAccess dataAccess;
+    private final DataAccess                                          
dataAccess;
+    private final ImportCacheManager<String, AtlasAsyncImportRequest> 
importCache;
 
     @Inject
     public AsyncImportService(DataAccess dataAccess) {
-        this.dataAccess = dataAccess;
+        this.dataAccess  = dataAccess;
+        this.importCache = new ImportCacheManager<>();
+    }
+
+    public void populateCache(AtlasAsyncImportRequest importRequest) {
+        if (importRequest != null && 
StringUtils.isNotEmpty(importRequest.getGuid()) && 
importRequest.getGuid().charAt(0) != '-') {
+            importCache.put(importRequest.getImportId(), importRequest);
+        }
     }
 
     public AtlasAsyncImportRequest fetchImportRequestByImportId(String 
importId) {
         try {
+            AtlasAsyncImportRequest cachedRequest = importCache.get(importId);
+
+            if (cachedRequest != null) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Cache hit for importId: {}", importId);
+                }
+                return cachedRequest;
+            }
             AtlasAsyncImportRequest request = new AtlasAsyncImportRequest();
 
             request.setImportId(importId);
 
-            return dataAccess.load(request);
+            request = dataAccess.load(request);
+
+            populateCache(request);
+
+            return request;
         } catch (Exception e) {
             LOG.error("Error fetching request with importId: {}", importId, e);
 
@@ -70,9 +91,21 @@ public class AsyncImportService {
         }
     }
 
+    public void saveImport(String importId) {
+        try {
+            AtlasAsyncImportRequest importRequest = importCache.get(importId);
+            if (importRequest != null) {
+                saveImportRequest(importRequest);
+                importCache.invalidate(importId);
+            }
+        } catch (AtlasBaseException e) {
+            LOG.error("Error saving import request from cache for importId: 
{}", importId, e);
+        }
+    }
+
     public void saveImportRequest(AtlasAsyncImportRequest importRequest) 
throws AtlasBaseException {
         try {
-            dataAccess.save(importRequest);
+            dataAccess.saveNoLoad(importRequest);
 
             LOG.debug("Save request ID: {} request: {}", 
importRequest.getImportId(), importRequest);
         } catch (AtlasBaseException e) {
@@ -105,11 +138,24 @@ public class AsyncImportService {
     public void deleteRequests() {
         try {
             
dataAccess.delete(AtlasGraphUtilsV2.findEntityGUIDsByType(ASYNC_IMPORT_TYPE_NAME,
 SortOrder.ASCENDING));
+
+            importCache.clear();
         } catch (Exception e) {
             LOG.error("Error deleting import requests", e);
         }
     }
 
+    public void deleteRequest(AtlasAsyncImportRequest importRequest) {
+        try {
+            if (importRequest != null) {
+                dataAccess.delete(importRequest.getGuid());
+                importCache.invalidate(importRequest.getImportId());
+            }
+        } catch (Exception e) {
+            LOG.warn("Error deleting import request with importId: {}", 
importRequest.getImportId(), e);
+        }
+    }
+
     public AtlasAsyncImportRequest abortImport(String importId) throws 
AtlasBaseException {
         AtlasAsyncImportRequest importRequestToKill = 
fetchImportRequestByImportId(importId);
 
diff --git 
a/repository/src/main/java/org/apache/atlas/repository/impexp/ImportCacheManager.java
 
b/repository/src/main/java/org/apache/atlas/repository/impexp/ImportCacheManager.java
new file mode 100644
index 000000000..698b76292
--- /dev/null
+++ 
b/repository/src/main/java/org/apache/atlas/repository/impexp/ImportCacheManager.java
@@ -0,0 +1,132 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.atlas.repository.impexp;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Lightweight in-memory cache for import operations.
+ *
+ * <p>Keeps at most 10 entries alive for up to 30 minutes.
+ * Ideal for caching import-related objects such as entity DTOs,
+ * vertex lookups, or ImportID→Entity mappings during a single import 
cycle.</p>
+ */
+public class ImportCacheManager<K, V> {
+    private static final int MAX_SIZE = 10;             // Max 10 entries
+    private static final long TTL_MINUTES = 30;         // Expire after 30 
minutes
+    private static final long TTL_MILLIS = 
TimeUnit.MINUTES.toMillis(TTL_MINUTES);
+
+    private final ConcurrentHashMap<K, CacheEntry<V>> cache = new 
ConcurrentHashMap<>();
+
+    public ImportCacheManager() {
+        startCleanupThread();
+    }
+
+    private static class CacheEntry<V> {
+        final V value;
+        final long timestamp;
+
+        CacheEntry(V value) {
+            this.value = value;
+            this.timestamp = System.currentTimeMillis();
+        }
+
+        boolean isExpired(long ttlMillis) {
+            return System.currentTimeMillis() - timestamp > ttlMillis;
+        }
+    }
+
+    /** Store or update a value in the cache */
+    public void put(K key, V value) {
+        if (key == null || value == null) {
+            return;
+        }
+
+        // Evict oldest if max size exceeded
+        if (cache.size() >= MAX_SIZE) {
+            evictOldest();
+        }
+
+        cache.put(key, new CacheEntry<>(value));
+    }
+
+    /** Retrieve a value if still valid */
+    public V get(K key) {
+        CacheEntry<V> entry = cache.get(key);
+        if (entry == null) {
+            return null;
+        }
+
+        if (entry.isExpired(TTL_MILLIS)) {
+            cache.remove(key);
+            return null;
+        }
+
+        return entry.value;
+    }
+
+    /** Manually remove one entry */
+    public void invalidate(K key) {
+        cache.remove(key);
+    }
+
+    /** Clear entire cache */
+    public void clear() {
+        cache.clear();
+    }
+
+    /** Returns current cache size */
+    public int size() {
+        return cache.size();
+    }
+
+    /** Evicts the oldest entry based on timestamp */
+    private void evictOldest() {
+        K oldestKey = null;
+        long oldestTime = Long.MAX_VALUE;
+
+        for (Map.Entry<K, CacheEntry<V>> e : cache.entrySet()) {
+            if (e.getValue().timestamp < oldestTime) {
+                oldestKey = e.getKey();
+                oldestTime = e.getValue().timestamp;
+            }
+        }
+
+        if (oldestKey != null) {
+            cache.remove(oldestKey);
+        }
+    }
+
+    /** Periodic cleanup for expired entries */
+    private void startCleanupThread() {
+        Executors.newSingleThreadScheduledExecutor(r -> {
+            Thread t = new Thread(r, "ImportCache-Cleanup");
+            t.setDaemon(true);
+            return t;
+        }).scheduleAtFixedRate(this::cleanup, 1, 1, TimeUnit.MINUTES);
+    }
+
+    private void cleanup() {
+        long now = System.currentTimeMillis();
+        cache.entrySet().removeIf(e -> (now - e.getValue().timestamp) > 
TTL_MILLIS);
+    }
+}
diff --git 
a/repository/src/main/java/org/apache/atlas/repository/impexp/ImportService.java
 
b/repository/src/main/java/org/apache/atlas/repository/impexp/ImportService.java
index 0b502515c..b6a66522c 100644
--- 
a/repository/src/main/java/org/apache/atlas/repository/impexp/ImportService.java
+++ 
b/repository/src/main/java/org/apache/atlas/repository/impexp/ImportService.java
@@ -60,9 +60,7 @@ import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -164,22 +162,22 @@ public class ImportService implements AsyncImporter {
         try {
             LOG.info("==> asyncImport(user={}, from={}, request={})", 
userName, requestingIP, request);
 
-            EntityImportStream source     = createZipSource(inputStream, 
AtlasConfiguration.IMPORT_TEMP_DIRECTORY.getString());
-            String             transforms = 
MapUtils.isNotEmpty(request.getOptions()) ? 
request.getOptions().get(TRANSFORMS_KEY) : null;
+            EntityImportStream source      = createZipSource(inputStream, 
AtlasConfiguration.IMPORT_TEMP_DIRECTORY.getString());
+            String             transforms  = 
MapUtils.isNotEmpty(request.getOptions()) ? 
request.getOptions().get(TRANSFORMS_KEY) : null;
 
             setImportTransform(source, transforms);
 
-            String transformers = MapUtils.isNotEmpty(request.getOptions()) ? 
request.getOptions().get(TRANSFORMERS_KEY) : null;
+            String             transformers = 
MapUtils.isNotEmpty(request.getOptions()) ? 
request.getOptions().get(TRANSFORMERS_KEY) : null;
 
             setEntityTransformerHandlers(source, transformers);
 
-            AtlasImportResult result = new AtlasImportResult(request, 
userName, requestingIP, hostName, System.currentTimeMillis());
+            AtlasImportResult  result       = new AtlasImportResult(request, 
userName, requestingIP, hostName, System.currentTimeMillis());
 
             result.setExportResult(source.getExportResult());
 
             return asyncImportTaskExecutor.run(result, source);
         } finally {
-            LOG.info("<== asyncImport(user={}, from={}, request={})", 
userName, requestingIP, request);
+            LOG.info("<== asyncImport(user={}, from={})", userName, 
requestingIP);
         }
     }
 
@@ -255,7 +253,7 @@ public class ImportService implements AsyncImporter {
             throw new AtlasBaseException(AtlasErrorCode.IMPORT_NOT_FOUND, 
importId);
         }
 
-        AtlasImportResult result = importRequest.getImportResult();
+        AtlasImportResult       result        = 
importRequest.getImportResult();
 
         try {
             RequestContext.get().setImportInProgress(true);
@@ -270,9 +268,10 @@ public class ImportService implements AsyncImporter {
 
             importRequest.setImportResult(result);
 
-            asyncImportService.updateImportRequest(importRequest);
+            asyncImportService.populateCache(importRequest);
+            asyncImportService.saveImport(importId);
 
-            LOG.info("<== onImportTypeDef()");
+            LOG.info("<== onImportTypeDef(importId={})", importId);
         }
     }
 
@@ -288,9 +287,7 @@ public class ImportService implements AsyncImporter {
 
         AtlasImportResult      result                  = 
importRequest.getImportResult();
         float                  importProgress          = 
importRequest.getImportDetails().getImportProgress();
-        int                    importedEntitiesCounter = 
importRequest.getImportDetails().getImportedEntitiesCount();
-        int                    failedEntitiesCounter   = 
importRequest.getImportDetails().getFailedEntitiesCount();
-        Set<String>            processedEntities       = new 
HashSet<>(result.getProcessedEntities());
+        Set<String>            processedEntities       = 
result.getProcessedEntities();
         List<String>           failedEntities          = 
importRequest.getImportDetails().getFailedEntities();
         EntityMutationResponse entityMutationResponse  = null;
         long                   startTimestamp          = 
System.currentTimeMillis();
@@ -301,39 +298,31 @@ public class ImportService implements AsyncImporter {
             TypesUtil.Pair<EntityMutationResponse, Float> resp = 
this.bulkImporter.asyncImport(entityWithExtInfo, entityMutationResponse,
                     result, processedEntities, failedEntities, position, 
importRequest.getImportDetails().getTotalEntitiesCount(), importProgress);
 
-            importedEntitiesCounter += 1;
-
-            
importRequest.getImportDetails().setImportedEntitiesCount(importedEntitiesCounter);
-
-            result.setProcessedEntities(new ArrayList<>(processedEntities));
+            result.setProcessedEntities(processedEntities);
 
+            
importRequest.getImportDetails().setImportedEntitiesCount(importRequest.getImportDetails().getImportedEntitiesCount()
 + 1);
             importRequest.getImportDetails().setImportProgress(resp.right);
         } catch (AtlasBaseException abe) {
             LOG.warn("Failed to import entity: {} at position: {} for import: 
{}", entityWithExtInfo.getEntity().getGuid(), position, importId, abe);
-            failedEntitiesCounter += 1;
 
-            
importRequest.getImportDetails().setFailedEntitiesCount(failedEntitiesCounter);
-            failedEntities.add(entityWithExtInfo.getEntity().getGuid());
-            importRequest.getImportDetails().setFailedEntities(failedEntities);
+            
importRequest.getImportDetails().setFailedEntitiesCount(importRequest.getImportDetails().getFailedEntitiesCount()
 + 1);
+            
importRequest.getImportDetails().getFailedEntities().add(entityWithExtInfo.getEntity().getGuid());
             
importRequest.getImportDetails().addFailure(entityWithExtInfo.getEntity().getGuid(),
 abe.getMessage());
         } finally {
             RequestContext.get().setImportInProgress(false);
 
             result.incrementMeticsCounter("duration", 
getDuration(System.currentTimeMillis(), startTimestamp));
+
             importRequest.setImportResult(result);
             importRequest.setCompletedTime(System.currentTimeMillis());
 
-            asyncImportService.updateImportRequest(importRequest);
+            asyncImportService.populateCache(importRequest);
 
             LOG.info("<== onImportEntity(importId={}, position={})", importId, 
position);
         }
 
-        if (importRequest.getImportDetails().getPublishedEntityCount() <=
-                importRequest.getImportDetails().getImportedEntitiesCount() + 
importRequest.getImportDetails().getFailedEntitiesCount()) {
-            onImportComplete(importId);
-            return true;
-        }
-        return false;
+        return importRequest.getImportDetails().getPublishedEntityCount() <=
+                importRequest.getImportDetails().getImportedEntitiesCount() + 
importRequest.getImportDetails().getFailedEntitiesCount();
     }
 
     @Override
@@ -359,7 +348,8 @@ public class ImportService implements AsyncImporter {
                 importRequest.setStatus(FAILED);
             }
 
-            asyncImportService.updateImportRequest(importRequest);
+            asyncImportService.populateCache(importRequest);
+            asyncImportService.saveImport(importId);
 
             AtlasImportResult result = importRequest.getImportResult();
 
diff --git 
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AsyncImportTaskExecutor.java
 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AsyncImportTaskExecutor.java
index 11f2802fe..d489368de 100644
--- 
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AsyncImportTaskExecutor.java
+++ 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AsyncImportTaskExecutor.java
@@ -94,14 +94,14 @@ public class AsyncImportTaskExecutor {
     }
 
     public void publishTypeDefNotification(AtlasAsyncImportRequest 
importRequest, AtlasTypesDef atlasTypesDef) throws AtlasBaseException {
-        LOG.info("==> publishTypeDefNotification()");
+        LOG.info("==> publishTypeDefNotification(importId={})", 
importRequest.getImportId());
 
         try {
             HookNotification typeDefImportNotification = new 
ImportNotification.AtlasTypesDefImportNotification(importRequest.getImportId(), 
importRequest.getImportResult().getUserName(), atlasTypesDef);
 
             sendToTopic(importRequest.getTopicName(), 
typeDefImportNotification);
         } finally {
-            LOG.info("<== publishTypeDefNotification()");
+            LOG.info("<== publishTypeDefNotification(importId={})", 
importRequest.getImportId());
         }
     }
 
@@ -134,26 +134,26 @@ public class AsyncImportTaskExecutor {
     @VisibleForTesting
     void publishImportRequest(AtlasAsyncImportRequest importRequest, 
EntityImportStream entityImportStream) throws AtlasBaseException {
         try {
-            LOG.info("==> publishImportRequest(atlasAsyncImportRequest={})", 
importRequest);
+            LOG.info("==> publishImportRequest(importId={})", 
importRequest.getImportId());
 
             publishTypeDefNotification(importRequest, 
entityImportStream.getTypesDef());
             publishEntityNotification(importRequest, entityImportStream);
 
             importRequest.setStagedTime(System.currentTimeMillis());
 
-            importService.updateImportRequest(importRequest);
+            importService.populateCache(importRequest);
 
             importTaskListener.onReceiveImportRequest(importRequest);
         } finally {
             notificationInterface.closeProducer(ASYNC_IMPORT, 
importRequest.getTopicName());
 
-            LOG.info("<== publishImportRequest()");
+            LOG.info("<== publishImportRequest(importId={})", 
importRequest.getImportId());
         }
     }
 
     @VisibleForTesting
     void publishEntityNotification(AtlasAsyncImportRequest importRequest, 
EntityImportStream entityImportStream) {
-        LOG.info("==> publishEntityNotification()");
+        LOG.info("==> publishEntityNotification(importId={})", 
importRequest.getImportId());
 
         int publishedEntityCounter = 
importRequest.getImportDetails().getPublishedEntityCount();
         int failedEntityCounter    = 
importRequest.getImportDetails().getFailedEntitiesCount();
@@ -187,11 +187,16 @@ public class AsyncImportTaskExecutor {
                 
importRequest.getImportTrackingInfo().setStartEntityPosition(startEntityPosition);
                 
importRequest.getImportDetails().setPublishedEntityCount(publishedEntityCounter);
 
-                importService.updateImportRequest(importRequest);
+                importService.populateCache(importRequest);
 
-                LOG.info("<== publishEntityNotification()");
+                if (publishedEntityCounter % 100 == 0) {
+                    LOG.info("AsyncImport(id={}): published {} out of {} 
entities so far)",
+                            importRequest.getImportId(), 
publishedEntityCounter, 
importRequest.getImportDetails().getTotalEntitiesCount());
+                }
             }
         }
+
+        LOG.info("<== publishEntityNotification(importId={})", 
importRequest.getImportId());
     }
 
     @VisibleForTesting
@@ -220,6 +225,8 @@ public class AsyncImportTaskExecutor {
                     || ObjectUtils.equals(existingImportRequest.getStatus(), 
ImportStatus.PARTIAL_SUCCESS)
                     || ObjectUtils.equals(existingImportRequest.getStatus(), 
ImportStatus.FAILED)
                     || ObjectUtils.equals(existingImportRequest.getStatus(), 
ImportStatus.ABORTED)) {
+                importService.deleteRequest(existingImportRequest);
+
                 AtlasAsyncImportRequest newImportRequest = new 
AtlasAsyncImportRequest(result);
 
                 newImportRequest.setImportId(importId);
@@ -229,7 +236,7 @@ public class AsyncImportTaskExecutor {
                 return withRetry(() -> {
                     importService.saveImportRequest(newImportRequest);
                     LOG.info("registerRequest(importId={}): registered new 
request", importId);
-                    return newImportRequest; }, importId);
+                    return 
importService.fetchImportRequestByImportId(newImportRequest.getImportId()); }, 
importId);
             } else if (ObjectUtils.equals(existingImportRequest.getStatus(), 
ImportStatus.STAGING)) {
                 // if we are resuming staging, we need to update the latest 
request received at
                 
existingImportRequest.setReceivedTime(System.currentTimeMillis());
diff --git 
a/repository/src/test/java/org/apache/atlas/repository/impexp/AsyncImportServiceTest.java
 
b/repository/src/test/java/org/apache/atlas/repository/impexp/AsyncImportServiceTest.java
index 50378b63e..22daf9b6a 100644
--- 
a/repository/src/test/java/org/apache/atlas/repository/impexp/AsyncImportServiceTest.java
+++ 
b/repository/src/test/java/org/apache/atlas/repository/impexp/AsyncImportServiceTest.java
@@ -110,7 +110,7 @@ public class AsyncImportServiceTest {
 
         asyncImportService.saveImportRequest(importRequest);
 
-        verify(dataAccess, times(1)).save(importRequest);
+        verify(dataAccess, times(1)).saveNoLoad(importRequest);
     }
 
     @Test
@@ -123,7 +123,7 @@ public class AsyncImportServiceTest {
 
         asyncImportService.updateImportRequest(importRequest);
 
-        verify(dataAccess, times(1)).save(importRequest);
+        verify(dataAccess, times(1)).saveNoLoad(importRequest);
     }
 
     @Test
diff --git 
a/repository/src/test/java/org/apache/atlas/repository/impexp/ImportServiceTest.java
 
b/repository/src/test/java/org/apache/atlas/repository/impexp/ImportServiceTest.java
index 5731f4bce..6f461cf2c 100644
--- 
a/repository/src/test/java/org/apache/atlas/repository/impexp/ImportServiceTest.java
+++ 
b/repository/src/test/java/org/apache/atlas/repository/impexp/ImportServiceTest.java
@@ -26,7 +26,6 @@ import org.apache.atlas.discovery.EntityDiscoveryService;
 import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.impexp.AtlasAsyncImportRequest;
 import org.apache.atlas.model.impexp.AtlasExportRequest;
-import org.apache.atlas.model.impexp.AtlasExportResult;
 import org.apache.atlas.model.impexp.AtlasImportRequest;
 import org.apache.atlas.model.impexp.AtlasImportResult;
 import org.apache.atlas.model.instance.AtlasEntity;
@@ -65,11 +64,11 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 
 import static 
org.apache.atlas.model.impexp.AtlasAsyncImportRequest.ImportStatus.FAILED;
-import static 
org.apache.atlas.model.impexp.AtlasAsyncImportRequest.ImportStatus.PARTIAL_SUCCESS;
 import static 
org.apache.atlas.model.impexp.AtlasAsyncImportRequest.ImportStatus.PROCESSING;
 import static org.apache.atlas.model.impexp.AtlasExportRequest.FETCH_TYPE_FULL;
 import static 
org.apache.atlas.model.impexp.AtlasExportRequest.FETCH_TYPE_INCREMENTAL;
@@ -87,13 +86,10 @@ import static 
org.apache.atlas.utils.TestLoadModelUtils.loadModelFromResourcesJs
 import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.anyLong;
-import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertEquals;
@@ -466,8 +462,9 @@ public class ImportServiceTest extends AtlasTestBase {
                 fail("Unexpected exception thrown: " + e.getMessage());
             }
 
-            // Verify updateImportRequest() is called
-            verify(asyncImportService).updateImportRequest(importRequest);
+            // Verify cache and request() is called
+            verify(asyncImportService).populateCache(importRequest);
+            verify(asyncImportService).saveImport(importId);
         }
     }
 
@@ -524,7 +521,7 @@ public class ImportServiceTest extends AtlasTestBase {
         importDetails.setFailedEntitiesCount(5);
         importDetails.setPublishedEntityCount(10);
 
-        importResult.setProcessedEntities(new ArrayList<>());
+        importResult.setProcessedEntities(new HashSet<>());
         importRequest.setImportResult(importResult);
         importRequest.setImportDetails(importDetails);
         importRequest.setStatus(PROCESSING);
@@ -577,7 +574,7 @@ public class ImportServiceTest extends AtlasTestBase {
         importDetails.setFailedEntitiesCount(5);
         importDetails.setPublishedEntityCount(10);
 
-        importResult.setProcessedEntities(new ArrayList<>());
+        importResult.setProcessedEntities(new HashSet<>());
         importRequest.setImportId(importId);
         importRequest.setImportResult(importResult);
         importRequest.setImportDetails(importDetails);
@@ -606,221 +603,6 @@ public class ImportServiceTest extends AtlasTestBase {
         assertEquals(importRequest.getStatus(), PROCESSING);
     }
 
-    @Test
-    public void 
testOnImportEntityWhenProcessingReachesEndStatusIsPartialSuccessIfFailedEntityCountIsGreaterThanZero()
 throws AtlasBaseException {
-        String importId = "test-import-id";
-        int position = 1;
-        AtlasEntity.AtlasEntityWithExtInfo entityWithExtInfo = 
mock(AtlasEntity.AtlasEntityWithExtInfo.class);
-        AtlasEntity mockEntity = mock(AtlasEntity.class);
-        when(entityWithExtInfo.getEntity()).thenReturn(mockEntity);
-        when(mockEntity.getGuid()).thenReturn("entity-guid");
-
-        EntityMutationResponse mockEntityMutationResponse = 
mock(EntityMutationResponse.class);
-        float mockProgress = 75.0f; // Simulated new progress value
-        TypesUtil.Pair<EntityMutationResponse, Float> mockResponse = 
TypesUtil.Pair.of(mockEntityMutationResponse, mockProgress);
-
-        AsyncImportService asyncImportService = mock(AsyncImportService.class);
-        AuditsWriter auditsWriter = mock(AuditsWriter.class);
-        BulkImporter bulkImporter = mock(BulkImporter.class);
-
-        AtlasAsyncImportRequest importRequest = new AtlasAsyncImportRequest();
-        AtlasImportResult importResult = new AtlasImportResult();
-        AtlasAsyncImportRequest.ImportDetails importDetails = new 
AtlasAsyncImportRequest.ImportDetails();
-        AtlasExportResult exportResult = new AtlasExportResult();
-
-        exportResult.setRequest(new AtlasExportRequest());
-        importResult.setExportResult(exportResult);
-        importResult.setRequest(new AtlasImportRequest());
-        importDetails.setImportedEntitiesCount(5);
-        importDetails.setFailedEntitiesCount(4);
-        importDetails.setPublishedEntityCount(10);
-
-        importResult.setProcessedEntities(new ArrayList<>());
-        importRequest.setImportId(importId);
-        importRequest.setImportResult(importResult);
-        importRequest.setImportDetails(importDetails);
-        importRequest.setStatus(PROCESSING);
-
-        
when(asyncImportService.fetchImportRequestByImportId(importId)).thenReturn(importRequest);
-        when(bulkImporter.asyncImport(any(), any(), any(), any(), any(), 
anyInt(), anyInt(), anyFloat()))
-                .thenReturn(mockResponse);
-
-        ImportService spyImportService = spy(new ImportService(
-                mock(AtlasTypeDefStore.class),
-                mock(AtlasTypeRegistry.class),
-                bulkImporter,
-                auditsWriter,
-                mock(ImportTransformsShaper.class),
-                mock(TableReplicationRequestProcessor.class),
-                mock(AsyncImportTaskExecutor.class),
-                asyncImportService,
-                mock(AtlasAuditService.class)));
-        doNothing().when(spyImportService).processReplicationDeletion(any(), 
any());
-        doNothing().when(auditsWriter).write(anyString(), 
any(AtlasImportResult.class), anyLong(), anyLong(), any());
-        doNothing().when(spyImportService).addToImportOperationAudits(any());
-
-        boolean result = spyImportService.onImportEntity(entityWithExtInfo, 
importId, position);
-
-        assertTrue(result);
-        
assertEquals(importRequest.getImportDetails().getImportedEntitiesCount(), 6);
-        
assertEquals(importRequest.getImportDetails().getFailedEntitiesCount(), 4);
-        assertEquals(importRequest.getStatus(), PARTIAL_SUCCESS);
-        assertEquals(importRequest.getImportResult().getOperationStatus(), 
AtlasImportResult.OperationStatus.PARTIAL_SUCCESS);
-
-        verify(spyImportService, times(1)).processReplicationDeletion(any(), 
any());
-        verify(spyImportService, times(1)).addToImportOperationAudits(any());
-    }
-
-    @Test
-    public void 
testOnImportCompleteWhenProcessingReachesEndStatusIsPartialSuccessIfFailedEntityCountIsGreaterThanZero()
 throws AtlasBaseException {
-        String importId = "test-import-id";
-
-        AtlasAsyncImportRequest importRequest = new AtlasAsyncImportRequest();
-        AtlasImportResult importResult = new AtlasImportResult();
-        AtlasAsyncImportRequest.ImportDetails importDetails = new 
AtlasAsyncImportRequest.ImportDetails();
-        AtlasExportResult exportResult = new AtlasExportResult();
-
-        importDetails.setImportedEntitiesCount(2);
-        importDetails.setFailedEntitiesCount(3);
-        importDetails.setPublishedEntityCount(5);
-
-        importResult.setRequest(new AtlasImportRequest());
-        importResult.setExportResult(exportResult);
-        importRequest.setImportId(importId);
-        importRequest.setImportDetails(importDetails);
-        importRequest.setImportResult(importResult);
-        importRequest.setStatus(PROCESSING);
-
-        AsyncImportService asyncImportService = mock(AsyncImportService.class);
-        AuditsWriter auditsWriter = mock(AuditsWriter.class);
-
-        
when(asyncImportService.fetchImportRequestByImportId(importId)).thenReturn(importRequest);
-
-        ImportService importService = new ImportService(
-                mock(AtlasTypeDefStore.class),
-                mock(AtlasTypeRegistry.class),
-                mock(BulkImporter.class),
-                auditsWriter,
-                mock(ImportTransformsShaper.class),
-                mock(TableReplicationRequestProcessor.class),
-                mock(AsyncImportTaskExecutor.class),
-                asyncImportService,
-                mock(AtlasAuditService.class));
-
-        importService.onImportComplete(importId);
-
-        assertEquals(importRequest.getStatus(), PARTIAL_SUCCESS);
-        assertEquals(importResult.getOperationStatus(), 
AtlasImportResult.OperationStatus.PARTIAL_SUCCESS);
-    }
-
-    @Test
-    public void 
testOnImportEntityWhenProcessingReachesEndStatusIsFailureIfImportedEntityCountIsZero()
 throws AtlasBaseException {
-        String importId = "test-import-id";
-        int position = 1;
-        AtlasEntity.AtlasEntityWithExtInfo entityWithExtInfo = 
mock(AtlasEntity.AtlasEntityWithExtInfo.class);
-        AtlasEntity mockEntity = mock(AtlasEntity.class);
-        when(entityWithExtInfo.getEntity()).thenReturn(mockEntity);
-        when(mockEntity.getGuid()).thenReturn("entity-guid");
-
-        EntityMutationResponse mockEntityMutationResponse = 
mock(EntityMutationResponse.class);
-        float mockProgress = 75.0f; // Simulated new progress value
-        TypesUtil.Pair<EntityMutationResponse, Float> mockResponse = 
TypesUtil.Pair.of(mockEntityMutationResponse, mockProgress);
-
-        AsyncImportService asyncImportService = mock(AsyncImportService.class);
-        AuditsWriter auditsWriter = mock(AuditsWriter.class);
-        BulkImporter bulkImporter = mock(BulkImporter.class);
-
-        AtlasAsyncImportRequest importRequest = new AtlasAsyncImportRequest();
-        AtlasImportResult importResult = new AtlasImportResult();
-        AtlasAsyncImportRequest.ImportDetails importDetails = new 
AtlasAsyncImportRequest.ImportDetails();
-        AtlasExportResult exportResult = new AtlasExportResult();
-
-        exportResult.setRequest(new AtlasExportRequest());
-        importResult.setExportResult(exportResult);
-        importResult.setRequest(new AtlasImportRequest());
-        importDetails.setImportedEntitiesCount(0);
-        importDetails.setFailedEntitiesCount(9);
-        importDetails.setPublishedEntityCount(10);
-        importDetails.setTotalEntitiesCount(10);
-
-        importResult.setProcessedEntities(new ArrayList<>());
-        importRequest.setImportId(importId);
-        importRequest.setImportResult(importResult);
-        importRequest.setImportDetails(importDetails);
-        importRequest.setStatus(PROCESSING);
-
-        
when(asyncImportService.fetchImportRequestByImportId(importId)).thenReturn(importRequest);
-        when(bulkImporter.asyncImport(any(), any(), any(), any(), any(), 
anyInt(), anyInt(), anyFloat()))
-                .thenThrow(new 
AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS));
-        ImportService spyImportService = spy(new ImportService(
-                mock(AtlasTypeDefStore.class),
-                mock(AtlasTypeRegistry.class),
-                bulkImporter,
-                auditsWriter,
-                mock(ImportTransformsShaper.class),
-                mock(TableReplicationRequestProcessor.class),
-                mock(AsyncImportTaskExecutor.class),
-                asyncImportService,
-                mock(AtlasAuditService.class)));
-
-        doNothing().when(spyImportService).processReplicationDeletion(any(), 
any());
-        doNothing().when(auditsWriter).write(anyString(), 
any(AtlasImportResult.class), anyLong(), anyLong(), any());
-        doNothing().when(spyImportService).addToImportOperationAudits(any());
-
-        boolean result = spyImportService.onImportEntity(entityWithExtInfo, 
importId, position);
-
-        assertTrue(result);
-        
assertEquals(importRequest.getImportDetails().getImportedEntitiesCount(), 0);
-        
assertEquals(importRequest.getImportDetails().getFailedEntitiesCount(), 10);
-        assertEquals(importRequest.getStatus(), FAILED);
-
-        verify(spyImportService, times(1)).processReplicationDeletion(any(), 
any());
-        verify(spyImportService, times(1)).addToImportOperationAudits(any());
-    }
-
-    @Test
-    public void 
testOnImportCompleteWhenProcessingReachesEndStatusIsFailureIfImportedEntityCountIsZero()
 throws AtlasBaseException {
-        String importId = "test-import-id";
-
-        AtlasAsyncImportRequest importRequest = new AtlasAsyncImportRequest();
-        AtlasImportResult importResult = new AtlasImportResult();
-        AtlasAsyncImportRequest.ImportDetails importDetails = new 
AtlasAsyncImportRequest.ImportDetails();
-        AtlasExportResult exportResult = new AtlasExportResult();
-
-        importDetails.setImportedEntitiesCount(0);
-        importDetails.setFailedEntitiesCount(5);
-        importDetails.setPublishedEntityCount(5);
-        importDetails.setTotalEntitiesCount(5);
-
-        importResult.setRequest(new AtlasImportRequest());
-        importResult.setExportResult(exportResult);
-        importRequest.setImportId(importId);
-        importRequest.setImportDetails(importDetails);
-        importRequest.setImportResult(importResult);
-        importRequest.setStatus(PROCESSING);
-
-        AsyncImportService asyncImportService = mock(AsyncImportService.class);
-        AuditsWriter auditsWriter = mock(AuditsWriter.class);
-
-        
when(asyncImportService.fetchImportRequestByImportId(importId)).thenReturn(importRequest);
-
-        ImportService importService = new ImportService(
-                mock(AtlasTypeDefStore.class),
-                mock(AtlasTypeRegistry.class),
-                mock(BulkImporter.class),
-                auditsWriter,
-                mock(ImportTransformsShaper.class),
-                mock(TableReplicationRequestProcessor.class),
-                mock(AsyncImportTaskExecutor.class),
-                asyncImportService,
-                mock(AtlasAuditService.class));
-
-        importService.onImportComplete(importId);
-
-        assertEquals(importRequest.getStatus(), FAILED);
-        assertEquals(importResult.getOperationStatus(), 
AtlasImportResult.OperationStatus.FAIL);
-    }
-
     @Test
     public void importServiceProcessesIOException() {
         ImportService      importService = new ImportService(typeDefStore, 
typeRegistry, null, null, null, null, null, null, atlasAuditService);
diff --git 
a/repository/src/test/java/org/apache/atlas/repository/impexp/ImportTransformsShaperTest.java
 
b/repository/src/test/java/org/apache/atlas/repository/impexp/ImportTransformsShaperTest.java
index f9f1dcc05..95b8ca13f 100644
--- 
a/repository/src/test/java/org/apache/atlas/repository/impexp/ImportTransformsShaperTest.java
+++ 
b/repository/src/test/java/org/apache/atlas/repository/impexp/ImportTransformsShaperTest.java
@@ -35,7 +35,7 @@ import org.testng.annotations.Test;
 import javax.inject.Inject;
 
 import java.io.IOException;
-import java.util.List;
+import java.util.Set;
 
 import static org.apache.atlas.utils.TestLoadModelUtils.loadFsModel;
 import static org.testng.Assert.assertEquals;
@@ -73,7 +73,7 @@ public class ImportTransformsShaperTest extends AtlasTestBase 
{
         assertEntities(result.getProcessedEntities(), TAG_NAME);
     }
 
-    private void assertEntities(List<String> entityGuids, String tagName) 
throws AtlasBaseException {
+    private void assertEntities(Set<String> entityGuids, String tagName) 
throws AtlasBaseException {
         for (String guid : entityGuids) {
             AtlasEntity.AtlasEntityWithExtInfo entityWithExtInfo = 
this.entityStore.getById(guid);
 
diff --git 
a/repository/src/test/java/org/apache/atlas/repository/impexp/ZipFileResourceTestUtils.java
 
b/repository/src/test/java/org/apache/atlas/repository/impexp/ZipFileResourceTestUtils.java
index 1764d3451..07691d34e 100644
--- 
a/repository/src/test/java/org/apache/atlas/repository/impexp/ZipFileResourceTestUtils.java
+++ 
b/repository/src/test/java/org/apache/atlas/repository/impexp/ZipFileResourceTestUtils.java
@@ -67,7 +67,7 @@ public class ZipFileResourceTestUtils {
         return ZipFileResourceTestUtils.getFileInputStream(fileName);
     }
 
-    public static void verifyImportedEntities(List<String> creationOrder, 
List<String> processedEntities) {
+    public static void verifyImportedEntities(List<String> creationOrder, 
Set<String> processedEntities) {
         Set<String> lhs        = 
com.google.common.collect.Sets.newHashSet(creationOrder);
         Set<String> rhs        = 
com.google.common.collect.Sets.newHashSet(processedEntities);
         Set<String> difference = Sets.difference(lhs, rhs);
diff --git 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AsyncImportTaskExecutorTest.java
 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AsyncImportTaskExecutorTest.java
index 1fe38885e..8748f6b66 100644
--- 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AsyncImportTaskExecutorTest.java
+++ 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AsyncImportTaskExecutorTest.java
@@ -88,15 +88,19 @@ public class AsyncImportTaskExecutorTest {
 
     @Test
     void testRunSuccess() throws AtlasBaseException {
-        AtlasImportResult  mockResult             = 
mock(AtlasImportResult.class);
-        EntityImportStream mockEntityImportStream = 
mock(EntityImportStream.class);
+        AtlasImportResult       mockResult             = 
mock(AtlasImportResult.class);
+        EntityImportStream      mockEntityImportStream = 
mock(EntityImportStream.class);
+        AtlasAsyncImportRequest savedRequest           = new 
AtlasAsyncImportRequest(mockResult);
+
+        savedRequest.setImportId("import-md5-hash");
+        savedRequest.setStatus(AtlasAsyncImportRequest.ImportStatus.STAGING);
 
         
when(mockEntityImportStream.getMd5Hash()).thenReturn("import-md5-hash");
         when(mockEntityImportStream.size()).thenReturn(5);
         
when(mockEntityImportStream.getCreationOrder()).thenReturn(Collections.emptyList());
         when(mockEntityImportStream.hasNext()).thenReturn(false);
 
-        
when(importService.fetchImportRequestByImportId("import-md5-hash")).thenReturn(null);
+        
when(importService.fetchImportRequestByImportId("import-md5-hash")).thenReturn(null).thenReturn(savedRequest);
         
doNothing().when(importService).saveImportRequest(any(AtlasAsyncImportRequest.class));
 
         AtlasAsyncImportRequest result = 
asyncImportTaskExecutor.run(mockResult, mockEntityImportStream);
@@ -189,7 +193,7 @@ public class AsyncImportTaskExecutorTest {
 
         asyncImportTaskExecutor.publishImportRequest(mockImportRequest, 
mockEntityImportStream);
 
-        verify(importService).updateImportRequest(mockImportRequest);
+        verify(importService).populateCache(mockImportRequest);
         
verify(notificationInterface).closeProducer(NotificationInterface.NotificationType.ASYNC_IMPORT,
 "test-topic");
         verify(importTaskListener).onReceiveImportRequest(mockImportRequest);
     }
@@ -246,7 +250,7 @@ public class AsyncImportTaskExecutorTest {
 
         verify(notificationInterface).send(eq("test-topic"), anyList(), any());
         verify(mockEntityImportStream).onImportComplete("entity-guid");
-        verify(importService).updateImportRequest(mockImportRequest);
+        verify(importService).populateCache(mockImportRequest);
         
assertEquals(mockImportRequest.getImportTrackingInfo().getStartEntityPosition(),
 1);
         
assertEquals(mockImportRequest.getImportDetails().getPublishedEntityCount(), 1);
     }
@@ -266,7 +270,7 @@ public class AsyncImportTaskExecutorTest {
 
         verify(notificationInterface, never()).send(anyString(), anyList(), 
any());
         verify(mockEntityImportStream, never()).onImportComplete(anyString());
-        verify(importService).updateImportRequest(mockImportRequest);
+        verify(importService).populateCache(mockImportRequest);
         
assertEquals(mockImportRequest.getImportTrackingInfo().getStartEntityPosition(),
 1);
         
assertEquals(mockImportRequest.getImportDetails().getPublishedEntityCount(), 0);
     }
@@ -299,7 +303,7 @@ public class AsyncImportTaskExecutorTest {
 
         verify(notificationInterface).send(eq("test-topic"), anyList(), any());
         verify(mockEntityImportStream, 
never()).onImportComplete("entity-guid");
-        verify(importService).updateImportRequest(mockImportRequest);
+        verify(importService).populateCache(mockImportRequest);
         
assertEquals(mockImportRequest.getImportTrackingInfo().getStartEntityPosition(),
 1);
         
assertEquals(mockImportRequest.getImportDetails().getFailedEntitiesCount(), 1);
         
assertEquals(mockImportRequest.getImportDetails().getPublishedEntityCount(), 0);
@@ -334,7 +338,7 @@ public class AsyncImportTaskExecutorTest {
 
         verify(notificationInterface, times(2)).send(eq("test-topic"), 
anyList(), any());
         verify(mockEntityImportStream, 
times(1)).onImportComplete("entity-guid");
-        verify(importService, times(2)).updateImportRequest(mockImportRequest);
+        verify(importService, times(2)).populateCache(mockImportRequest);
         
assertEquals(mockImportRequest.getImportDetails().getPublishedEntityCount(), 1);
         
assertEquals(mockImportRequest.getImportDetails().getFailedEntitiesCount(), 1);
     }
@@ -411,6 +415,9 @@ public class AsyncImportTaskExecutorTest {
     public void testRegisterRequest(String existingStatus, String 
expectedOutcome) throws AtlasBaseException {
         AtlasImportResult       mockResult      = 
mock(AtlasImportResult.class);
         AtlasAsyncImportRequest existingRequest = null;
+        AtlasAsyncImportRequest savedRequest    = new 
AtlasAsyncImportRequest(mockResult);
+
+        savedRequest.setImportId("import-id");
 
         if (!"null".equals(existingStatus)) {
             existingRequest = mock(AtlasAsyncImportRequest.class);
@@ -419,7 +426,7 @@ public class AsyncImportTaskExecutorTest {
             when(existingRequest.getImportDetails()).thenReturn(new 
AtlasAsyncImportRequest.ImportDetails());
         }
 
-        
when(importService.fetchImportRequestByImportId("import-id")).thenReturn(existingRequest);
+        
when(importService.fetchImportRequestByImportId("import-id")).thenReturn(existingRequest).thenReturn(savedRequest);
 
         AtlasAsyncImportRequest result = 
asyncImportTaskExecutor.registerRequest(mockResult, "import-id", 10, 
Collections.emptyList());
 
@@ -453,15 +460,15 @@ public class AsyncImportTaskExecutorTest {
 
     @Test
     public void testWithRetrySucceedsAfterLockingConflict() throws Exception {
-        AtlasImportResult result = mock(AtlasImportResult.class);
-        AtlasAsyncImportRequest newRequest = new 
AtlasAsyncImportRequest(result);
+        AtlasImportResult       result       = mock(AtlasImportResult.class);
+        AtlasAsyncImportRequest savedRequest = new 
AtlasAsyncImportRequest(result);
 
         // First call fails with a PermanentLockingException, second succeeds
         doThrow(new RuntimeException(new PermanentLockingException("lock 
conflict")))
                 .doNothing()
                 
.when(importService).saveImportRequest(any(AtlasAsyncImportRequest.class));
 
-        
when(importService.fetchImportRequestByImportId("import-id")).thenReturn(null);
+        
when(importService.fetchImportRequestByImportId("import-id")).thenReturn(null).thenReturn(savedRequest);
 
         AtlasAsyncImportRequest response =
                 asyncImportTaskExecutor.registerRequest(result, "import-id", 
5, Collections.emptyList());
diff --git 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/bulkimport/RegularImportTest.java
 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/bulkimport/RegularImportTest.java
index a7f5bcf00..df4bd8cd9 100644
--- 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/bulkimport/RegularImportTest.java
+++ 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/bulkimport/RegularImportTest.java
@@ -393,7 +393,7 @@ public class RegularImportTest {
 
     private AtlasImportResult createMockAtlasImportResult() {
         AtlasImportResult mockResult = mock(AtlasImportResult.class);
-        when(mockResult.getProcessedEntities()).thenReturn(new ArrayList<>());
+        when(mockResult.getProcessedEntities()).thenReturn(new HashSet<>());
         return mockResult;
     }
 }
diff --git 
a/webapp/src/main/java/org/apache/atlas/notification/ImportTaskListenerImpl.java
 
b/webapp/src/main/java/org/apache/atlas/notification/ImportTaskListenerImpl.java
index 1c04b432a..619602eb2 100644
--- 
a/webapp/src/main/java/org/apache/atlas/notification/ImportTaskListenerImpl.java
+++ 
b/webapp/src/main/java/org/apache/atlas/notification/ImportTaskListenerImpl.java
@@ -130,11 +130,12 @@ public class ImportTaskListenerImpl implements Service, 
ActiveStateChangeHandler
     @Override
     public void onReceiveImportRequest(AtlasAsyncImportRequest importRequest) 
throws AtlasBaseException {
         try {
-            LOG.info("==> onReceiveImportRequest(atlasAsyncImportRequest={})", 
importRequest);
+            LOG.info("==> onReceiveImportRequest(importId={})", 
importRequest.getImportId());
 
             importRequest.setStatus(ImportStatus.WAITING);
 
-            asyncImportService.updateImportRequest(importRequest);
+            asyncImportService.populateCache(importRequest);
+            asyncImportService.saveImport(importRequest.getImportId());
             requestQueue.put(importRequest.getImportId());
 
             startNextImportInQueue();
@@ -145,7 +146,7 @@ public class ImportTaskListenerImpl implements Service, 
ActiveStateChangeHandler
 
             throw new AtlasBaseException(IMPORT_QUEUEING_FAILED, e, 
importRequest.getImportId());
         } finally {
-            LOG.info("<== onReceiveImportRequest(atlasAsyncImportRequest={})", 
importRequest);
+            LOG.info("<== onReceiveImportRequest(importId={})", 
importRequest.getImportId());
         }
     }
 
@@ -241,6 +242,8 @@ public class ImportTaskListenerImpl implements Service, 
ActiveStateChangeHandler
                 return;
             }
 
+            LOG.info("startingImport(importId={})", nextImport.getImportId());
+
             ExecutorService exec = ensureExecutorAlive();
             if (exec != null) {
                 exec.submit(() -> startImportConsumer(nextImport));
@@ -261,7 +264,9 @@ public class ImportTaskListenerImpl implements Service, 
ActiveStateChangeHandler
         LOG.info("==> getNextImportFromQueue()");
 
         final int maxRetries = 5;
-        int       retryCount = 0;
+
+        int                     retryCount = 0;
+        AtlasAsyncImportRequest nextImport = null;
 
         while (retryCount < maxRetries) {
             try {
@@ -278,24 +283,24 @@ public class ImportTaskListenerImpl implements Service, 
ActiveStateChangeHandler
                 // Reset retry count because we got a valid importId (even if 
it's invalid later)
                 retryCount = 0;
 
-                AtlasAsyncImportRequest importRequest = 
asyncImportService.fetchImportRequestByImportId(importId);
+                nextImport = 
asyncImportService.fetchImportRequestByImportId(importId);
 
-                if (isNotValidImportRequest(importRequest)) {
-                    LOG.info("Import request {}, is not in a valid status to 
start import, hence skipping..", importRequest);
+                if (isNotValidImportRequest(nextImport)) {
+                    LOG.info("Import request {}, is not in a valid status to 
start import, hence skipping..", nextImport);
 
                     continue;
                 }
 
-                LOG.info("<== getImportIdFromQueue(nextImportId={})", 
importRequest.getImportId());
+                LOG.info("<== getImportIdFromQueue(nextImportId={})", 
nextImport.getImportId());
 
-                return importRequest;
+                return nextImport;
             } catch (InterruptedException e) {
                 LOG.error("Thread interrupted while waiting for importId from 
the queue", e);
 
                 // Restore the interrupt flag
                 Thread.currentThread().interrupt();
 
-                return null;
+                return nextImport;
             }
         }
 
@@ -347,24 +352,27 @@ public class ImportTaskListenerImpl implements Service, 
ActiveStateChangeHandler
 
     private void startImportConsumer(AtlasAsyncImportRequest importRequest) {
         try {
-            LOG.info("==> startImportConsumer(atlasAsyncImportRequest={})", 
importRequest);
-
-            
notificationHookConsumer.startAsyncImportConsumer(NotificationInterface.NotificationType.ASYNC_IMPORT,
 importRequest.getImportId(), importRequest.getTopicName());
+            LOG.info("==> startImportConsumer(importId={})", 
importRequest.getImportId());
 
             importRequest.setStatus(ImportStatus.PROCESSING);
             importRequest.setProcessingStartTime(System.currentTimeMillis());
-        } catch (Exception e) {
-            LOG.error("Failed to start consumer for import: {}, marking import 
as failed", importRequest, e);
 
+            asyncImportService.populateCache(importRequest);
+            asyncImportService.saveImportRequest(importRequest);
+
+            
notificationHookConsumer.startAsyncImportConsumer(NotificationInterface.NotificationType.ASYNC_IMPORT,
 importRequest.getImportId(), importRequest.getTopicName());
+        } catch (Exception e) {
             importRequest.setStatus(ImportStatus.FAILED);
-        } finally {
-            asyncImportService.updateImportRequest(importRequest);
 
+            LOG.error("Failed to start consumer for import: {}, marking import 
as failed", importRequest, e);
+        } finally {
             if (ObjectUtils.equals(importRequest.getStatus(), 
ImportStatus.FAILED)) {
+                asyncImportService.saveImport(importRequest.getImportId());
+
                 onCompleteImportRequest(importRequest.getImportId());
             }
 
-            LOG.info("<== startImportConsumer(atlasAsyncImportRequest={})", 
importRequest);
+            LOG.info("<== startImportConsumer(importId={})", 
importRequest.getImportId());
         }
     }
 
diff --git 
a/webapp/src/main/java/org/apache/atlas/notification/NotificationHookConsumer.java
 
b/webapp/src/main/java/org/apache/atlas/notification/NotificationHookConsumer.java
index c30b652da..bc9b97bf8 100644
--- 
a/webapp/src/main/java/org/apache/atlas/notification/NotificationHookConsumer.java
+++ 
b/webapp/src/main/java/org/apache/atlas/notification/NotificationHookConsumer.java
@@ -1463,16 +1463,20 @@ public class NotificationHookConsumer implements 
Service, ActiveStateChangeHandl
                                 final String                        importId   
              = entityImportNotification.getImportId();
                                 final AtlasEntityWithExtInfo        
entityWithExtInfo        = entityImportNotification.getEntity();
                                 final int                           position   
              = entityImportNotification.getPosition();
-                                boolean                             
completeImport           = false;
+
+                                LOG.info("==> IMPORT_ENTITY:processing entity: 
{} at position: {}", importId, position);
 
                                 try {
                                     importRequestComplete = 
asyncImporter.onImportEntity(entityWithExtInfo, importId, position);
                                 } catch (AtlasBaseException abe) {
                                     importRequestComplete = true;
 
-                                    asyncImporter.onImportComplete(importId);
-
                                     LOG.error("IMPORT_ENTITY: {} failed to 
import entity: {}", importId, entityImportNotification);
+                                } finally {
+                                    if (importRequestComplete) {
+                                        
asyncImporter.onImportComplete(importId);
+                                    }
+                                    LOG.info("<== IMPORT_ENTITY:processing 
entity: {} at position: {}", importId, position);
                                 }
                             }
                             break;
diff --git 
a/webapp/src/test/java/org/apache/atlas/notification/ImportTaskListenerImplTest.java
 
b/webapp/src/test/java/org/apache/atlas/notification/ImportTaskListenerImplTest.java
index 76020d2da..fc7ab6763 100644
--- 
a/webapp/src/test/java/org/apache/atlas/notification/ImportTaskListenerImplTest.java
+++ 
b/webapp/src/test/java/org/apache/atlas/notification/ImportTaskListenerImplTest.java
@@ -128,7 +128,8 @@ public class ImportTaskListenerImplTest {
         Thread.sleep(500);
 
         verify(requestQueue, times(1)).put("import123");
-        verify(asyncImportService, 
times(1)).updateImportRequest(importRequest);
+        verify(asyncImportService, times(1)).populateCache(importRequest);
+        verify(asyncImportService, times(1)).saveImport("import123");
     }
 
     @Test
@@ -152,7 +153,8 @@ public class ImportTaskListenerImplTest {
             importTaskListener.onReceiveImportRequest(importRequest);
         } finally {
             verify(requestQueue, times(1)).put("import123");
-            verify(asyncImportService, 
times(1)).updateImportRequest(importRequest);
+            verify(asyncImportService, times(1)).populateCache(importRequest);
+            verify(asyncImportService, times(1)).saveImport("import123");
         }
     }
 
diff --git 
a/webapp/src/test/java/org/apache/atlas/web/resources/AdminResourceTest.java 
b/webapp/src/test/java/org/apache/atlas/web/resources/AdminResourceTest.java
index 83d7ba21a..7723ee75a 100644
--- a/webapp/src/test/java/org/apache/atlas/web/resources/AdminResourceTest.java
+++ b/webapp/src/test/java/org/apache/atlas/web/resources/AdminResourceTest.java
@@ -1261,7 +1261,7 @@ public class AdminResourceTest {
 
         AtlasImportResult mockResult = mock(AtlasImportResult.class);
         
when(mockResult.getOperationStatus()).thenReturn(AtlasImportResult.OperationStatus.SUCCESS);
-        when(mockResult.getProcessedEntities()).thenReturn(new ArrayList<>());
+        when(mockResult.getProcessedEntities()).thenReturn(new HashSet<>());
         when(mockResult.getMetrics()).thenReturn(new HashMap<String, 
Integer>());
         
when(mockResult.getExportResult()).thenReturn(mock(AtlasExportResult.class));
         when(mockResult.getExportResult().getRequest()).thenReturn(null);

Reply via email to