router fix

This commit is contained in:
黄孟柱
2021-07-27 15:24:29 +08:00
parent 9187822122
commit cd2a15f7c6
5 changed files with 71 additions and 26 deletions

View File

@@ -12,6 +12,7 @@ import (
"fmt"
"github.com/eolinker/goku-eosc/router/checker"
"sort"
"strings"
)
type RulePath struct {
@@ -29,16 +30,16 @@ type ICreateHelper interface {
//ParseRouter parse rule to IRouter
func ParseRouter(rules []Rule,helper ICreateHelper)(IRouter,error) {
root:=newCreateRoot()
root:=newCreateRoot(helper)
for i:=range rules{
r:=rules[i]
err:=root.add(r.Path,NewEndpoint(r.Target,r.Path))
err:=root.add(r.Path,r.Target)
if err!= nil{
return nil,err
}
}
return root.toRouter(helper ),nil
return root.toRouter( ),nil
}
type createNodes map[string]*createNode
@@ -87,6 +88,7 @@ type createNodeList struct {
ICreateHelper
}
func (cl *createNodeList) Len() int {
return len(cl.nodes)
}
@@ -99,30 +101,51 @@ func (cl *createNodeList) Swap(i, j int) {
cl.nodes[i],cl.nodes[j] = cl.nodes[j],cl.nodes[i]
}
type PathSort struct {
path []RulePath
helper ICreateHelper
}
func (p *PathSort) Len() int {
return len(p.path)
}
func (p *PathSort) Less(i, j int) bool {
return p.helper.Less(p.path[i].CMD,p.path[j].CMD)
}
func (p *PathSort) Swap(i, j int) {
p.path[i],p.path[j]= p.path[j],p.path[i]
}
type createRoot struct {
helper ICreateHelper
nexts createNodes
}
func newCreateRoot() *createRoot {
func newCreateRoot(helper ICreateHelper) *createRoot {
return &createRoot{
nexts: make(createNodes),
helper:helper,
}
}
func (cr *createRoot) toRouter(helper ICreateHelper) IRouter {
func (cr *createRoot) toRouter() IRouter {
return cr.nexts.toRouter(helper)
return cr.nexts.toRouter(cr.helper)
}
type IEndpoint interface {
type IEndPoint interface {
CMDs()[]string
Get(CMD string)(checker.Checker,bool)
Target()string
EndPoint()string
}
type tEndpoint struct {
target string
cmds []string
checkers map[string]checker.Checker
endpoint string
}
func (e *tEndpoint) CMDs() []string {
@@ -137,26 +160,44 @@ func (e *tEndpoint) Get(CMD string) (checker.Checker,bool) {
func (e *tEndpoint) Target() string {
return e.target
}
func (e *tEndpoint)EndPoint()string {
return e.target
}
func NewEndpoint(target string, path []RulePath) *tEndpoint {
cs:=make(map[string]checker.Checker)
cmds:=make([]string,0,len(path))
build:=strings.Builder{}
for _,p:=range path{
cs[p.CMD] = p.Checker
cmds = append(cmds, p.CMD)
build.WriteString(p.CMD)
build.WriteString(p.Checker.Key())
build.WriteString("&")
}
return &tEndpoint{target: target, checkers:cs,cmds:cmds}
return &tEndpoint{target: target, checkers:cs,cmds:cmds,endpoint:build.String()}
}
func (e *tEndpoint) Router(source ISource) (endpoint IEndpoint, has bool) {
func (e *tEndpoint) Router(source ISource) (endpoint IEndPoint, has bool) {
return e,e!= nil
}
func (cr *createRoot) add(path []RulePath,endpoint *tEndpoint) error {
if len(path) == 0 || endpoint == nil {
func (cr *createRoot) add(path []RulePath,target string) error {
if len(path) == 0 || target == "" {
return fmt.Errorf("invalid router")
}
return cr.nexts.add(path,endpoint)
cl:= &PathSort{
path:path,
helper:cr.helper,
}
sort.Sort(cl)
return cr.nexts.add(path, NewEndpoint(target,path))
}
type createChecker struct {
@@ -193,7 +234,7 @@ func (cc *createChecker) toRouter(helper ICreateHelper) IRouter {
func (cc *createChecker) add(path []RulePath,endpoint *tEndpoint) error {
if len(path) == 0 {
if cc.endpoint != nil{
return fmt.Errorf("%s target %s: exist",cc.checker.Key(),endpoint.target)
return fmt.Errorf("%s: exist",endpoint.endpoint)
}
cc.endpoint = endpoint
return nil

View File

@@ -425,13 +425,13 @@ var tests = []struct {
},
},
want: []string{"demo2", "demo3"},
wantErr: true,
wantErr: false,
},
}
func TestParseRouter(t *testing.T) {
helper := NewTestHelper([]string{"location", "header", "query"})
helper := NewTestHelper([]string{"host","location", "header", "query"})
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@@ -444,6 +444,10 @@ func TestParseRouter(t *testing.T) {
t.Errorf("ParseRouter() error = %v, wantErr %v", err, tt.wantErr)
return
}
if tt.wantErr{
t.Logf("ParseRouter() error = %v ok", err)
return
}
for i, s := range tt.testCase {
endpoint, h := r.Router(s)

View File

@@ -16,7 +16,7 @@ import (
)
var _ service.IRouterEndpoint = (*EndPoint)(nil)
type EndPoint struct {
endpoint router.IEndpoint
endpoint router.IEndPoint
headers []string
@@ -63,7 +63,7 @@ func (e *EndPoint) Queries() []string {
func NewEndPoint(endpoint router.IEndpoint) *EndPoint {
func NewEndPoint(endpoint router.IEndPoint) *EndPoint {
return &EndPoint{endpoint: endpoint}
}

View File

@@ -9,7 +9,7 @@ import (
)
type IMatcher interface {
Match(req *http.Request) (service.IService, router.IEndpoint, bool)
Match(req *http.Request) (service.IService, router.IEndPoint, bool)
}
type Matcher struct {
@@ -17,7 +17,7 @@ type Matcher struct {
services map[string]service.IService
}
func (m *Matcher) Match(req *http.Request) (service.IService, router.IEndpoint, bool) {
func (m *Matcher) Match(req *http.Request) (service.IService, router.IEndPoint, bool) {
sources := newHttpSources(req)
endpoint, has := m.r.Router(sources)

View File

@@ -9,12 +9,12 @@ type ISource interface {
}
type IRouter interface {
Router(source ISource)(endpoint IEndpoint,has bool)
Router(source ISource)(endpoint IEndPoint,has bool)
}
type Routers []IRouter
func (rs Routers) Router(source ISource) ( IEndpoint, bool) {
func (rs Routers) Router(source ISource) (IEndPoint, bool) {
for _,r:=range rs{
if target,has:=r.Router(source);has{
return target,has
@@ -35,7 +35,7 @@ type Node struct {
func (n *Node) Router(source ISource) ( IEndpoint, bool) {
func (n *Node) Router(source ISource) (IEndPoint, bool) {
v,has:=source.Get(n.cmd)
@@ -61,16 +61,16 @@ func (n *Node) Router(source ISource) ( IEndpoint, bool) {
type NodeShut struct {
next IRouter
endpoint IEndpoint
endpoint IEndPoint
}
func (n *NodeShut) Router(source ISource) ( IEndpoint, bool) {
func (n *NodeShut) Router(source ISource) (IEndPoint, bool) {
if e ,has:=n.next.Router(source);has{
return e,has
}
return n.endpoint,true
}
func NewNodeShut(next IRouter, endpoint IEndpoint) IRouter {
func NewNodeShut(next IRouter, endpoint IEndPoint) IRouter {
return &NodeShut{next: next, endpoint: endpoint}
}