From c2f4f99fc4af1306a0186d4d9221e6dd3052f0f5 Mon Sep 17 00:00:00 2001 From: Ali-Salman29 Date: Fri, 9 Aug 2024 10:29:14 +0200 Subject: [PATCH] feat: Allow discussion client to use Forum V2 APIs Added a setting FORUM_V2_REGEXS. It contains regex patterns for matching ForumV2 app URLs. The application will use the ForumV2 APIs if a ForumV1 URL matches any of these regex patterns. This setting is intended to help route traffic to the appropriate version of the Forum API based on the structure of the URL. --- .../comment_client/settings.py | 44 +++++++++++++++++-- .../comment_client/utils.py | 38 +++++++++++++--- 2 files changed, 72 insertions(+), 10 deletions(-) diff --git a/openedx/core/djangoapps/django_comment_common/comment_client/settings.py b/openedx/core/djangoapps/django_comment_common/comment_client/settings.py index 4e93ceec354d..2f4d5fa12993 100644 --- a/openedx/core/djangoapps/django_comment_common/comment_client/settings.py +++ b/openedx/core/djangoapps/django_comment_common/comment_client/settings.py @@ -4,14 +4,50 @@ if hasattr(settings, "COMMENTS_SERVICE_URL"): SERVICE_HOST = settings.COMMENTS_SERVICE_URL else: - SERVICE_HOST = 'http://localhost:4567' + SERVICE_HOST = "http://localhost:4567" -PREFIX = SERVICE_HOST + '/api/v1' +PREFIX = SERVICE_HOST + "/api/v1" # V2 url support for differential logging if hasattr(settings, "COMMENTS_SERVICE_V2_URL"): SERVICE_HOST_V2 = settings.COMMENTS_SERVICE_V2_URL else: - SERVICE_HOST_V2 = 'http://localhost:8000' + SERVICE_HOST_V2 = "http://localhost:8000" -PREFIX_V2 = SERVICE_HOST_V2 + '/forum/forum_proxy/api/v1' +PREFIX_V2 = SERVICE_HOST_V2 + "/forum/api/v2" +PROXY_PREFIX_V2 = SERVICE_HOST_V2 + "/forum/forum_proxy/api/v1" + +""" +This setting is intended to help route traffic to the appropriate version of the Forum API based on the structure of the URL. + +FORUM_V2_REGEXS contains regex patterns for matching ForumV2 app URLs. +The application will use the ForumV2 APIs if a ForumV1 URL matches any of these regex patterns. + +The dictionary keys represent the HTTP methods and the values are lists of +regex patternsthat correspond to the endpoints for each method. + +Example: +FORUM_V2_REGEXS = { + "put": [ + "^/threads/([a-zA-Z0-9]+)/votes$", + # Example regex for PUT requests to update votes for a specific thread. + ], + "delete": [ + "^/threads/([a-zA-Z0-9]+)/votes$", + # Example regex for DELETE requests to remove votes for a specific thread. + ], + "post": [ + # Add regex patterns for POST requests here. + ], + "get": [ + # Add regex patterns for GET requests here. + ], +} +""" + +FORUM_V2_REGEXS = { + "put": [], + "delete": [], + "post": [], + "get": [], +} diff --git a/openedx/core/djangoapps/django_comment_common/comment_client/utils.py b/openedx/core/djangoapps/django_comment_common/comment_client/utils.py index 92a647bdc15c..957fa88a4a7e 100644 --- a/openedx/core/djangoapps/django_comment_common/comment_client/utils.py +++ b/openedx/core/djangoapps/django_comment_common/comment_client/utils.py @@ -1,14 +1,14 @@ # pylint: disable=missing-docstring,unused-argument,broad-except """" Common utilities for comment client wrapper """ - +import re import logging from uuid import uuid4 import requests from django.utils.translation import get_language -from .settings import PREFIX, PREFIX_V2, SERVICE_HOST as COMMENTS_SERVICE +from .settings import PREFIX, PREFIX_V2, PROXY_PREFIX_V2, FORUM_V2_REGEXS, SERVICE_HOST as COMMENTS_SERVICE log = logging.getLogger(__name__) @@ -33,6 +33,15 @@ def extract(dic, keys): def _get_forum_v2_url(url): return url.replace(PREFIX, PREFIX_V2) +def _get_forum_proxy_v2_url(url): + return url.replace(PREFIX, PROXY_PREFIX_V2) + +def should_use_forum_v2_urls(method, url): + path = url.replace(PREFIX, '') + for pattern in FORUM_V2_REGEXS.get(method, []): + if re.match(pattern, path): + return True + return False def perform_request(method, url, data_or_params=None, raw=False, metric_action=None, metric_tags=None, paged_results=False): @@ -66,6 +75,11 @@ def perform_request(method, url, data_or_params=None, raw=False, data = None params = data_or_params.copy() params.update(request_id_dict) + + forum_v1_url = url + if should_use_forum_v2_urls(method, url): + url = _get_forum_v2_url(url) + response = requests.request( method, url, @@ -76,7 +90,19 @@ def perform_request(method, url, data_or_params=None, raw=False, ) if method == "get": - forum_v2_url = _get_forum_v2_url(url) + forum_v2_url = _get_forum_proxy_v2_url(url) + if url != forum_v1_url: + response_v1 = requests.request( + method, + forum_v1_url, + data=data, + params=params, + headers=headers, + timeout=config.connection_timeout + ) + else: + response_v1 = response + response_v2 = requests.request( method, forum_v2_url, @@ -85,11 +111,11 @@ def perform_request(method, url, data_or_params=None, raw=False, headers=headers, timeout=config.connection_timeout, ) - log.info(f"requested forum v1 url: {url}") + log.info(f"requested forum v1 url: {forum_v1_url}") log.info(f"requested forum v2 url: {forum_v2_url}") - if response_v2.json() != response.json(): + if response_v2.json() != response_v1.json(): log.error( - f"Forum v2 difference, for endpoint {url} with params={params}. \ + f"Forum v2 difference, for endpoint {forum_v1_url} with params={params}. \ Expected: {response.json()}. Got: {response_v2.json()}." )