from utils import * class Route(object): """ 路由实体类,对应一项路由配置 TODO replace_placeholder 函数,替换字符串中的占位符 TODO extract_placeholders 函数,获取字符串中的点位符 TODO get_pipe 函数,通过handler name获取对应的PipeHandler类 """ SERVICE_NAME_PLACEHOLDER = 'service_name' def __init__(self, name, service_name, methods, path, upstream_path, pipelines=None): """ :param str name: (string) 路由名称 :param str service_name: (string) 内部微服务名称(如 `resolver` `data_manager` 等) :param list methods: (array) 支持的请求方法列表, 如 `['GET', 'PUT']` :param str path: (string) 匹配的路径,使用`flask`的占位符 `` 声明路径参数,服务名称固定使用 `` 占位符 :param str upstream_path: (string) 转发到上游服务的路径,与`path`使用同样风格的参数占位符 :param dict pipelines: (object) 数据处理管道 """ if not isinstance(methods, (list, set, tuple)): raise ValueError("methods must be an iterable list") pipelines = pipelines or {} self.name = name self.service_name = service_name self.methods = list(set(methods)) # 使用 replace_placeholder 将 替换为路由配置中的后端服务 self.path = replace_placeholder(path, self.SERVICE_NAME_PLACEHOLDER, service_name) self.upstream_path = replace_placeholder(upstream_path, self.SERVICE_NAME_PLACEHOLDER, service_name) self.pipelines = { "inbound": map(self.init_pipe_handler, pipelines.get('inbound') or []), "outbound": map(self.init_pipe_handler, pipelines.get('outbound') or []), } # 导出上游服务资源所需的参数(占位符) self.upstream_params = extract_placeholders(self.upstream_path) def init_pipe_handler(self, pipe_conf): try: name = pipe_conf['name'] properties = pipe_conf.get('properties', {}) klass = get_pipe(name) return klass(**properties) except Exception as e: raise ValueError("illegal pipe config {}: {}".format(pipe_conf, e)) def inbound_pipes(self): return self.pipelines.get("inbound") or [] def outbound_pipes(self): return self.pipelines.get("outbound") or [] def load(routes): """ :param list of dict routes: 路由配置列表 :rtype: list of Route """ return map(lambda kv: Route(**kv), routes)