Skip to content

Commit 4363743

Browse files
committed
feat(vefaas): update enable affinity plug
1 parent e41d184 commit 4363743

4 files changed

Lines changed: 111 additions & 14 deletions

File tree

veadk/cloud/cloud_agent_engine.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ def deploy(
221221
identity_user_pool_name: str = "",
222222
identity_client_name: str = "",
223223
local_test: bool = False,
224+
enable_session_affinity: bool = False,
224225
) -> CloudApp:
225226
"""Deploys a local agent project to Volcengine FaaS, creating necessary resources.
226227
@@ -287,15 +288,20 @@ def deploy(
287288
identity_client_name = f"{application_name}-id-cli-{formatted_timestamp()}"
288289

289290
try:
290-
vefaas_application_url, app_id, function_id = self._vefaas_service.deploy(
291-
path=path,
292-
name=application_name,
293-
gateway_name=gateway_name,
294-
gateway_service_name=gateway_service_name,
295-
gateway_upstream_name=gateway_upstream_name,
296-
enable_key_auth=enable_key_auth,
291+
vefaas_application_url, app_id, function_id, affinity_binding_id = (
292+
self._vefaas_service.deploy(
293+
path=path,
294+
name=application_name,
295+
gateway_name=gateway_name,
296+
gateway_service_name=gateway_service_name,
297+
gateway_upstream_name=gateway_upstream_name,
298+
enable_key_auth=enable_key_auth,
299+
enable_session_affinity=enable_session_affinity,
300+
)
297301
)
298-
_ = function_id # for future use
302+
_ = function_id
303+
if affinity_binding_id:
304+
logger.info(f"Session affinity plugin bindng_id: {affinity_binding_id}")
299305

300306
veapig_gateway_id, _, veapig_route_id = (
301307
self._vefaas_service.get_application_route(app_id=app_id)
@@ -393,6 +399,7 @@ def deploy(
393399
vefaas_application_name=application_name,
394400
vefaas_endpoint=vefaas_application_url,
395401
vefaas_application_id=app_id,
402+
affinity_binding_id=affinity_binding_id,
396403
)
397404
except Exception as e:
398405
raise ValueError(
@@ -483,3 +490,8 @@ def update_function_code(
483490
raise ValueError(
484491
f"Failed to update agent project on Volcengine FaaS platform. Error: {e}"
485492
)
493+
494+
def disable_session_affinity(self, binding_id: str) -> None:
495+
"""Disable session affinity by deleting plugin binding."""
496+
self._vefaas_service.disable_session_affinity(binding_id)
497+
logger.info(f"Session affinity plugin binding {binding_id} deleted.")

veadk/cloud/cloud_app.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ def __init__(
6262
vefaas_endpoint: str = "",
6363
vefaas_application_id: str = "",
6464
use_agent_card: bool = False,
65+
affinity_binding_id: str | None = None,
6566
):
6667
"""Initializes the CloudApp with VeFaaS application details.
6768
@@ -92,6 +93,7 @@ def __init__(
9293
self.vefaas_application_id = vefaas_application_id
9394
self.vefaas_application_name = vefaas_application_name
9495
self.use_agent_card = use_agent_card
96+
self.affinity_binding_id = affinity_binding_id
9597

9698
# vefaas must be set one of three
9799
if (

veadk/integrations/ve_apig/ve_apig.py

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# limitations under the License.
1414

1515
import time
16-
16+
import json
1717
import volcenginesdkcore
1818
from volcenginesdkapig import APIGApi
1919
from volcenginesdkapig20221112 import APIG20221112Api, UpstreamListForCreateRouteInput
@@ -347,3 +347,52 @@ def create(
347347
"upstream_id": upstream_id,
348348
"route_ids": route_ids,
349349
}
350+
351+
def create_session_affinity_plugin(self, gateway_id: str) -> str:
352+
"""Create session affinity plugin on gateway. Returns plugin_id."""
353+
response = ve_request(
354+
request_body={
355+
"PluginName": "wasm-session-affinity-pro",
356+
"PluginConfig": "",
357+
"GatewayId": gateway_id,
358+
"Enable": True,
359+
},
360+
action="CreatePlugin",
361+
ak=self.ak,
362+
sk=self.sk,
363+
service="apig",
364+
version="2022-11-12",
365+
region=self.region,
366+
host="open.volcengineapi.com",
367+
)
368+
return response["Result"]["PluginID"]
369+
370+
def bind_session_affinity_plugin(self, service_id: str) -> str:
371+
"""Bind session affinity plugin to service. Returns binding_id."""
372+
plugin_config = json.dumps(
373+
{
374+
"Position": "Header",
375+
"DownstreamSessionKey": "x-session-id-veadk",
376+
"UpstreamHeaders": [],
377+
"FailureModeAllow": False,
378+
}
379+
)
380+
return self.create_plugin_binding(
381+
scope="SERVICE",
382+
target=service_id,
383+
plugin_name="wasm-session-affinity-pro",
384+
plugin_config=plugin_config,
385+
)
386+
387+
def delete_plugin_binding(self, binding_id: str) -> None:
388+
"""Delete a plugin binding by id."""
389+
ve_request(
390+
request_body={"Id": binding_id},
391+
action="DeletePluginBinding",
392+
ak=self.ak,
393+
sk=self.sk,
394+
service="apig",
395+
version="2021-03-03",
396+
region=self.region,
397+
host="open.volcengineapi.com",
398+
)

veadk/integrations/ve_faas/ve_faas.py

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,8 @@ def deploy(
444444
gateway_service_name: str = "",
445445
gateway_upstream_name: str = "",
446446
enable_key_auth: bool = False,
447-
) -> tuple[str, str, str]:
447+
enable_session_affinity: bool = False,
448+
) -> tuple[str, str, str, str | None]:
448449
"""Deploy an agent project to VeFaaS service.
449450
450451
Args:
@@ -456,7 +457,7 @@ def deploy(
456457
enable_key_auth (bool, optional): Enable key auth. Defaults to False.
457458
458459
Returns:
459-
tuple[str, str, str]: (url, app_id, function_id)
460+
tuple[str, str, str, str | None]: (url, app_id, function_id, affinity_binding_id)
460461
"""
461462
# Naming check
462463
if "_" in name:
@@ -508,7 +509,11 @@ def deploy(
508509

509510
logger.info(f"VeFaaS application {name} with ID {app_id} deployed on {url}.")
510511

511-
return url, app_id, function_id
512+
# Enable session affinity plugin
513+
affinity_binding_id = None
514+
if enable_session_affinity:
515+
affinity_binding_id = self._enable_session_affinity(app_id)
516+
return url, app_id, function_id, affinity_binding_id
512517

513518
def _create_image_function(self, function_name: str, image: str):
514519
"""Create function using container image instead of code upload."""
@@ -678,7 +683,8 @@ def deploy_image(
678683
gateway_name: str = "",
679684
gateway_service_name: str = "",
680685
gateway_upstream_name: str = "",
681-
) -> tuple[str, str, str]:
686+
enable_session_affinity: bool = False,
687+
) -> tuple[str, str, str, str | None]:
682688
"""Deploy application using container image.
683689
684690
Args:
@@ -767,7 +773,11 @@ def deploy_image(
767773

768774
logger.info(f"VeFaaS application {name} with ID {app_id} deployed on {url}.")
769775

770-
return url, app_id, function_id
776+
# Enable session affinity plugin
777+
affinity_binding_id = None
778+
if enable_session_affinity:
779+
affinity_binding_id = self._enable_session_affinity(app_id)
780+
return url, app_id, function_id, affinity_binding_id
771781

772782
def _get_application_logs(self, app_id: str) -> list[str]:
773783
response = _ = ve_request(
@@ -786,3 +796,27 @@ def _get_application_logs(self, app_id: str) -> list[str]:
786796
return logs
787797
except Exception as _:
788798
raise ValueError(f"Get application log failed. Response: {response}")
799+
800+
def _enable_session_affinity(self, app_id: str) -> str | None:
801+
"""Enable session affinity for application. Returns binding_id."""
802+
route_info = self.get_application_route(app_id=app_id)
803+
if not route_info:
804+
logger.warning(f"Cannot get route info for app {app_id}, skip affinity")
805+
return None
806+
gateway_id, service_id, _ = route_info
807+
# Create plugin on gateway (ignore if already exists)
808+
try:
809+
self.apig_client.create_session_affinity_plugin(gateway_id)
810+
except Exception:
811+
logger.warning(
812+
f"Create session affinity plugin failed. Gateway ID: {gateway_id}"
813+
)
814+
# Bind plugin to service
815+
binding_id = self.apig_client.bind_session_affinity_plugin(service_id)
816+
logger.info(f"Session affinity enabled, binding_id: {binding_id}")
817+
return binding_id
818+
819+
def disable_session_affinity(self, binding_id: str) -> None:
820+
"""Disable session affinity by deleting plugin binding."""
821+
self.apig_client.delete_plugin_binding(binding_id)
822+
logger.info(f"Session affinity disabled, binding_id: {binding_id}")

0 commit comments

Comments
 (0)