Browse Source

[ui-dataCatalog] fix key generation bug that caused frontend cache to fail

Björn Alm 2 tháng trước cách đây
mục cha
commit
d242f6bc62

+ 66 - 2
desktop/core/src/desktop/js/catalog/dataCatalog.test.ts

@@ -16,6 +16,7 @@
 
 import { Compute, Connector, Namespace } from 'config/types';
 import dataCatalog from './dataCatalog';
+import { TableAnalysis } from './DataCatalogEntry';
 
 const connectorOne: Connector = {
   buttonName: '',
@@ -35,7 +36,7 @@ const connectorTwo: Connector = {
   type: ''
 };
 
-const compute: Compute = { id: 'computeId', name: '', type: '' };
+const compute: Compute = { id: 'computeId', name: 'testCompute', type: '' };
 
 const namespaceOne: Namespace = { computes: [compute], id: 'namespaceOne', name: '', status: '' };
 const namespaceTwo: Namespace = { computes: [compute], id: 'namespaceTwo', name: '', status: '' };
@@ -53,8 +54,35 @@ const clearStorage = async (): Promise<void> => {
   await dataCatalog.getCatalog(connectorTwo).clearStorageCascade();
 };
 
+const createMockAnalysis = (comment: string): TableAnalysis => ({
+  cols: [],
+  comment,
+  details: { properties: {}, stats: {} },
+  hdfs_link: '',
+  is_view: false,
+  message: '',
+  name: '',
+  partition_keys: [],
+  path_location: '',
+  primary_keys: [],
+  properties: [],
+  stats: [],
+  hueTimestamp: Date.now()
+});
+
 describe('dataCatalog.ts', () => {
-  beforeEach(clearStorage);
+  beforeEach(() => {
+    // Enable caching for tests so that we can test the cache key generation
+    (window as unknown as { CACHEABLE_TTL: { default: number } }).CACHEABLE_TTL = {
+      default: 3600000
+    }; // 1 hour
+    return clearStorage();
+  });
+
+  afterEach(() => {
+    // Clean up global state to prevent test pollution
+    delete (window as unknown as { CACHEABLE_TTL?: { default: number } }).CACHEABLE_TTL;
+  });
 
   afterAll(clearStorage);
 
@@ -107,4 +135,40 @@ describe('dataCatalog.ts', () => {
       expect(caught).toBeTruthy();
     });
   });
+
+  describe('cache key consistency', () => {
+    it('should generate consistent cache keys between save and load operations', async () => {
+      const testCases = [
+        { path: ['db1'], description: 'database level' },
+        { path: ['db1', 'table1'], description: 'table level' },
+        { path: ['db1', 'table1', 'col1'], description: 'column level' }
+      ];
+
+      for (const testCase of testCases) {
+        const entry = await getEntry(testCase.path);
+
+        // Mock the store to capture the cache key used during save
+        let savedCacheKey: string | undefined;
+        const originalSetItem = entry.dataCatalog.store.setItem;
+        entry.dataCatalog.store.setItem = jest
+          .fn()
+          .mockImplementation((key: string, value: unknown) => {
+            savedCacheKey = key;
+            return originalSetItem.call(entry.dataCatalog.store, key, value);
+          });
+
+        // Save analysis data
+        entry.analysis = createMockAnalysis(`test comment for ${testCase.description}`);
+        await entry.save();
+
+        // Verify cache key format: namespace_computeName_path
+        const expectedKey = `${namespaceOne.id}_${compute.name}_${testCase.path.join('.')}`;
+        expect(savedCacheKey).toBe(expectedKey);
+        expect(savedCacheKey).not.toContain('undefined');
+
+        // Restore original method for next iteration
+        entry.dataCatalog.store.setItem = originalSetItem;
+      }
+    });
+  });
 });

+ 5 - 1
desktop/core/src/desktop/js/catalog/dataCatalog.ts

@@ -359,7 +359,11 @@ export class DataCatalog {
     if (!cacheEnabled || !confTtl.default || confTtl.default <= 0) {
       return;
     }
-    const identifier = generateEntryCacheId(dataCatalogEntry);
+    const identifier = generateEntryCacheId({
+      namespace: dataCatalogEntry.namespace,
+      path: dataCatalogEntry.path,
+      computeName: dataCatalogEntry.compute.name
+    });
 
     await this.store.setItem<StoreEntry>(identifier, {
       version: DATA_CATALOG_VERSION,