diff --git a/python_package/_321CQU/service.py b/python_package/_321CQU/service.py index 057942e..b2595fe 100644 --- a/python_package/_321CQU/service.py +++ b/python_package/_321CQU/service.py @@ -1,11 +1,6 @@ from enum import Enum from ._mock import MockApnStub -from micro_services_protobuf.notification_center import service_pb2_grpc as notification_grpc -from micro_services_protobuf.mycqu_service import mycqu_service_pb2_grpc as mycqu_grpc -from micro_services_protobuf.edu_admin_center import eac_service_pb2_grpc as eac_grpc -from micro_services_protobuf.course_score_query import service_pb2_grpc as csq_grpc -from micro_services_protobuf.control_center import control_center_service_pb2_grpc as cc_grpc class ServiceEnum(str, Enum): @@ -24,29 +19,6 @@ class ServiceEnum(str, Enum): CourseScoreQuery = 'course_score_query' - @property - def service_name(self) -> str: - if self == ServiceEnum.WechatManager: - return 'wechat_manager' - elif self == ServiceEnum.ApnsService: - return 'notification_center' - elif self == ServiceEnum.WechatService: - return 'notification_center' - elif self == ServiceEnum.NotificationService: - return 'notification_center' - elif self == ServiceEnum.ImportantInfoService: - return 'important_info' - elif self == ServiceEnum.MycquService: - return 'mycqu' - elif self == ServiceEnum.CardService: - return 'mycqu' - elif self == ServiceEnum.LibraryService: - return 'mycqu' - elif self == ServiceEnum.EduAdminCenter: - return 'edu_admin_center' - elif self == ServiceEnum.CourseScoreQuery: - return 'course_score_query' - @property def is_http_service(self): if self == ServiceEnum.WechatManager: @@ -54,28 +26,6 @@ def is_http_service(self): return False - def _get_stub_class(self): - if self == ServiceEnum.ApnsService: - return notification_grpc.ApnsStub - elif self == ServiceEnum.WechatService: - return notification_grpc.WechatStub - elif self == ServiceEnum.NotificationService: - return notification_grpc.NotificationStub - elif self == ServiceEnum.ImportantInfoService: - return cc_grpc.ImportantInfoServiceStub - elif self == ServiceEnum.MycquService: - return mycqu_grpc.MycquFetcherStub - elif self == ServiceEnum.CardService: - return mycqu_grpc.CardFetcherStub - elif self == ServiceEnum.LibraryService: - return mycqu_grpc.LibraryFetcherStub - elif self == ServiceEnum.EduAdminCenter: - return eac_grpc.EduAdminCenterStub - elif self == ServiceEnum.CourseScoreQuery: - return csq_grpc.CourseScoreQueryStub - else: - raise RuntimeError("未提供对应服务Stub") - def _get_mock_stub_class(self): if self == ServiceEnum.ApnsService: return MockApnStub diff --git a/python_package/_321CQU/service_handler.py b/python_package/_321CQU/service_handler.py new file mode 100644 index 0000000..16ea094 --- /dev/null +++ b/python_package/_321CQU/service_handler.py @@ -0,0 +1,186 @@ +from python_package._321CQU.service import ServiceEnum +from abc import ABC, abstractmethod +from micro_services_protobuf.notification_center import service_pb2_grpc as notification_grpc +from micro_services_protobuf.mycqu_service import mycqu_service_pb2_grpc as mycqu_grpc +from micro_services_protobuf.edu_admin_center import eac_service_pb2_grpc as eac_grpc +from micro_services_protobuf.course_score_query import service_pb2_grpc as csq_grpc +from micro_services_protobuf.control_center import control_center_service_pb2_grpc as cc_grpc + + +class ServiceHandler(ABC): + """ + 服务处理器抽象类 + """ + + @abstractmethod + def support(self, name: ServiceEnum) -> bool: + """ + 判断是否支持该服务 + @param name: 服务名枚举 + """ + pass + + @abstractmethod + @property + def get_service_name(self) -> str: + """ + 获取服务名 + """ + pass + + @abstractmethod + def get_stub_class(self): + """ + 获取stub类 + """ + pass + + +class WechatManagerHandler(ServiceHandler): + """ + 微信管理器服务处理器 + """ + + def support(self, name: ServiceEnum) -> bool: + return name == ServiceEnum.WechatManager + + def get_service_name(self) -> str: + return 'wechat_manager' + + def get_stub_class(self): + pass + + +class ApnsServiceHandler(ServiceHandler): + """ + Apns服务处理器 + """ + + def support(self, name: ServiceEnum) -> bool: + return name == ServiceEnum.ApnsService + + def get_service_name(self) -> str: + return 'notification_center' + + def get_stub_class(self): + return notification_grpc.ApnsStub + + +class WechatServiceHandler(ServiceHandler): + """ + 微信服务处理器 + """ + + def support(self, name: ServiceEnum) -> bool: + return name == ServiceEnum.WechatService + + def get_service_name(self) -> str: + return 'notification_center' + + def get_stub_class(self): + return notification_grpc.WechatStub + + +class NotificationServiceHandler(ServiceHandler): + """ + 通知服务处理器 + """ + + def support(self, name: ServiceEnum) -> bool: + return name == ServiceEnum.NotificationService + + def get_service_name(self) -> str: + return 'notification_center' + + def get_stub_class(self): + return notification_grpc.NotificationStub + + +class ImportantInfoServiceHandler(ServiceHandler): + """ + 重要信息服务处理器 + """ + + def support(self, name: ServiceEnum) -> bool: + return name == ServiceEnum.ImportantInfoService + + def get_service_name(self) -> str: + return 'important_info' + + def get_stub_class(self): + return cc_grpc.ImportantInfoServiceStub + + +class MycquServiceHandler(ServiceHandler): + """ + Mycqu服务处理器 + """ + + def support(self, name: ServiceEnum) -> bool: + return name == ServiceEnum.MycquService + + def get_service_name(self) -> str: + return 'mycqu' + + def get_stub_class(self): + return mycqu_grpc.MycquFetcherStub + + +class CardServiceHandler(ServiceHandler): + """ + 一卡通服务处理器 + """ + + def support(self, name: ServiceEnum) -> bool: + return name == ServiceEnum.CardService + + def get_service_name(self) -> str: + return 'mycqu' + + def get_stub_class(self): + return mycqu_grpc.CardFetcherStub + + +class LibraryServiceHandler(ServiceHandler): + """ + 图书馆服务处理器 + """ + + def support(self, name: ServiceEnum) -> bool: + return name == ServiceEnum.LibraryService + + def get_service_name(self) -> str: + return 'mycqu' + + def get_stub_class(self): + return mycqu_grpc.LibraryFetcherStub + + +class EduAdminCenterHandler(ServiceHandler): + """ + 教务中心服务处理器 + """ + + def support(self, name: ServiceEnum) -> bool: + return name == ServiceEnum.EduAdminCenter + + def get_service_name(self) -> str: + return 'edu_admin_center' + + def get_stub_class(self): + return eac_grpc.EduAdminCenterStub + + +class CourseScoreQueryHandler(ServiceHandler): + """ + 课程成绩查询服务处理器 + """ + + def support(self, name: ServiceEnum) -> bool: + return name == ServiceEnum.CourseScoreQuery + + def get_service_name(self) -> str: + return 'course_score_query' + + def get_stub_class(self): + return csq_grpc.CourseScoreQueryStub diff --git a/python_package/_321CQU/tools/gRPCManager.py b/python_package/_321CQU/tools/gRPCManager.py index b27229a..2a85c8a 100644 --- a/python_package/_321CQU/tools/gRPCManager.py +++ b/python_package/_321CQU/tools/gRPCManager.py @@ -9,10 +9,13 @@ __all__ = ['gRPCManager', 'MockGRPCManager'] from ..service import ServiceEnum +from ..service_handler import ServiceHandler class gRPCManager(metaclass=Singleton): def __init__(self, handler: ConfigHandler = _CONFIG_HANDLER): + # 初始化时创建每个ServiceHandler子类的实例 + self.service_instances = [cls() for cls in ServiceHandler.__subclasses__()] all_options = handler.get_options('ServiceSetting') service_hosts = list(filter(lambda x: x.endswith('_service_host'), all_options)) @@ -31,22 +34,26 @@ def __init__(self, handler: ConfigHandler = _CONFIG_HANDLER): }) def get_service_config(self, service: ServiceEnum) -> Tuple[str, str]: - return (self._service_host[service.service_name + "_service_host"], - self._service_ports[service.service_name + "_service_port"]) + for instance in self.service_instances: + if instance.support(name=service): + return (self._service_host[instance.get_service_name + "_service_host"], + self._service_ports[instance.get_service_name + "_service_port"]) @asynccontextmanager async def get_stub(self, service: ServiceEnum): if service.is_http_service: raise RuntimeError("该服务不是gRPC服务") - - target = service._get_stub_class() - - if target is not None: - host = self._service_host[service.service_name + "_service_host"] - port = self._service_ports[service.service_name + "_service_port"] - target_url = host + ":" + port - async with insecure_channel(target_url) as channel: - yield target(channel) + for instance in self.service_instances: + if instance.support(name=service): + target = instance.get_stub_class() + if target is not None: + host = self._service_host[instance.get_service_name + "_service_host"] + port = self._service_ports[instance.get_service_name + "_service_port"] + target_url = host + ":" + str(port) + async with insecure_channel(target_url) as channel: + yield target(channel) + else: + raise RuntimeError("未提供对应服务Stub") class MockGRPCManager(gRPCManager): diff --git a/python_package/_321CQU/tools/httpServiceManager.py b/python_package/_321CQU/tools/httpServiceManager.py index fb8711d..e929f20 100644 --- a/python_package/_321CQU/tools/httpServiceManager.py +++ b/python_package/_321CQU/tools/httpServiceManager.py @@ -2,10 +2,13 @@ from .Singleton import Singleton from ..service import ServiceEnum +from ..service_handler import ServiceHandler class HttpServiceManager(metaclass=Singleton): def __init__(self, handler: ConfigHandler = _CONFIG_HANDLER): + # 初始化时创建每个ServiceHandler子类的实例 + self.service_instances = [cls() for cls in ServiceHandler.__subclasses__()] all_options = handler.get_options('ServiceSetting') service_hosts = list(filter(lambda x: x.endswith('_http_host'), all_options)) @@ -26,8 +29,8 @@ def __init__(self, handler: ConfigHandler = _CONFIG_HANDLER): def host(self, service: ServiceEnum) -> str: if not service.is_http_service: raise RuntimeError("该服务不是http服务") - - host = self._service_host[service.service_name + "_http_host"] - port = self._service_ports[service.service_name + "_http_port"] - - return host + ":" + port + for instance in self.service_instances: + if instance.support(name=service): + host = self._service_host[instance.get_service_name + "_http_host"] + port = self._service_ports[instance.get_service_name + "_http_port"] + return host + ":" + port