Skip to content

Commit e5ccc99

Browse files
author
Victoria Hall
committed
merge
2 parents 83d83fc + ceac558 commit e5ccc99

File tree

4 files changed

+76
-15
lines changed

4 files changed

+76
-15
lines changed

azure_functions_worker/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
SHARED_MEMORY_DATA_TRANSFER = "SharedMemoryDataTransfer"
1212
FUNCTION_DATA_CACHE = "FunctionDataCache"
1313
HTTP_URI = "HttpUri"
14-
14+
REQUIRES_ROUTE_PARAMETERS = "RequiresRouteParameters"
1515
# When this capability is enabled, logs are not piped back to the
1616
# host from the worker. Logs will directly go to where the user has
1717
# configured them to go. This is to ensure that the logs are not

azure_functions_worker/dispatcher.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
PYTHON_THREADPOOL_THREAD_COUNT_DEFAULT,
4040
PYTHON_THREADPOOL_THREAD_COUNT_MAX_37,
4141
PYTHON_THREADPOOL_THREAD_COUNT_MIN,
42+
REQUIRES_ROUTE_PARAMETERS,
43+
HTTP_URI
4244
)
4345
from .extension import ExtensionManager
4446
from .http_v2 import (
@@ -431,9 +433,9 @@ async def _handle__worker_init_request(self, request):
431433
)
432434

433435
if HttpV2Registry.http_v2_enabled():
434-
capabilities[constants.HTTP_URI] = initialize_http_server(
435-
self._host
436-
)
436+
capabilities[HTTP_URI] = \
437+
initialize_http_server(self._host)
438+
capabilities[REQUIRES_ROUTE_PARAMETERS] = _TRUE
437439

438440
except HttpServerInitError:
439441
raise
@@ -692,8 +694,10 @@ async def _handle__invocation_request(self, request):
692694
invocation_id
693695
)
694696

695-
await sync_http_request(http_request, invoc_request)
696-
args[fi.trigger_metadata.get("param_name")] = http_request
697+
trigger_arg_name = fi.trigger_metadata.get('param_name')
698+
func_http_request = args[trigger_arg_name]
699+
await sync_http_request(http_request, func_http_request)
700+
args[trigger_arg_name] = http_request
697701

698702
fi_context = self._get_context(invoc_request, fi.name, fi.directory)
699703

@@ -859,9 +863,9 @@ async def _handle__function_environment_reload_request(self, request):
859863
)
860864

861865
if HttpV2Registry.http_v2_enabled():
862-
capabilities[constants.HTTP_URI] = initialize_http_server(
863-
self._host
864-
)
866+
capabilities[HTTP_URI] = \
867+
initialize_http_server(self._host)
868+
capabilities[REQUIRES_ROUTE_PARAMETERS] = _TRUE
865869
except HttpServerInitError:
866870
raise
867871
except Exception as ex:

azure_functions_worker/http_v2.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -246,14 +246,11 @@ async def catch_all(request: request_type): # type: ignore
246246
from e
247247

248248

249-
async def sync_http_request(http_request, invoc_request):
249+
async def sync_http_request(http_request, func_http_request):
250250
# Sync http request route params from invoc_request to http_request
251-
route_params = {key: item.string for key, item
252-
in invoc_request.trigger_metadata.items()
253-
if key not in ['Headers', 'Query']}
254251
(HttpV2Registry.ext_base().RequestTrackerMeta
255252
.get_synchronizer()
256-
.sync_route_params(http_request, route_params))
253+
.sync_route_params(http_request, func_http_request.route_params))
257254

258255

259256
class HttpV2Registry:

tests/unittests/test_dispatcher.py

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
PYTHON_THREADPOOL_THREAD_COUNT,
2121
PYTHON_THREADPOOL_THREAD_COUNT_DEFAULT,
2222
PYTHON_THREADPOOL_THREAD_COUNT_MAX_37,
23-
PYTHON_THREADPOOL_THREAD_COUNT_MIN,
23+
PYTHON_THREADPOOL_THREAD_COUNT_MIN, HTTP_URI, REQUIRES_ROUTE_PARAMETERS,
2424
)
2525
from azure_functions_worker.dispatcher import Dispatcher, ContextEnabledTask
2626
from azure_functions_worker.utils import config_manager
@@ -34,6 +34,8 @@
3434
'dispatcher_functions_stein'
3535
FUNCTION_APP_DIRECTORY = UNIT_TESTS_ROOT / 'dispatcher_functions' / \
3636
'dispatcher_functions_stein'
37+
HTTPV2_FUNCTION_APP_DIRECTORY = UNIT_TESTS_ROOT / 'dispatcher_functions' / \
38+
'http_v2' / 'fastapi'
3739

3840

3941
class TestThreadPoolSettingsPython37(testutils.AsyncTestCase):
@@ -778,6 +780,7 @@ def setUp(self):
778780
asyncio.set_event_loop(self.loop)
779781
self.dispatcher = testutils.create_dummy_dispatcher()
780782
sys.path.append(str(FUNCTION_APP_DIRECTORY))
783+
sys.path.append(str(HTTPV2_FUNCTION_APP_DIRECTORY))
781784

782785
def tearDown(self):
783786
self.loop.close()
@@ -1002,6 +1005,63 @@ def test_dispatcher_indexing_in_load_request_with_exception(
10021005
response.function_load_response.result.exception.message,
10031006
"Exception: Mocked Exception")
10041007

1008+
@patch.dict(os.environ, {PYTHON_ENABLE_INIT_INDEXING: 'true'})
1009+
@patch("azure_functions_worker.http_v2.HttpV2Registry.http_v2_enabled",
1010+
return_value=True)
1011+
def test_dispatcher_http_v2_init_request_fail(self, mock_http_v2_enabled):
1012+
request = protos.StreamingMessage(
1013+
worker_init_request=protos.WorkerInitRequest(
1014+
host_version="2.3.4",
1015+
function_app_directory=str(HTTPV2_FUNCTION_APP_DIRECTORY)
1016+
)
1017+
)
1018+
1019+
resp = self.loop.run_until_complete(
1020+
self.dispatcher._handle__worker_init_request(request)
1021+
)
1022+
1023+
mock_http_v2_enabled.assert_called_once()
1024+
self.assertIsNotNone(self.dispatcher._function_metadata_exception)
1025+
1026+
capabilities = resp.worker_init_response.capabilities
1027+
self.assertNotIn(HTTP_URI, capabilities)
1028+
self.assertNotIn(REQUIRES_ROUTE_PARAMETERS, capabilities)
1029+
1030+
# Cleanup
1031+
del sys.modules['function_app']
1032+
1033+
@patch.dict(os.environ, {PYTHON_ENABLE_INIT_INDEXING: 'true'})
1034+
@patch("azure_functions_worker.http_v2.HttpV2Registry.http_v2_enabled",
1035+
return_value=True)
1036+
@patch("azure_functions_worker.dispatcher.initialize_http_server",
1037+
return_value="http://localhost:8080")
1038+
@patch("azure_functions_worker.dispatcher.Dispatcher"
1039+
".load_function_metadata")
1040+
def test_dispatcher_http_v2_init_request_pass(self, mock_http_v2_enabled,
1041+
mock_init_http_server,
1042+
mock_load_func_metadata):
1043+
request = protos.StreamingMessage(
1044+
worker_init_request=protos.WorkerInitRequest(
1045+
host_version="2.3.4",
1046+
function_app_directory=str(HTTPV2_FUNCTION_APP_DIRECTORY)
1047+
)
1048+
)
1049+
1050+
resp = self.loop.run_until_complete(
1051+
self.dispatcher._handle__worker_init_request(request)
1052+
)
1053+
1054+
mock_http_v2_enabled.assert_called_once()
1055+
mock_init_http_server.assert_called_once()
1056+
mock_load_func_metadata.assert_called_once()
1057+
self.assertIsNone(self.dispatcher._function_metadata_exception)
1058+
1059+
capabilities = resp.worker_init_response.capabilities
1060+
self.assertIn(HTTP_URI, capabilities)
1061+
self.assertEqual(capabilities[HTTP_URI], "http://localhost:8080")
1062+
self.assertIn(REQUIRES_ROUTE_PARAMETERS, capabilities)
1063+
self.assertEqual(capabilities[REQUIRES_ROUTE_PARAMETERS], "true")
1064+
10051065

10061066
class TestContextEnabledTask(unittest.TestCase):
10071067
def setUp(self):

0 commit comments

Comments
 (0)