From 912879da3d806aa82a931e955d7aa94265df236d Mon Sep 17 00:00:00 2001 From: Eliana Rosselli Date: Fri, 20 Dec 2024 10:15:31 -0300 Subject: [PATCH 1/2] Add cache-clearing methods to DBCache --- src/fides/api/models/db_cache.py | 38 +++++++ tests/ops/models/test_dbcache.py | 184 +++++++++++++++++++++++++++++++ 2 files changed, 222 insertions(+) diff --git a/src/fides/api/models/db_cache.py b/src/fides/api/models/db_cache.py index 4102a0d942..7d19023d4b 100644 --- a/src/fides/api/models/db_cache.py +++ b/src/fides/api/models/db_cache.py @@ -87,3 +87,41 @@ def set_cache_value( db.commit() db.refresh(db_cache_entry) return db_cache_entry + + @classmethod + def delete_cache_entry( + cls, + db: Session, + namespace: DBCacheNamespace, + cache_key: str, + ) -> None: + """ + Deletes the cache entry for the given cache_key + """ + db.query(cls).filter( + cls.namespace == namespace.value, cls.cache_key == cache_key + ).delete() + db.commit() + + @classmethod + def clear_cache_for_namespace( + cls, + db: Session, + namespace: DBCacheNamespace, + ) -> None: + """ + Deletes all cache entries for the given namespace + """ + db.query(cls).filter(cls.namespace == namespace.value).delete() + db.commit() + + @classmethod + def clear_cache( + cls, + db: Session, + ) -> None: + """ + Deletes all cache entries + """ + db.query(cls).delete() + db.commit() diff --git a/tests/ops/models/test_dbcache.py b/tests/ops/models/test_dbcache.py index a1c48aec42..7fe9062fab 100644 --- a/tests/ops/models/test_dbcache.py +++ b/tests/ops/models/test_dbcache.py @@ -1,6 +1,14 @@ +from enum import Enum + from fides.api.models.db_cache import DBCache, DBCacheNamespace +# enum used to test extra namespaces since right now DBCacheNamespace only has one value +# this can be removed once more namespaces are added +class TestDbCacheNamespace(Enum): + TEST_NAMESPACE = "test-namespace" + + class TestDBCacheModel: def test_get_nonexisting_entry(self, db): cache_value = DBCache.get_cache_value( @@ -51,3 +59,179 @@ def test_update_cache_value(self, db): db, DBCacheNamespace.LIST_PRIVACY_EXPERIENCE, "some-key" ) assert updated_value.decode() == "value 2" + + def test_delete_cache_entry(self, db): + # Add two entries + DBCache.set_cache_value( + db, + DBCacheNamespace.LIST_PRIVACY_EXPERIENCE, + "some-key", + "value 1".encode(), + ) + DBCache.set_cache_value( + db, + DBCacheNamespace.LIST_PRIVACY_EXPERIENCE, + "some-key-2", + "value 2".encode(), + ) + assert ( + DBCache.get_cache_value( + db, DBCacheNamespace.LIST_PRIVACY_EXPERIENCE, "some-key" + ).decode() + == "value 1" + ) + assert ( + DBCache.get_cache_value( + db, DBCacheNamespace.LIST_PRIVACY_EXPERIENCE, "some-key-2" + ).decode() + == "value 2" + ) + + # Delete the first entry + DBCache.delete_cache_entry( + db, DBCacheNamespace.LIST_PRIVACY_EXPERIENCE, "some-key" + ) + + # Check the first entry was deleted + assert ( + DBCache.get_cache_value( + db, DBCacheNamespace.LIST_PRIVACY_EXPERIENCE, "some-key" + ) + is None + ) + + # Check the second entry still exists + assert ( + DBCache.get_cache_value( + db, DBCacheNamespace.LIST_PRIVACY_EXPERIENCE, "some-key-2" + ).decode() + == "value 2" + ) + + def test_clear_cache_for_namespace(self, db): + # Add three entries, two belonging to namespace LIST_PRIVACY_EXPERIENCE and one to another namespace + DBCache.set_cache_value( + db, + DBCacheNamespace.LIST_PRIVACY_EXPERIENCE, + "key-1", + "value 1".encode(), + ) + DBCache.set_cache_value( + db, + DBCacheNamespace.LIST_PRIVACY_EXPERIENCE, + "key-2", + "value 2".encode(), + ) + DBCache.set_cache_value( + db, + TestDbCacheNamespace.TEST_NAMESPACE, + "key-1", + "value 3".encode(), + ) + + # Check all entries exist + assert ( + DBCache.get_cache_value( + db, DBCacheNamespace.LIST_PRIVACY_EXPERIENCE, "key-1" + ).decode() + == "value 1" + ) + assert ( + DBCache.get_cache_value( + db, DBCacheNamespace.LIST_PRIVACY_EXPERIENCE, "key-2" + ).decode() + == "value 2" + ) + assert ( + DBCache.get_cache_value( + db, TestDbCacheNamespace.TEST_NAMESPACE, "key-1" + ).decode() + == "value 3" + ) + + # Clear the cache for LIST_PRIVACY_EXPERIENCE namespace + DBCache.clear_cache_for_namespace(db, DBCacheNamespace.LIST_PRIVACY_EXPERIENCE) + + # Check the entries belonging to LIST_PRIVACY_EXPERIENCE were deleted + assert ( + DBCache.get_cache_value( + db, DBCacheNamespace.LIST_PRIVACY_EXPERIENCE, "key-1" + ) + is None + ) + assert ( + DBCache.get_cache_value( + db, DBCacheNamespace.LIST_PRIVACY_EXPERIENCE, "key-2" + ) + is None + ) + + # Check the entry belonging to another namespace still exists + assert ( + DBCache.get_cache_value( + db, TestDbCacheNamespace.TEST_NAMESPACE, "key-1" + ).decode() + == "value 3" + ) + + def test_clear_cache(self, db): + # Add three entries, two belonging to namespace LIST_PRIVACY_EXPERIENCE and one to another namespace + DBCache.set_cache_value( + db, + DBCacheNamespace.LIST_PRIVACY_EXPERIENCE, + "key-1", + "value 1".encode(), + ) + DBCache.set_cache_value( + db, + DBCacheNamespace.LIST_PRIVACY_EXPERIENCE, + "key-2", + "value 2".encode(), + ) + DBCache.set_cache_value( + db, + TestDbCacheNamespace.TEST_NAMESPACE, + "key-1", + "value 3".encode(), + ) + + # Check all entries exist + assert ( + DBCache.get_cache_value( + db, DBCacheNamespace.LIST_PRIVACY_EXPERIENCE, "key-1" + ).decode() + == "value 1" + ) + assert ( + DBCache.get_cache_value( + db, DBCacheNamespace.LIST_PRIVACY_EXPERIENCE, "key-2" + ).decode() + == "value 2" + ) + assert ( + DBCache.get_cache_value( + db, TestDbCacheNamespace.TEST_NAMESPACE, "key-1" + ).decode() + == "value 3" + ) + + # Clear the cache + DBCache.clear_cache(db) + + # Check all entries were deleted + assert ( + DBCache.get_cache_value( + db, DBCacheNamespace.LIST_PRIVACY_EXPERIENCE, "key-1" + ) + is None + ) + assert ( + DBCache.get_cache_value( + db, DBCacheNamespace.LIST_PRIVACY_EXPERIENCE, "key-2" + ) + is None + ) + assert ( + DBCache.get_cache_value(db, TestDbCacheNamespace.TEST_NAMESPACE, "key-1") + is None + ) From 5137cdbfae2999de9a2619527e68943386b81082 Mon Sep 17 00:00:00 2001 From: Eliana Rosselli Date: Fri, 20 Dec 2024 10:21:05 -0300 Subject: [PATCH 2/2] Add changelog entry --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 325bba29cd..a73592389f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,9 @@ The types of changes are: ## [Unreleased](https://github.com/ethyca/fides/compare/2.52.0...main) +### Added +- Added cache-clearing methods to the `DBCache` model to allow deleting cache entries [#5629](https://github.com/ethyca/fides/pull/5629) + ## [2.52.0](https://github.com/ethyca/fides/compare/2.51.2...2.52.0)