Skip to content

Commit

Permalink
feat: separate studio config and handler (#185)
Browse files Browse the repository at this point in the history
refactor: store config column names in constants
  • Loading branch information
navinkarkera authored Apr 15, 2024
1 parent 9ed052c commit 17cf513
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 41 deletions.
8 changes: 4 additions & 4 deletions eox_tenant/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class EdunextOpenedxExtensionsTenantConfig(AppConfig):
'relative_path': 'signals',
'receivers': [
{
'receiver_func_name': 'start_tenant',
'receiver_func_name': 'start_lms_tenant',
'signal_path': 'django.core.signals.request_started',
},
{
Expand All @@ -53,7 +53,7 @@ class EdunextOpenedxExtensionsTenantConfig(AppConfig):
'signal_path': 'celery.signals.before_task_publish',
},
{
'receiver_func_name': 'start_async_tenant',
'receiver_func_name': 'start_async_lms_tenant',
'signal_path': 'celery.signals.task_prerun',
},
{
Expand All @@ -74,15 +74,15 @@ class EdunextOpenedxExtensionsTenantConfig(AppConfig):
'relative_path': 'signals',
'receivers': [
{
'receiver_func_name': 'start_tenant',
'receiver_func_name': 'start_studio_tenant',
'signal_path': 'django.core.signals.request_started',
},
{
'receiver_func_name': 'tenant_context_addition',
'signal_path': 'celery.signals.before_task_publish',
},
{
'receiver_func_name': 'start_async_tenant',
'receiver_func_name': 'start_async_studio_tenant',
'signal_path': 'celery.signals.task_prerun',
},
],
Expand Down
3 changes: 3 additions & 0 deletions eox_tenant/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
from django.conf import settings

LMS_ENVIRONMENT = getattr(settings, "SERVICE_VARIANT", None) == "lms"
CMS_ENVIRONMENT = getattr(settings, "SERVICE_VARIANT", None) == "cms"
LMS_CONFIG_COLUMN = "lms_configs"
CMS_CONFIG_COLUMN = "studio_configs"
10 changes: 6 additions & 4 deletions eox_tenant/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
from django.utils.translation import gettext_lazy as _
from jsonfield.fields import JSONField

from eox_tenant.constants import CMS_CONFIG_COLUMN, LMS_CONFIG_COLUMN


class TenantOrganization(models.Model):
"""
Expand Down Expand Up @@ -150,8 +152,8 @@ def get_configurations(self, domain):
configurations = {
"id": row[0],
"external_key": row[1],
"lms_configs": json.loads(row[2]),
"studio_configs": json.loads(row[3]),
LMS_CONFIG_COLUMN: json.loads(row[2]),
CMS_CONFIG_COLUMN: json.loads(row[3]),
"theming_configs": json.loads(row[4]),
"meta": json.loads(row[5]),
}
Expand Down Expand Up @@ -193,7 +195,7 @@ def get_organizations(self):
return org_filter

@classmethod
def get_configs_for_domain(cls, domain):
def get_configs_for_domain(cls, domain, config_key):
"""
Get edxapp configuration using a domain. There is a compat layer to support microsite until
deprecation.
Expand All @@ -204,7 +206,7 @@ def get_configs_for_domain(cls, domain):
config = TenantConfig.objects.get_configurations(domain=domain)

if config:
return config["lms_configs"], config["external_key"]
return config[config_key], config["external_key"]

return {}, None

Expand Down
5 changes: 3 additions & 2 deletions eox_tenant/receivers_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
from eox_tenant.models import Microsite, TenantConfig


def get_tenant_config_by_domain(domain):
def get_tenant_config_by_domain(domain, config_key):
"""
Reach for the configuration for a given domain.
**Arguments**
domain: String parameter.
config_key: Config column name.
**Returns**
configurations: dict
Expand All @@ -20,7 +21,7 @@ def get_tenant_config_by_domain(domain):
if not getattr(settings, 'USE_EOX_TENANT', False):
return {}, None

configurations, external_key = TenantConfig.get_configs_for_domain(domain)
configurations, external_key = TenantConfig.get_configs_for_domain(domain, config_key)

if configurations and external_key:
return configurations, external_key
Expand Down
47 changes: 39 additions & 8 deletions eox_tenant/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from django.conf import settings as base_settings

from eox_tenant.async_utils import AsyncTaskHandler
from eox_tenant.constants import CMS_CONFIG_COLUMN, LMS_CONFIG_COLUMN
from eox_tenant.receivers_helpers import get_tenant_config_by_domain
from eox_tenant.utils import synchronize_tenant_organizations

Expand All @@ -38,11 +39,11 @@
EOX_MAX_CONFIG_OVERRIDE_SECONDS = getattr(base_settings, "EOX_MAX_CONFIG_OVERRIDE_SECONDS", 300)


def _update_settings(domain):
def _update_settings(domain, config_key):
"""
Perform the override procedure on the settings object
"""
config, tenant_key = get_tenant_config_by_domain(domain)
config, tenant_key = get_tenant_config_by_domain(domain, config_key)

if not config.get("EDNX_USE_SIGNAL"):
LOG.info("Site %s, does not use eox_tenant signals", domain)
Expand Down Expand Up @@ -157,9 +158,24 @@ def _ttl_reached():
return False


def start_tenant(sender, environ, **kwargs): # pylint: disable=unused-argument
def start_lms_tenant(sender, environ, **kwargs): # pylint: disable=unused-argument
"""
This function runs every time a request is started in LMS.
Read documentation of `_start_tenant` for more details.
"""
_start_tenant(environ, LMS_CONFIG_COLUMN)


def start_studio_tenant(sender, environ, **kwargs): # pylint: disable=unused-argument
"""
This function runs every time a request is started in studio.
Read documentation of `_start_tenant` for more details.
"""
_start_tenant(environ, CMS_CONFIG_COLUMN)


def _start_tenant(environ, config_key):
"""
This function runs every time a request is started.
It will analyze the current settings object, the domain from the incoming
request and the configuration stored in the tenants for this domain.
Expand All @@ -182,7 +198,7 @@ def start_tenant(sender, environ, **kwargs): # pylint: disable=unused-argument
return

# Do the update
_update_settings(domain)
_update_settings(domain, config_key)


def finish_tenant(sender, **kwargs): # pylint: disable=unused-argument
Expand Down Expand Up @@ -219,9 +235,24 @@ def tenant_context_addition(sender, body, headers, *args, **kwargs): # pylint:
body['kwargs']['eox_tenant_sender'] = get_host_func(body)


def start_async_tenant(sender, *args, **kwargs): # pylint: disable=unused-argument
def start_async_lms_tenant(sender, *args, **kwargs): # pylint: disable=unused-argument
"""
Receiver that runs on the LMS async process to update the settings accordingly to the tenant.
Read documentation of `_start_tenant` for more details.
"""
_start_async_tenant(sender, LMS_CONFIG_COLUMN)


def start_async_studio_tenant(sender, *args, **kwargs): # pylint: disable=unused-argument
"""
Receiver that runs on the studio async process to update the settings accordingly to the tenant.
Read documentation of `_start_tenant` for more details.
"""
_start_async_tenant(sender, CMS_CONFIG_COLUMN)


def _start_async_tenant(sender, config_key):
"""
Receiver that runs on the async process to update the settings accordingly to the tenant.
Dispatched before a task is executed.
See:
https://celery.readthedocs.io/en/latest/userguide/signals.html#task-prerun
Expand All @@ -245,7 +276,7 @@ def start_async_tenant(sender, *args, **kwargs): # pylint: disable=unused-argum
return

# Do the update
_update_settings(domain)
_update_settings(domain, config_key)


def update_tenant_organizations(instance, **kwargs): # pylint: disable=unused-argument
Expand Down
35 changes: 30 additions & 5 deletions eox_tenant/test/test_receivers_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from django.test import TestCase

from eox_tenant.constants import CMS_CONFIG_COLUMN, LMS_CONFIG_COLUMN
from eox_tenant.models import Microsite, Route, TenantConfig
from eox_tenant.receivers_helpers import get_tenant_config_by_domain

Expand Down Expand Up @@ -34,7 +35,9 @@ def setUp(self):
"course_org_filter": ["test5-org", "test1-org"],
"value-test": "Hello-World3",
},
studio_configs={},
studio_configs={
"value-test": "studio",
},
theming_configs={},
meta={},
)
Expand All @@ -44,11 +47,11 @@ def setUp(self):
config=TenantConfig.objects.get(external_key="tenant-key1"),
)

def test_tenant_get_config_by_domain(self):
def test_tenant_get_lms_config_by_domain(self):
"""
Test to get the configuration and external key for a given domain.
"""
configurations, external_key = get_tenant_config_by_domain("domain1")
configurations, external_key = get_tenant_config_by_domain("domain1", LMS_CONFIG_COLUMN)

self.assertEqual(external_key, "tenant-key1")
self.assertDictEqual(
Expand All @@ -59,12 +62,34 @@ def test_tenant_get_config_by_domain(self):
},
)

configurations, external_key = get_tenant_config_by_domain("domain2")
def test_tenant_get_studio_config_by_domain(self):
"""
Test to get the configuration and external key for a given domain.
"""
configurations, external_key = get_tenant_config_by_domain("domain1", CMS_CONFIG_COLUMN)

self.assertEqual(external_key, "tenant-key1")
self.assertDictEqual(
configurations,
{
"value-test": "studio",
},
)

def test_no_tenant_get_config_by_domain(self):
"""
Test to get the configuration and external key for a non-existent domain.
"""
configurations, external_key = get_tenant_config_by_domain("domain2", LMS_CONFIG_COLUMN)

self.assertEqual(external_key, None)
self.assertDictEqual(configurations, {})

configurations, external_key = get_tenant_config_by_domain("first.test.prod.edunext")
def test_microsite_get_config_by_domain(self):
"""
Test to get the configuration and external key for a given domain from Microsite table.
"""
configurations, external_key = get_tenant_config_by_domain("first.test.prod.edunext", LMS_CONFIG_COLUMN)

self.assertEqual(external_key, "test_fake_key")
self.assertDictEqual(
Expand Down
Loading

0 comments on commit 17cf513

Please sign in to comment.