Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat dashboard fix resource version #267

Merged
6 changes: 6 additions & 0 deletions src/dashboard/apigateway/apigateway/account/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@
from django.urls import path

from . import views
from ..apis.web.monitor.views import AlarmRecordSummaryListApi

urlpatterns = [
path("userinfo/", views.UserAPIView.as_view(), name="accounts.userinfo"),
path(
"gateways/monitors/alarm/records/summary/",
AlarmRecordSummaryListApi.as_view(),
name="accounts.monitors.alarm_records.summary",
),
Han-Ya-Jun marked this conversation as resolved.
Show resolved Hide resolved
]
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

from apigateway.biz.constants import SEMVER_PATTERN
from apigateway.biz.stage import StageHandler
from apigateway.biz.validators import ResourceVersionValidator
from apigateway.common.fields import CurrentGatewayDefault
from apigateway.core.models import ResourceVersion

Expand Down Expand Up @@ -65,6 +66,18 @@ def _get_resource_version_id(self, gateway, version: Optional[str], resource_ver
raise serializers.ValidationError({"version": "请指定待发布的版本"})


class ResourceVersionCreateV1InputSLZ(serializers.Serializer):
gateway = serializers.HiddenField(default=CurrentGatewayDefault())
version = serializers.RegexField(SEMVER_PATTERN, max_length=64, required=True)
title = serializers.CharField(required=False)
comment = serializers.CharField(required=False)

def validate(self, data):
validator = ResourceVersionValidator()
validator(data)
return data
Han-Ya-Jun marked this conversation as resolved.
Show resolved Hide resolved


class ResourceVersionQueryV1InputSLZ(serializers.Serializer):
version = serializers.CharField(required=False)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
from drf_yasg.utils import swagger_auto_schema
from rest_framework import generics, status

from apigateway.apis.web.resource_version.serializers import ResourceVersionInfoSLZ
from apigateway.apps.support.models import ResourceDoc, ResourceDocVersion
from apigateway.biz.releaser import ReleaseError, Releaser
from apigateway.biz.resource_version import ResourceVersionHandler
Expand All @@ -30,7 +29,12 @@
from apigateway.utils.access_token import get_user_access_token_from_request
from apigateway.utils.responses import V1FailJsonResponse, V1OKJsonResponse

from .serializers import ReleaseV1InputSLZ, ResourceVersionListV1OutputSLZ, ResourceVersionQueryV1InputSLZ
from .serializers import (
ReleaseV1InputSLZ,
ResourceVersionCreateV1InputSLZ,
ResourceVersionListV1OutputSLZ,
ResourceVersionQueryV1InputSLZ,
)


@method_decorator(
Expand All @@ -43,12 +47,13 @@
@method_decorator(
name="post",
decorator=swagger_auto_schema(
request_body=ResourceVersionInfoSLZ,
request_body=ResourceVersionCreateV1InputSLZ,
tags=["OpenAPI.ResourceVersion"],
),
)
class ResourceVersionListCreateApi(generics.ListCreateAPIView):
permission_classes = [GatewayRelatedAppPermission]
serializer_class = ResourceVersionCreateV1InputSLZ

def list(self, request, *args, **kwargs):
slz = ResourceVersionQueryV1InputSLZ(data=request.query_params)
Expand All @@ -64,9 +69,10 @@ def list(self, request, *args, **kwargs):

@transaction.atomic
def create(self, request, gateway_name: str, *args, **kwargs):
# manager = ResourceVersionManager()
# instance = manager.create_resource_version(request.gateway, request.data, request.user.username)
instance = ResourceVersionHandler.create_resource_version(request.gateway, request.data, request.user.username)
slz = self.get_serializer(data=request.data, context={"request": request})
slz.is_valid(raise_exception=True)
data = slz.validated_data
instance = ResourceVersionHandler.create_resource_version(request.gateway, data, request.user.username)

# 创建文档版本
if ResourceDoc.objects.filter(gateway=request.gateway).exists():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from apigateway.apps.support.api_sdk import exceptions
from apigateway.apps.support.api_sdk.helper import SDKHelper
from apigateway.apps.support.api_sdk.models import SDKFactory
from apigateway.apps.support.models import APISDK
from apigateway.apps.support.models import GatewaySDK
from apigateway.common.contexts import GatewayAuthContext
from apigateway.common.error_codes import error_codes
from apigateway.common.permissions import GatewayRelatedAppPermission
Expand All @@ -44,15 +44,15 @@ class APISDKV1ViewSet(viewsets.ModelViewSet):
api_permission_exempt = True

def get_queryset(self):
return APISDK.objects.all()
return GatewaySDK.objects.all()

def list_latest_sdks(self, request, *args, **kwargs):
slz = serializers.APISDKQueryV1SLZ(data=request.query_params)
slz.is_valid(raise_exception=True)

data = slz.validated_data

queryset = APISDK.objects.filter_recommended_sdks(
queryset = GatewaySDK.objects.filter_recommended_sdks(
data["language"],
gateway_id=data.get("api_id"),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from rest_framework import generics, status
from tencent_apigateway_common.django.translation import get_current_language_code

from apigateway.apps.support.models import APISDK
from apigateway.apps.support.models import GatewaySDK
from apigateway.biz.sdk.gateway_sdk import GatewaySDKHandler
from apigateway.biz.sdk.models import SDKDocContext
from apigateway.common.permissions import GatewayDisplayablePermission
Expand Down Expand Up @@ -73,7 +73,7 @@ def retrieve(self, request, gateway_name: str, *args, **kwargs):
slz.is_valid(raise_exception=True)
programming_language = slz.validated_data["language"]

sdk = APISDK.objects.filter(
sdk = GatewaySDK.objects.filter(
gateway_id=request.gateway.id,
is_recommended=True,
language=programming_language,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from rest_framework import generics, status
from tencent_apigateway_common.django.translation import get_current_language_code

from apigateway.apps.support.models import APISDK
from apigateway.apps.support.models import GatewaySDK
from apigateway.biz.sdk.models import DummySDKDocContext
from apigateway.core.constants import GatewayStatusEnum
from apigateway.core.models import Release, ResourceVersion
Expand All @@ -45,7 +45,7 @@ def list(self, request, *args, **kwargs):
slz.is_valid(raise_exception=True)

sdks = list(
APISDK.objects.filter(
GatewaySDK.objects.filter(
gateway__is_public=True,
gateway__status=GatewayStatusEnum.ACTIVE.value,
is_recommended=True,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def create(self, request, *args, **kwargs):
request.user.username,
)
except LockTimeout as err:
logger.exception("release failed.")
logger.exception("retrieve lock timeout")
return FailJsonResponse(status=status.HTTP_500_INTERNAL_SERVER_ERROR, code="UNKNOWN", message=str(err))
except ReleaseError as err:
logger.exception("release failed.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,125 +16,55 @@
# We undertake not to change the open source license (MIT license) applicable
# to the current version of the project delivered to anyone in the future.
#

from django.utils.translation import gettext as _
from rest_framework import serializers

from apigateway.biz.constants import SEMVER_PATTERN
from apigateway.biz.resource_version import ResourceVersionHandler
from apigateway.biz.validators import ResourceVersionValidator
from apigateway.common.fields import CurrentGatewayDefault
from apigateway.core.models import Gateway, Resource, ResourceVersion
from apigateway.utils import time as time_utils
from apigateway.core.models import ResourceVersion


class ResourceVersionInfoSLZ(serializers.ModelSerializer):
class ResourceVersionCreateInputSLZ(serializers.Serializer):
gateway = serializers.HiddenField(default=CurrentGatewayDefault())
# TODO: 待开源版中,同步资源版本的服务全部切换为 version 后,此字段才能指定为必填: required=True
version = serializers.RegexField(SEMVER_PATTERN, max_length=64, required=False)

class Meta:
model = ResourceVersion
fields = [
"gateway",
"id",
"version",
"name",
"title",
"comment",
"data",
"created_by",
"created_time",
]
read_only_fields = ["id", "name", "data", "created_by", "created_time"]
lookup_field = "id"
version = serializers.RegexField(SEMVER_PATTERN, max_length=64, required=True)
comment = serializers.CharField(allow_blank=True, required=False)
Han-Ya-Jun marked this conversation as resolved.
Show resolved Hide resolved

def validate(self, data):
self._validate_resource_count(data["gateway"])
self._validate_version_unique(gateway=data["gateway"], version=data.get("version", ""))
validator = ResourceVersionValidator()
Han-Ya-Jun marked this conversation as resolved.
Show resolved Hide resolved
validator(data)
return data

def _validate_version_unique(self, gateway: Gateway, version: str):
# TODO: 临时跳过 version 校验,待提供 version 后,此部分删除
if not version:
return

# ResourceVersion 中数据量较大,因此,不使用 UniqueTogetherValidator
queryset = ResourceVersion.objects.filter(gateway=gateway, version=version)
if self.instance is not None:
queryset = queryset.exclude(pk=self.instance.pk)

if queryset.exists():
raise serializers.ValidationError(_("版本 {version} 已存在。").format(version=version))

def _validate_resource_count(self, gateway):
"""
校验网关下资源数量,网关下资源数量为0时,不允许创建网关版本
"""
if not Resource.objects.filter(gateway_id=gateway.id).exists():
raise serializers.ValidationError(_("请先创建资源,然后再生成版本。"))

def to_representation(self, instance):
result = super().to_representation(instance)
result["data"] = instance.data_display

# TODO: 用 name 数据初始化 version 数据后,此部分可删除
result["version"] = instance.version or instance.name

return result

def create(self, validated_data):
gateway = validated_data["gateway"]
now = time_utils.now_datetime()

# created_time:与版本名中时间保持一致,方便SDK使用此时间作为版本号
name = ResourceVersionHandler.generate_version_name(gateway.name, now)
validated_data.update(
{
"name": name,
# TODO: 待 version 改为必填后,下面的 version 赋值去掉
"version": validated_data.get("version") or name,
"created_time": now,
}
)
class ResourceVersionRetrieveOutputSLZ(serializers.Serializer):
id = serializers.IntegerField()
version = serializers.CharField()
comment = serializers.CharField()
data = serializers.SerializerMethodField()
created_time = serializers.DateTimeField()
created_by = serializers.CharField()

return super().create(validated_data)
def get_data(self, obj: ResourceVersion):
return obj.data_display


class ResourceVersionListOutputSLZ(serializers.ModelSerializer):
class ResourceVersionListOutputSLZ(serializers.Serializer):
id = serializers.IntegerField()
released_stages = serializers.SerializerMethodField()
has_sdk = serializers.SerializerMethodField()
sdk_count = serializers.SerializerMethodField()
resource_version_display = serializers.SerializerMethodField()
version = serializers.SerializerMethodField()

class Meta:
model = ResourceVersion
fields = (
"id",
"version",
"name",
"title",
"comment",
"resource_version_display",
"created_time",
"released_stages",
"has_sdk",
"sdk_count",
)
read_only_fields = fields
lookup_field = "id"
comment = serializers.CharField()
created_time = serializers.DateTimeField()

def get_released_stages(self, obj):
return self.context["released_stages"].get(obj["id"], [])

def get_has_sdk(self, obj):
return obj["id"] in self.context["resource_version_ids_has_sdk"]

def get_sdk_count(self, obj):
return self.context["resource_version_ids_sdk_count"].get(obj["id"], 0)

def get_version(self, obj):
return obj.get("version") or obj.get("name", "")
return obj.get("version")

def get_resource_version_display(self, obj):
return ResourceVersionHandler.get_resource_version_display(obj)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
name="gateway.resource_version.retrieve",
),
path(
"need_new_version/",
"need-new-version/",
ResourceVersionNeedNewVersionRetrieveApi.as_view(),
name="gateway.resource_version.need_new_version",
),
Expand Down
Loading