Commit 3cc70bc9 authored by Yannick's avatar Yannick
Browse files

keep secret value to avoid multiple sync call to the keyvault

parent 0673eec6
__version__ = '1.1.1'
__version__ = '1.1.2'
......@@ -10,7 +10,8 @@ from osdu_az.identity.az_identity import AzureIdentity
_LOGGER = logging.getLogger(__name__)
class PartitionInfo():
class PartitionInfo:
def __init__(self, partition_properties: dict = None):
self._partition_properties = partition_properties
self._secret_client = None
......@@ -23,13 +24,14 @@ class PartitionInfo():
if not partition_property.get('sensitive'):
return partition_property['value']
secret = self._get_secret(partition_property['value'])
return secret.value
if 'secret' not in partition_property:
partition_property['secret'] = self._get_secret(partition_property['value']).value
return partition_property['secret']
def _get_secret(self, key: str):
ts = datetime.utcnow()
secret = self._get_secret_client().get_secret(key)
_LOGGER.info(f'PartitionInfo get secret took {(datetime.utcnow() - ts).total_seconds()} ms')
_LOGGER.debug(f'PartitionInfo get secret took {(datetime.utcnow() - ts).total_seconds()} s')
return secret
def _get_secret_client(self):
......
import logging
from os import environ
import asyncio
from osdu_az.opendes.fake_partition_client import FakePartitionClient
from osdu_az.opendes.partition_client import PartitionClient
......@@ -26,15 +27,20 @@ PARTITION_ID = 'id'
class PartitionService:
partition_client = None
scope = ''
partition_cache_lock = asyncio.Lock()
@staticmethod
async def get_partition(data_partition_id: str) -> PartitionInfo:
partition_info = PartitionsCache.get(data_partition_id)
if not partition_info:
partition_info = await PartitionService._partition_client().get_partition(data_partition_id)
if partition_info:
_LOGGER.info(f'PartitionService fetching partition info for "{data_partition_id}"')
PartitionsCache.set(data_partition_id, partition_info)
async with PartitionService.partition_cache_lock:
# this prevent multi fetch in case of concurrency when cache expired and so avoid unnecessary calls
partition_info = PartitionsCache.get(data_partition_id)
if not partition_info:
_LOGGER.info(f'PartitionService fetching partition info for "{data_partition_id}"')
partition_info = await PartitionService._partition_client().get_partition(data_partition_id)
if partition_info:
PartitionsCache.set(data_partition_id, partition_info)
return partition_info
@staticmethod
......
import logging
from cachetools import TTLCache
import uuid
_LOGGER = logging.getLogger(__name__)
class PartitionsCache:
......@@ -10,6 +14,7 @@ class PartitionsCache:
@staticmethod
def set(data_partition_id: str, partition_info):
_LOGGER.debug(f"partition info for '{data_partition_id}' put in cache")
PartitionsCache.partitions_cache[data_partition_id] = partition_info
@staticmethod
......
......@@ -42,6 +42,7 @@ partition_service_response = \
}
"""
def test_get_value():
storage_account_name = 'mocked_storage_account_name_in_key_vault'
......@@ -55,11 +56,13 @@ def test_get_value():
assert (partition_info.get_value('storage-account-name') == storage_account_name)
kv_mock.get_secret.assert_called_with('opendes-storage')
def test_get_value_invalid_property_name():
properties = json.loads(partition_service_response)
partition_info = PartitionInfo(partition_properties=properties)
assert (partition_info.get_value('invalid-partition-service-property') is None)
def test_get_value_non_sensitive():
kv_mock = MagicMock()
......@@ -69,3 +72,19 @@ def test_get_value_non_sensitive():
assert (partition_info.get_value('compliance-ruleset') == 'shared')
kv_mock.get_secret.assert_not_called()
def test_not_trigger_key_vault_fetch_twice():
storage_account_name = 'mocked_storage_account_name_in_key_vault'
kv_mock = MagicMock()
kv_mock.get_secret.return_value = KeyVaultSecret('opendes-storage', storage_account_name)
properties = json.loads(partition_service_response)
partition_info = PartitionInfo(partition_properties=properties)
partition_info._secret_client = kv_mock
partition_info.get_value('storage-account-name')
partition_info.get_value('storage-account-name')
kv_mock.get_secret.assert_called_once()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment