66 lines
2.7 KiB
Python
66 lines
2.7 KiB
Python
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`的占位符 `<parameter_name>` 声明路径参数,服务名称固定使用 `<service_name>` 占位符
|
||
: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 将 <service_name> 替换为路由配置中的后端服务
|
||
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) |