Skip to content

Commit

Permalink
fix(apis/web/resource/view): 修复资源绑定插件未修改但触发更新问题
Browse files Browse the repository at this point in the history
  • Loading branch information
F-cq committed Nov 8, 2024
1 parent 4175924 commit 10ada76
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 15 deletions.
52 changes: 37 additions & 15 deletions src/dashboard/apigateway/apigateway/apis/web/plugin/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from apigateway.core.models import Resource, Stage
from apigateway.utils.django import get_model_dict
from apigateway.utils.responses import OKJsonResponse
from apigateway.utils.yaml import yaml_loads

from .serializers import (
PluginBindingListOutputSLZ,
Expand Down Expand Up @@ -327,6 +328,25 @@ class PluginConfigRetrieveUpdateDestroyApi(

lookup_field = "id"

def _check_if_changed(self, input_data: Dict[str, Any], instance: PluginConfig) -> bool:

try:
input_yaml = yaml_loads(input_data["yaml"])
current_yaml = yaml_loads(instance.yaml)

if input_yaml != current_yaml:
return True
except Exception:
return True

if input_data["name"] != instance.name:
return True

if input_data["type_id"].id != instance.type.id:
return True

return False

def get_queryset(self):
return PluginConfig.objects.prefetch_related("type").filter(gateway=self.request.gateway)

Expand All @@ -339,23 +359,25 @@ def perform_update(self, serializer):
self.validate_scope()
self.validate_code(type_id=serializer.validated_data["type_id"])

data_before = get_model_dict(serializer.instance)
if self._check_if_changed(dict(serializer.validated_data), serializer.instance):

super().perform_update(serializer)
data_before = get_model_dict(serializer.instance)

# if scope_type is stage, should publish
scope_type = self.kwargs["scope_type"]
scope_id = self.kwargs["scope_id"]
self.post_modification(
source=PublishSourceEnum.PLUGIN_UPDATE,
op_type=OpTypeEnum.MODIFY,
scope_type=scope_type,
scope_id=scope_id,
instance_id=serializer.instance.id,
instance_name=serializer.instance.name,
data_before=data_before,
data_after=get_model_dict(serializer.instance),
)
super().perform_update(serializer)

# if scope_type is stage, should publish
scope_type = self.kwargs["scope_type"]
scope_id = self.kwargs["scope_id"]
self.post_modification(
source=PublishSourceEnum.PLUGIN_UPDATE,
op_type=OpTypeEnum.MODIFY,
scope_type=scope_type,
scope_id=scope_id,
instance_id=serializer.instance.id,
instance_name=serializer.instance.name,
data_before=data_before,
data_after=get_model_dict(serializer.instance),
)

@transaction.atomic
def perform_destroy(self, instance):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import pytest
from django.utils.translation import override

from apigateway.apis.web.plugin.views import PluginConfigRetrieveUpdateDestroyApi
from apigateway.utils.yaml import yaml_dumps


Expand Down Expand Up @@ -215,6 +216,56 @@ def test_delete(

assert response.status_code == 204

def test_check_if_changed(
self,
request_view,
fake_gateway,
fake_stage,
fake_plugin_bk_header_rewrite,
fake_plugin_check_changed_binding,
):

yaml = yaml_dumps(
{
"set": [{"key": "foo", "value": "bar"}],
"remove": [{"key": "baz"}],
}
)

view = PluginConfigRetrieveUpdateDestroyApi()

# update yaml
fake_input_data1 = {
"name": fake_plugin_bk_header_rewrite.name,
"type_id": fake_plugin_check_changed_binding[0],
"yaml": '',
}
assert view._check_if_changed(fake_input_data1, fake_plugin_bk_header_rewrite)

# update name
fake_input_data2 = {
"name": "bk-header-rewrite-2",
"type_id": fake_plugin_check_changed_binding[0],
"yaml": yaml,
}
assert view._check_if_changed(fake_input_data2, fake_plugin_bk_header_rewrite)

# update type_id
fake_input_data3 = {
"name": fake_plugin_bk_header_rewrite.name,
"type_id": fake_plugin_check_changed_binding[1],
"yaml": yaml,
}
assert view._check_if_changed(fake_input_data3, fake_plugin_bk_header_rewrite)

# no update
fake_input_data4 = {
"name": fake_plugin_bk_header_rewrite.name,
"type_id": fake_plugin_check_changed_binding[0],
"yaml": yaml,
}
assert not view._check_if_changed(fake_input_data4, fake_plugin_bk_header_rewrite)


class TestPluginFormRetrieveApi:
@pytest.mark.parametrize(
Expand Down
36 changes: 36 additions & 0 deletions src/dashboard/apigateway/apigateway/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,42 @@ def fake_plugin_resource_bk_cors_binding(fake_plugin_bk_cors, fake_resource):
)


@pytest.fixture()
def fake_plugin_check_changed(fake_plugin_type_bk_header_rewrite, fake_gateway):
return G(
PluginConfig,
gateway=fake_gateway,
name="bk-test",
type=fake_plugin_type_bk_header_rewrite,
yaml=yaml_dumps(
{
"set": [{"key": "foo", "value": "bar"}],
"remove": [{"key": "baz"}],
}
),
)


@pytest.fixture()
def fake_plugin_check_changed_binding(fake_plugin_bk_header_rewrite, fake_plugin_check_changed, fake_stage):
bangding1 = G(
PluginBinding,
gateway=fake_plugin_bk_header_rewrite.gateway,
config=fake_plugin_bk_header_rewrite,
scope_type=PluginBindingScopeEnum.STAGE.value,
scope_id=fake_stage.pk,
)

bangding2 = G(
PluginBinding,
gateway=fake_plugin_check_changed.gateway,
config=fake_plugin_check_changed,
scope_type=PluginBindingScopeEnum.STAGE.value,
scope_id=fake_stage.pk,
)
return [bangding1, bangding2]


@pytest.fixture()
def fake_rsa_private_key():
return """-----BEGIN RSA PRIVATE KEY-----
Expand Down

0 comments on commit 10ada76

Please sign in to comment.