pull/25/head
sunface 7 years ago
parent 011eb8bc80
commit df71a4d07a

@ -27,6 +27,9 @@ type ApiServer struct {
func (p *ApiServer) Start() {
g.Info("start tfe..")
// 获取所有内部服务节点信息
g.ETCD.QueryAll(misc.Conf.Etcd.Addrs)
// 初始化mysql连接
misc.InitMysql()

@ -20,8 +20,8 @@ func (p *ApiServer) loadData() {
now := time.Now()
date := talent.Time2StringSecond(time.Now())
version := talent.Time2Version(now)
g.DB.Exec(fmt.Sprintf("insert into api_release (service,api_id,description,mock_data,route_type,route_addr,app,create_date) values('admin','admin.test.get.v1','','',1,'http://httpbin.org/get','admin','%s')", date))
g.DB.Exec(fmt.Sprintf("insert into api_define (service,api_id,description,mock_data,route_type,route_addr,revise_version,release_version,app,create_date) values('admin','admin.test.get.v1','','',1,'http://httpbin.org/get','%s','%s','admin','%s')", version, version, date))
g.DB.Exec(fmt.Sprintf("insert into api_release (service,api_id,description,mock_data,route_type,backend_addr,app,create_date) values('admin','admin.test.get.v1','','',1,'http://httpbin.org/get','admin','%s')", date))
g.DB.Exec(fmt.Sprintf("insert into api_define (service,api_id,description,mock_data,route_type,backend_addr,revise_version,release_version,app,create_date) values('admin','admin.test.get.v1','','',1,'http://httpbin.org/get','%s','%s','admin','%s')", version, version, date))
lastLoadTime = time.Now()
// 加载所有数据

@ -144,9 +144,9 @@ func (m *Manage) DefineAPI(c echo.Context) error {
pr := g.B64.EncodeToString(talent.String2Bytes(*api.ParamTable))
if action == "create" {
query := fmt.Sprintf(`insert into api_define (api_id,path_type,service,description,route_type,route_addr,route_proto,bw_strategy,retry_strategy,traffic_strategy,mock_data,traffic_on,traffic_api,traffic_ratio,traffic_ips,verify_on,param_rules,cached_time,revise_version,create_date,app)
values ('%s','%d','%s','%s','%d','%s','%d','%d','%d','%d','%s','%d','%s','%d','%s','%d','%s','%d','%s', '%s','%s')`,
api.APIID, api.PathType, api.Service, *api.Desc, api.RouteType, api.RouteAddr, api.RouteProto, api.BwStrategy, api.RetryStrategy, api.TrafficStrategy, *api.MockData, api.TrafficOn, api.TrafficAPI, api.TrafficRatio, api.TrafficIPs, api.VerifyOn, pr, api.CachedTime, talent.Time2Version(now), date, api.App)
query := fmt.Sprintf(`insert into api_define (api_id,path_type,service,description,route_type,backend_addr,backend_type,bw_strategy,retry_strategy,traffic_strategy,mock_data,traffic_on,traffic_api,traffic_ratio,traffic_ips,verify_on,param_rules,cached_time,revise_version,create_date,app,addr_type,backend_uri)
values ('%s','%d','%s','%s','%d','%s','%d','%d','%d','%d','%s','%d','%s','%d','%s','%d','%s','%d','%s', '%s','%s','%d','%s')`,
api.APIID, api.PathType, api.Service, *api.Desc, api.RouteType, api.BackendAddr, api.BackendType, api.BwStrategy, api.RetryStrategy, api.TrafficStrategy, *api.MockData, api.TrafficOn, api.TrafficAPI, api.TrafficRatio, api.TrafficIPs, api.VerifyOn, pr, api.CachedTime, talent.Time2Version(now), date, api.App, api.AddrType, api.BackendURI)
_, err := g.DB.Exec(query)
if err != nil {
if strings.Contains(err.Error(), g.DUP_KEY_ERR) {
@ -165,8 +165,8 @@ func (m *Manage) DefineAPI(c echo.Context) error {
}
// 初始化api发布表并设置为未发布状态
// 这里把不能再修改的值进行初始化
query = fmt.Sprintf(`insert into api_release (api_id,path_type,service,route_addr,status,create_date) values ('%s','%d','%s','%s','%d','%s')`,
api.APIID, api.PathType, api.Service, api.RouteAddr, misc.API_OFFLINE, date)
query = fmt.Sprintf(`insert into api_release (api_id,path_type,service,backend_addr,status,create_date) values ('%s','%d','%s','%s','%d','%s')`,
api.APIID, api.PathType, api.Service, api.BackendAddr, misc.API_OFFLINE, date)
_, err = g.DB.Exec(query)
if err != nil {
g.Info("access database error", zap.Error(err), zap.String("query", query))
@ -178,8 +178,8 @@ func (m *Manage) DefineAPI(c echo.Context) error {
}
audit.Log(c.FormValue("username"), api.Service, audit.TypeApi, api.APIID, audit.OpCreate, c.FormValue("api"), "")
} else {
query := fmt.Sprintf("update api_define set description='%s',route_type='%d',route_addr='%s',route_proto='%d',bw_strategy='%d',retry_strategy='%d',traffic_strategy='%d',mock_data='%s',traffic_on='%d',traffic_api='%s',traffic_ratio='%d',traffic_ips='%s',verify_on='%d',param_rules='%s',cached_time='%d',app='%s' where api_id='%s'",
*api.Desc, api.RouteType, api.RouteAddr, api.RouteProto, api.BwStrategy, api.RetryStrategy, api.TrafficStrategy, *api.MockData, api.TrafficOn, api.TrafficAPI, api.TrafficRatio, api.TrafficIPs, api.VerifyOn, pr, api.CachedTime, api.App, api.APIID)
query := fmt.Sprintf("update api_define set description='%s',route_type='%d',backend_addr='%s',backend_type='%d',bw_strategy='%d',retry_strategy='%d',traffic_strategy='%d',mock_data='%s',traffic_on='%d',traffic_api='%s',traffic_ratio='%d',traffic_ips='%s',verify_on='%d',param_rules='%s',cached_time='%d',app='%s',addr_type='%d',backend_uri='%s' where api_id='%s'",
*api.Desc, api.RouteType, api.BackendAddr, api.BackendType, api.BwStrategy, api.RetryStrategy, api.TrafficStrategy, *api.MockData, api.TrafficOn, api.TrafficAPI, api.TrafficRatio, api.TrafficIPs, api.VerifyOn, pr, api.CachedTime, api.App, api.AddrType, api.BackendURI, api.APIID)
res, err := g.DB.Exec(query)
if err != nil {
g.Info("access database error", zap.Error(err), zap.String("query", query))
@ -374,18 +374,26 @@ func (m *Manage) parseAPI(c echo.Context) (*misc.API, int, string) {
return nil, ApiWithServiceSuffixC, ApiWithServiceSuffixE
}
if api.RouteAddr == "" || strings.TrimSpace(api.RouteAddr) == "http://" || strings.TrimSpace(api.RouteAddr) == "https://" {
return nil, RouteAddrEmptyC, RouteAddrEmptyE
if api.BackendAddr == "" {
return nil, BackendAddrEmptyC, BackendAddrEmptyE
}
if api.RouteAddr != "" {
if !strings.HasPrefix(api.RouteAddr, "http") {
return nil, RouteAddrWithHTTPPrefixC, RouteAddrWithHTTPPrefixE
if api.AddrType == misc.ADDR_URL {
if strings.TrimSpace(api.BackendAddr) == "http://" || strings.TrimSpace(api.BackendAddr) == "https://" {
return nil, BackendAddrEmptyC, BackendAddrEmptyE
}
if !strings.HasPrefix(api.BackendAddr, "http") {
return nil, BackendAddrWithHTTPPrefixC, BackendAddrWithHTTPPrefixE
}
} else {
if !talent.OnlyAlphaNumAndUri(api.BackendURI) {
return nil, UriAlphaNumAndUriC, UriAlphaNumAndUriE
}
}
if (api.RouteProto != 1) && (api.RouteProto != 2) {
return nil, RouteProtoInvalidC, RouteProtoInvalidE
if (api.BackendType != 1) && (api.BackendType != 2) {
return nil, BackendTypeInvalidC, BackendTypeInvalidE
}
if api.TrafficAPI != "" {
@ -449,8 +457,8 @@ func (m *Manage) APIRelease(c echo.Context) error {
}
// 更新release
query = fmt.Sprintf("update api_release set description='%s',route_type='%d',route_addr='%s',route_proto='%d',mock_data='%s',retry_strategy='%d',bw_strategy='%d',traffic_strategy='%d',traffic_on='%d',traffic_api='%s',traffic_ratio='%d',traffic_ips='%s',verify_on='%d',param_rules='%s', cached_time='%d',status='%d',app='%s' where api_id='%s'",
*api.Desc, api.RouteType, api.RouteAddr, api.RouteProto, *api.MockData, api.RetryStrategy, api.BwStrategy, api.TrafficStrategy, api.TrafficOn, api.TrafficAPI, api.TrafficRatio, api.TrafficIPs, api.VerifyOn, *api.ParamTable, api.CachedTime, misc.API_RELEASED, api.App, api.APIID)
query = fmt.Sprintf("update api_release set description='%s',route_type='%d',backend_addr='%s',backend_type='%d',mock_data='%s',retry_strategy='%d',bw_strategy='%d',traffic_strategy='%d',traffic_on='%d',traffic_api='%s',traffic_ratio='%d',traffic_ips='%s',verify_on='%d',param_rules='%s', cached_time='%d',status='%d',app='%s',addr_type='%d',backend_uri='%s' where api_id='%s'",
*api.Desc, api.RouteType, api.BackendAddr, api.BackendType, *api.MockData, api.RetryStrategy, api.BwStrategy, api.TrafficStrategy, api.TrafficOn, api.TrafficAPI, api.TrafficRatio, api.TrafficIPs, api.VerifyOn, *api.ParamTable, api.CachedTime, misc.API_RELEASED, api.App, api.AddrType, api.BackendURI, api.APIID)
_, err = g.DB.Exec(query)
if err != nil {
@ -794,8 +802,8 @@ func (m *Manage) APIBatchRelease(c echo.Context) error {
}
// 更新release
query = fmt.Sprintf("update api_release set description='%s',route_type='%d',route_addr='%s',route_proto='%d',mock_data='%s',retry_strategy='%d',bw_strategy='%d',traffic_on='%d',traffic_api='%s',traffic_ratio='%d',traffic_ips='%s',verify_on='%d',param_rules='%s', cached_time='%d',status='%d',app='%s' where api_id='%s'",
*api.Desc, api.RouteType, api.RouteAddr, api.RouteProto, *api.MockData, api.RetryStrategy, api.BwStrategy, api.TrafficOn, api.TrafficAPI, api.TrafficRatio, api.TrafficIPs, api.VerifyOn, *api.ParamTable, api.CachedTime, misc.API_RELEASED, api.App, api.APIID)
query = fmt.Sprintf("update api_release set description='%s',route_type='%d',backend_addr='%s',backend_type='%d',mock_data='%s',retry_strategy='%d',bw_strategy='%d',traffic_on='%d',traffic_api='%s',traffic_ratio='%d',traffic_ips='%s',verify_on='%d',param_rules='%s', cached_time='%d',status='%d',app='%s',addr_type='%d',backend_uri='%s' where api_id='%s'",
*api.Desc, api.RouteType, api.BackendAddr, api.BackendType, *api.MockData, api.RetryStrategy, api.BwStrategy, api.TrafficOn, api.TrafficAPI, api.TrafficRatio, api.TrafficIPs, api.VerifyOn, *api.ParamTable, api.CachedTime, misc.API_RELEASED, api.App, api.AddrType, api.BackendURI, api.APIID)
_, err = g.DB.Exec(query)
if err != nil {

@ -21,14 +21,14 @@ const (
ApiOnlyAlphaNumAndDotC = 10006
ApiOnlyAlphaNumAndDotE = "API name can only be consisted of alphabet and numberic"
RouteAddrWithHTTPPrefixC = 10007
RouteAddrWithHTTPPrefixE = "Backend url must prefix with http:// or https://"
BackendAddrWithHTTPPrefixC = 10007
BackendAddrWithHTTPPrefixE = "Backend url must prefix with http:// or https://"
RouteAddrEmptyC = 10008
RouteAddrEmptyE = "Backend url cant be empty"
BackendAddrEmptyC = 10008
BackendAddrEmptyE = "Backend url cant be empty"
RouteProtoInvalidC = 10009
RouteProtoInvalidE = "Backend type invalid"
BackendTypeInvalidC = 10009
BackendTypeInvalidE = "Backend type invalid"
ReqTimeoutInvalidC = 10010
ReqTimeoutInvalidE = "Timeout must be in (0,60]"
@ -65,4 +65,7 @@ const (
StrategyNameExistE = "Strategy name already exist"
StrategyNameExistc = 1061
UriAlphaNumAndUriC = 10062
UriAlphaNumAndUriE = "uri can only be consisted of alphabet,numberic and /"
)

@ -92,7 +92,7 @@ func (router *router) route(c echo.Context) error {
func (rt *router) redirect(c echo.Context, r *req.Request) error {
// 组装参数
url := r.Api.RouteAddr + "?" + c.QueryString()
url := r.Api.BackendAddr + "?" + c.QueryString()
return c.Redirect(http.StatusMovedPermanently, url)
}
@ -118,7 +118,17 @@ func (rt *router) sync(r *req.Request) (int, []byte, error) {
// 写入客户端真实ip
req.Header.Set("X-Forwarded-For", r.ClientIP)
url := r.Api.RouteAddr
var url string
// 获取url
if r.Api.AddrType == misc.ADDR_URL { // direct url
url = r.Api.BackendAddr
} else { // get url from etcd
s := g.GetServer(r.Api.BackendAddr)
if s == nil {
return http.StatusServiceUnavailable, nil, errors.New("no target server available")
}
url = "http://" + s.IP + r.Api.BackendURI
}
switch r.Method {
case "GET":
// 拼接url
@ -126,7 +136,6 @@ func (rt *router) sync(r *req.Request) (int, []byte, error) {
default:
args.WriteTo(req.BodyWriter())
}
req.SetRequestURI(url)
// 超时重试

@ -8,9 +8,11 @@ CREATE TABLE IF NOT EXISTS `api_release` (
`service` varchar(255) NOT NULL COMMENT 'service名',
`description` text COMMENT '介绍',
`route_type` int(11) NOT NULL DEFAULT '1' COMMENT '代理类型',
`route_addr` varchar(255) NOT NULL COMMENT '后段服务地址',
`route_proto` int(11) DEFAULT '1' COMMENT '后端服务协议',
`route_type` int(11) NOT NULL DEFAULT '1' COMMENT '代理类型,1: direct 2: redirect',
`addr_type` int(11) DEFAULT '1' COMMENT '后端地址类型,1:直接寻址 2: ETCD服务发现',
`backend_addr` varchar(255) NOT NULL COMMENT '后段服务地址',
`backend_uri` varchar(255) DEFAUlT '' COMMENT '后端服务URI路径',
`backend_type` int(11) DEFAULT '1' COMMENT '后端服务协议,1: HTTP(S) 2: Mock',
`mock_data` text COMMENT 'mock类型接口返回定义的mock数据',
`retry_strategy` int(11) DEFAULT '0' COMMENT '重试策略ID',
@ -46,9 +48,11 @@ CREATE TABLE IF NOT EXISTS `api_define` (
`service` varchar(255) NOT NULL COMMENT 'service名',
`description` text COMMENT '介绍',
`route_type` int(11) NOT NULL DEFAULT '1' COMMENT '代理类型',
`route_addr` varchar(255) NOT NULL COMMENT '后段服务地址',
`route_proto` int(11) DEFAULT '1' COMMENT '后端服务协议',
`route_type` int(11) NOT NULL DEFAULT '1' COMMENT '代理类型,1: direct 2: redirect',
`addr_type` int(11) DEFAULT '1' COMMENT '后端地址类型,1:直接寻址 2: ETCD服务发现',
`backend_addr` varchar(255) NOT NULL COMMENT '后段服务地址',
`backend_uri` varchar(255) DEFAUlT '' COMMENT '后端服务URI路径',
`backend_type` int(11) DEFAULT '1' COMMENT '后端服务协议,1: HTTP(S) 2: Mock',
`mock_data` text COMMENT 'mock类型接口返回定义的mock数据',
`retry_strategy` int(11) DEFAULT '0' COMMENT '重试策略ID',

@ -50,6 +50,9 @@ const (
STRATEGY_ON = 1
STRATEGY_OFF = 0
ADDR_URL = 1
ADDR_ETCD = 2
)
// redis后缀

@ -19,8 +19,10 @@ type API struct {
Desc *string `db:"description" json:"desc"`
RouteType int `db:"route_type" json:"route_type"`
RouteAddr string `db:"route_addr" json:"route_addr"`
RouteProto int `db:"route_proto" json:"route_proto"`
AddrType int `db:"addr_type" json:"addr_type"`
BackendAddr string `db:"backend_addr" json:"backend_addr"`
BackendURI string `db:"backend_uri" json:"backend_uri"`
BackendType int `db:"backend_type" json:"backend_type"`
MockData *string `db:"mock_data" json:"mock_data"`
// 通用策略

Loading…
Cancel
Save