diff --git a/README.md b/README.md index 5868a207a584c03dfc07059a624356cebf1df8e6..0ad3746eea24c0988ffe79927ffb761210785a40 100644 --- a/README.md +++ b/README.md @@ -91,4 +91,4 @@ You may obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -``` +``` \ No newline at end of file diff --git a/admin/cmd/cmd.go b/admin/cmd/cmd.go new file mode 100644 index 0000000000000000000000000000000000000000..1c2ed6b132cf713fe739c2a4d9c7ec70caaf7e26 --- /dev/null +++ b/admin/cmd/cmd.go @@ -0,0 +1,47 @@ +package cmd + +import ( + "encoding/json" + "errors" + + "github.com/eolinker/goku-api-gateway/config" +) + +var ( + ErrorInvalidNodeInstance = errors.New("invalid instance value") + ErrorInvalidNodeConfig = errors.New("invalid instance config") +) + +type Code string + +const ( + None Code = "none" + NodeRegister Code = "register" + NodeRegisterResult Code = "register-result" + NodeLevel Code = "level" + Config Code = "config" + Restart Code = "restart" + Stop Code = "stop" + Monitor Code = "monitor" + EventClientLeave Code = "leave" + Error Code = "error" +) + +func EncodeConfig(c *config.GokuConfig) ([]byte, error) { + if c == nil { + return nil, ErrorInvalidNodeConfig + } + + return json.Marshal(c) +} +func DecodeConfig(data []byte) (*config.GokuConfig, error) { + if len(data) == 0 { + return nil, ErrorInvalidNodeConfig + } + c := new(config.GokuConfig) + err := json.Unmarshal(data, c) + if err != nil { + return nil, err + } + return c, nil +} diff --git a/admin/cmd/conn.go b/admin/cmd/conn.go new file mode 100644 index 0000000000000000000000000000000000000000..772001fd4fabd291fc591c8bd5fba871e4dfce9a --- /dev/null +++ b/admin/cmd/conn.go @@ -0,0 +1,84 @@ +package cmd + +import ( + "context" + "errors" + "net" + "sync" +) + +var ( + ErrorSendToClosedConnect = errors.New("send to closed connect") +) + +type Connect struct { + conn net.Conn + + //inputC chan _Frame + outputC chan []byte + + doneC chan struct{} + + ctx context.Context + cancelFunc context.CancelFunc + + once sync.Once +} + +func NewConnect(conn net.Conn) *Connect { + ctx, cancel := context.WithCancel(context.Background()) + c := &Connect{ + conn: conn, + + //inputC: make(chan _Frame,10), + outputC: make(chan []byte, 10), + + ctx: ctx, + cancelFunc: cancel, + } + + go c.r() + + return c +} +func (c *Connect) r() { + + for { + frame, err := ReadFrame(c.conn) + if err != nil { + break + } + c.outputC <- frame + } + close(c.outputC) +} + +func (c *Connect) Close() error { + + c.once.Do(func() { + c.cancelFunc() + c.conn.Close() + + }) + + return nil +} + +func (c *Connect) LocalAddr() net.Addr { + return c.conn.LocalAddr() +} + +func (c *Connect) RemoteAddr() net.Addr { + return c.conn.RemoteAddr() +} + +func (c *Connect) Send(code Code, data []byte) error { + return SendFrame(c.conn, code, data) +} + +func (c *Connect) ReadC() <-chan []byte { + return c.outputC +} +func (c *Connect) Done() <-chan struct{} { + return c.ctx.Done() +} diff --git a/admin/cmd/error.go b/admin/cmd/error.go new file mode 100644 index 0000000000000000000000000000000000000000..780f7c0104a23426a0389023c23617b0fd9326c3 --- /dev/null +++ b/admin/cmd/error.go @@ -0,0 +1,14 @@ +package cmd + +type ErrorInfo struct { + Error string `json:"error"` +} + +func DecodeError(data []byte) (string, error) { + + return string(data), nil +} +func EncodeError(err string) ([]byte, error) { + + return []byte(err), nil +} diff --git a/admin/cmd/register.go b/admin/cmd/register.go new file mode 100644 index 0000000000000000000000000000000000000000..3f80793b6cb11d06edcdb79ccce3d3915fdc3f08 --- /dev/null +++ b/admin/cmd/register.go @@ -0,0 +1,52 @@ +package cmd + +import ( + "encoding/json" + "github.com/eolinker/goku-api-gateway/config" +) + +type RegisterResult struct { + Code int + Error string + Config *config.GokuConfig +} + +func DecodeRegisterResult(data []byte) (*RegisterResult, error) { + r := new(RegisterResult) + err := json.Unmarshal(data, r) + if err != nil { + return nil, err + } + return r, nil +} +func EncodeRegisterResultConfig(c *config.GokuConfig) ([]byte, error) { + r := RegisterResult{ + Code: 0, + Error: "", + Config: c, + } + return json.Marshal(r) +} +func EncodeRegisterResultError(err string) ([]byte, error) { + r := RegisterResult{ + Code: -1, + Error: err, + Config: nil, + } + return json.Marshal(r) +} + +func DecodeRegister(data []byte) (string, error) { + if len(data) == 32 { + return string(data), nil + } + return "", ErrorInvalidNodeInstance +} + +func EncodeRegister(nodeKey string) ([]byte, error) { + data := []byte(nodeKey) + if len(data) == 32 { + return data, nil + } + return nil, ErrorInvalidNodeInstance +} diff --git a/admin/cmd/server.go b/admin/cmd/server.go new file mode 100644 index 0000000000000000000000000000000000000000..b7bc0e5f7b0c0cd5030a6fe12252ed489dd98f55 --- /dev/null +++ b/admin/cmd/server.go @@ -0,0 +1,86 @@ +package cmd + +import ( + "bytes" + "encoding/binary" + "errors" + "io" + + "github.com/eolinker/goku-api-gateway/common/ioutils" +) + +var ( + ErrorEmptyFrame = errors.New("empty frame") + ErrorInvalidCode = errors.New("invalid code") +) + +func ReadFrame(reader io.Reader) ([]byte, error) { + + sizeBuf := make([]byte, 4, 4) + // 获取报文头部信息 + _, err := io.ReadFull(reader, sizeBuf) + if err != nil { + return nil, err + } + // 获取报文数据大小 + size := binary.BigEndian.Uint32(sizeBuf) + + data := make([]byte, size, size) + + _, e := io.ReadFull(reader, data) + if e != nil { + return nil, err + } + return data, nil +} +func GetCmd(frame []byte) (Code, []byte, error) { + frameLen := len(frame) + if frameLen < 5 { + // 长度小于5时,报文没有数据 + return "", nil, ErrorEmptyFrame + } + buf := bytes.NewBuffer(frame) + codeData, n, err := ioutils.ReadLField(buf, nil) + if err != nil { + return "", nil, err + } + + return Code(codeData), frame[n:], nil +} + +func SendError(w io.Writer, err error) { + if err == nil { + return + } + data := []byte(err.Error()) + SendFrame(w, Error, data) +} +func SendFrame(w io.Writer, code Code, data []byte) error { + codeData := []byte(code) + + size := uint32(len(data) + len(codeData) + 1) + sizeAll := size + 4 + buf := bytes.NewBuffer(make([]byte, sizeAll, sizeAll)) + buf.Reset() + + err := binary.Write(buf, binary.BigEndian, size) + if err != nil { + return err + } + + _, err = ioutils.WriteLField(buf, codeData) + if err != nil { + return err + } + + if len(data) > 0 { + _, err := buf.Write(data) + if err != nil { + return err + } + } + //b:= buf.Bytes() + //_,err =w.Write(b) + _, err = buf.WriteTo(w) + return err +} diff --git a/admin/console/callback.go b/admin/console/callback.go new file mode 100644 index 0000000000000000000000000000000000000000..ea3c33f97c01538d9f8385f3a5307028a8af0bcd --- /dev/null +++ b/admin/console/callback.go @@ -0,0 +1,52 @@ +package console + +import ( + "github.com/eolinker/goku-api-gateway/admin/cmd" + goku_log "github.com/eolinker/goku-api-gateway/goku-log" +) + +type Callback func(code cmd.Code, data []byte,client *Client) error + +func (c Callback) ServerCode(code cmd.Code, data []byte, client *Client) error{ + return c(code,data,client) +} + +type CodeHandler interface { + ServerCode(code cmd.Code, data []byte,client *Client)error +} + +//Register cmd 回调注册器 +type Register struct { + callbacks map[cmd.Code][]CodeHandler +} +//NewRegister create register +func NewRegister() *Register { + return &Register{ + callbacks: make(map[cmd.Code][]CodeHandler), + } +} + +//Register 注册回调 +func (s *Register) Register(code cmd.Code,handler CodeHandler){ + s.callbacks[code] = append(s.callbacks[code],handler) +} +//Register 注册回调 +func (s *Register) RegisterFunc(code cmd.Code,callback func(code cmd.Code, data []byte,client *Client) error){ + s.callbacks[code] = append(s.callbacks[code],Callback(callback)) +} + +//Callback 调用回调 +func (s *Register)Callback(code cmd.Code,data []byte,client *Client)error { + m:=s.callbacks + callbacks,has:= m[code] + if !has{ + goku_log.Info("not exists call for ",code) + return nil + } + for _,handler:=range callbacks{ + if e:=handler.ServerCode(code,data,client);e!=nil{ + return e + } + } + return nil +} \ No newline at end of file diff --git a/admin/console/client-manager.go b/admin/console/client-manager.go new file mode 100644 index 0000000000000000000000000000000000000000..d564784264e569ecbad82a1b2196d093906a3653 --- /dev/null +++ b/admin/console/client-manager.go @@ -0,0 +1,67 @@ +package console + +import ( + "fmt" + "sync" + + "github.com/eolinker/goku-api-gateway/common/listener" +) + +type ClientManager struct { + clients map[string]*Client + locker sync.RWMutex + intercept *listener.Intercept +} + +var ( + clientManager = &ClientManager{ + clients: make(map[string]*Client), + locker: sync.RWMutex{}, + intercept: listener.NewIntercept(), + } +) + +func (m *ClientManager) Add(client *Client) (err error) { + + if _, has := m.Get(client.instance); has { + return ErrorDuplicateInstance + } + + e := m.intercept.Call(client) + if e != nil { + return e + } + m.locker.Lock() + + _, has := m.clients[client.instance] + if has { + fmt.Println(client.instance) + err = ErrorDuplicateInstance + } else { + m.clients[client.instance] = client + err = nil + } + m.locker.Unlock() + return +} +func (m *ClientManager) Get(instance string) (*Client, bool) { + m.locker.RLock() + c, has := m.clients[instance] + m.locker.RUnlock() + return c, has +} +func (m *ClientManager) Remove(instance string) { + m.locker.Lock() + delete(m.clients, instance) + m.locker.Unlock() +} +func InterceptNodeRegister(f func(client *Client) error) { + clientManager.intercept.Add(func(v interface{}) error { + c := v.(*Client) + return f(c) + }) +} +func IsLive(key string) bool { + _, b := clientManager.Get(key) + return b +} diff --git a/admin/console/client.go b/admin/console/client.go new file mode 100644 index 0000000000000000000000000000000000000000..e8e960c5c00b424e5891573f6377bef43e0bee92 --- /dev/null +++ b/admin/console/client.go @@ -0,0 +1,50 @@ +package console + +import ( + "net" + + "github.com/eolinker/goku-api-gateway/admin/cmd" + "github.com/eolinker/goku-api-gateway/config" + entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" +) + +type Client struct { + *cmd.Connect + instance string +} + +func NewClient(conn net.Conn, instance string) *Client { + + return &Client{ + Connect: cmd.NewConnect(conn), + instance: instance, + } +} + +func (c *Client) Instance() string { + return c.instance +} + +func (c *Client) SendConfig(conf *config.GokuConfig, nodeInfo *entity.Node) error { + + nodeConfig := toNodeConfig(conf, nodeInfo) + + data, err := cmd.EncodeConfig(nodeConfig) + if err != nil { + return err + } + + return c.Send(cmd.Config, data) +} + +func (c *Client) SendRunCMD(operate string) error { + + if operate == "stop" { + return c.Send(cmd.Stop, []byte("")) + } else if operate == "restart" { + + return c.Send(cmd.Restart, []byte("")) + } + return nil + +} diff --git a/admin/console/config.go b/admin/console/config.go new file mode 100644 index 0000000000000000000000000000000000000000..bba8b7af7a525108c6f6fab17fbf6ce3c6118678 --- /dev/null +++ b/admin/console/config.go @@ -0,0 +1,17 @@ +package console + +import ( + "github.com/eolinker/goku-api-gateway/config" + entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" +) + +func toNodeConfig(c *config.GokuConfig, nodeInfo *entity.Node) *config.GokuConfig { + + conf := *c + conf.Cluster = nodeInfo.Cluster + conf.BindAddress = nodeInfo.ListenAddress + conf.AdminAddress = nodeInfo.AdminAddress + conf.Instance = nodeInfo.NodeKey + + return &conf +} diff --git a/admin/console/console.go b/admin/console/console.go new file mode 100644 index 0000000000000000000000000000000000000000..6b3ce1990170aa61cddde9429b67749f9926772a --- /dev/null +++ b/admin/console/console.go @@ -0,0 +1,132 @@ +package console + +import ( + "context" + "fmt" + "net" + "sync" + + "github.com/eolinker/goku-api-gateway/admin/cmd" + "github.com/eolinker/goku-api-gateway/console/module/node" + "github.com/eolinker/goku-api-gateway/console/module/versionConfig" +) + +var ( + register *Register + ctx context.Context + cancelFunc context.CancelFunc + + once sync.Once +) + +func Stop() { + cancelFunc() +} + +func Start(addr string) error { + once.Do(func() { + versionConfig.InitVersionConfig() + register = doRegister() + }) + + var lc net.ListenConfig + ctx, cancelFunc = context.WithCancel(context.Background()) + + listener, err := lc.Listen(ctx, "tcp", addr) + if err != nil { + return err + } + + go doAccept(listener) + return nil + +} + +func doAccept(listener net.Listener) { + for { + conn, e := listener.Accept() + if e != nil { + listener.Close() + return + } + + go startClient(conn) + + } +} + +func readClient(conn net.Conn) (string, error) { + frame, e := cmd.ReadFrame(conn) + if e != nil { + return "", e + } + + code, data, e := cmd.GetCmd(frame) + if e != nil { + return "", e + } + if code != cmd.NodeRegister { + return "", ErrorNeedRegister + } + + instance, err := cmd.DecodeRegister(data) + if err != nil { + return "", err + } + + return instance, nil + +} +func startClient(conn net.Conn) { + + instance, err := readClient(conn) + if err != nil { + return + } + fmt.Println(instance) + if !node.Lock(instance) { + data, err := cmd.EncodeRegisterResultError(ErrorDuplicateInstance.Error()) + if err == nil { + cmd.SendFrame(conn, cmd.NodeRegisterResult, data) + } + //conn.Close() + return + } + + client := NewClient(conn, instance) + defer func() { + node.UnLock(instance) + NodeLeave(client) + _ = client.Close() + }() + + e := NodeRegister(client) + if e != nil { + data, err := cmd.EncodeRegisterResultError(e.Error()) + if err == nil { + cmd.SendFrame(conn, cmd.NodeRegisterResult, data) + } + return + } + + for { + select { + case frame, ok := <-client.ReadC(): + { + if !ok { + return + } + code, data, e := cmd.GetCmd(frame) + if e != nil { + return + } + err := register.Callback(code, data, client) + if err != nil { + return + } + } + case <-client.Done(): + return + } + } +} diff --git a/admin/console/node-register.go b/admin/console/node-register.go new file mode 100644 index 0000000000000000000000000000000000000000..a644c2b478481542b8051dfffc673ea9166a0029 --- /dev/null +++ b/admin/console/node-register.go @@ -0,0 +1,97 @@ +package console + +import ( + "errors" + + "github.com/eolinker/goku-api-gateway/admin/cmd" + "github.com/eolinker/goku-api-gateway/config" + "github.com/eolinker/goku-api-gateway/console/module/node" + "github.com/eolinker/goku-api-gateway/console/module/versionConfig" + log "github.com/eolinker/goku-api-gateway/goku-log" + entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" +) + +var ( + ErrorDuplicateInstance = errors.New("duplicate instance") + ErrorNeedRegister = errors.New("need register") +) + +func NodeRegister(client *Client) error { + + err := clientManager.Add(client) + if err != nil { + return err + } + + nodeInfo, err := node.GetNodeInfoByKey(client.instance) + + if err != nil { + return ErrorDuplicateInstance + } + result, err := versionConfig.GetConfig(nodeInfo.Cluster) + if err != nil { + return err + } + nodeConf := toNodeConfig(result, nodeInfo) + data, _ := cmd.EncodeRegisterResultConfig(nodeConf) + + return client.Send(cmd.NodeRegisterResult, data) +} + +func NodeLeave(client *Client) { + clientManager.Remove(client.instance) + +} + +func getNodeMapByCluster() (map[string][]*entity.Node, error) { + nodes, e := node.GetAllNode() + if e != nil { + return nil, e + } + + nodeMap := make(map[string][]*entity.Node) + for _, node := range nodes { + + nodeMap[node.Cluster] = append(nodeMap[node.Cluster], node) + } + return nodeMap, nil +} +func OnConfigChange(conf map[string]*config.GokuConfig) { + + nodeMap, err := getNodeMapByCluster() + if err != nil { + log.Warn(err) + } + for cluster, c := range conf { + for _, nodeInfo := range nodeMap[cluster] { + + client, has := clientManager.Get(nodeInfo.NodeKey) + if has { + + _ = client.SendConfig(c, nodeInfo) + + } + + } + } +} + +func StopNode(nodeKey string) { + + client, has := clientManager.Get(nodeKey) + if has { + _ = client.SendRunCMD("stop") + NodeLeave(client) + + } +} + +func RestartNode(nodeKey string) { + + client, has := clientManager.Get(nodeKey) + if has { + NodeLeave(client) + node.UnLock(nodeKey) + _ = client.SendRunCMD("restart") + } +} diff --git a/admin/console/register.go b/admin/console/register.go new file mode 100644 index 0000000000000000000000000000000000000000..08e7e3a16e75295e627719ad5c5acf07361db25a --- /dev/null +++ b/admin/console/register.go @@ -0,0 +1,33 @@ +package console + +import ( + "github.com/eolinker/goku-api-gateway/admin/cmd" + "github.com/eolinker/goku-api-gateway/console/module/versionConfig" + log "github.com/eolinker/goku-api-gateway/goku-log" +) + + +var( + callbacksInit = NewRegister() +) + +func doRegister()*Register{ + + r:=callbacksInit + callbacksInit = nil + versionConfig.AddCallback(OnConfigChange) + return r +} +func AddRegisterHandler(code cmd.Code,handler CodeHandler) { + if callbacksInit == nil{ + log.Panic("not allow register now") + } + callbacksInit.Register(code,handler) +} + +func AddRegisterFunc(code cmd.Code,handleFunc func(code cmd.Code, data []byte,client *Client) error) { + if callbacksInit == nil{ + log.Panic("not allow register now") + } + callbacksInit.RegisterFunc(code,handleFunc) +} \ No newline at end of file diff --git a/admin/node/callback.go b/admin/node/callback.go new file mode 100644 index 0000000000000000000000000000000000000000..41aa62c042ae89d41e032505a9b26700b7ce9fd1 --- /dev/null +++ b/admin/node/callback.go @@ -0,0 +1,49 @@ +package node + +import ( + "github.com/eolinker/goku-api-gateway/admin/cmd" +) + +type Callback func(code cmd.Code, data []byte) error + +func (c Callback) ServerCode(code cmd.Code, data []byte) error { + return c(code, data) +} + +type CodeHandler interface { + ServerCode(code cmd.Code, data []byte) error +} + +//Register cmd 回调注册器 +type Register struct { + callbacks map[cmd.Code][]CodeHandler +} + +//NewRegister create register +func NewRegister() *Register { + return &Register{ + callbacks: make(map[cmd.Code][]CodeHandler), + } +} + +//Register 注册回调 +func (s *Register) Register(code cmd.Code, handler CodeHandler) { + s.callbacks[code] = append(s.callbacks[code], handler) +} + +//Register 注册回调 +func (s *Register) RegisterFunc(code cmd.Code, callback func(code cmd.Code, data []byte) error) { + s.callbacks[code] = append(s.callbacks[code], Callback(callback)) +} + +//Callback 调用回调 +func (s *Register) Callback(code cmd.Code, data []byte) error { + m := s.callbacks + + for _, handler := range m[code] { + if e := handler.ServerCode(code, data); e != nil { + return e + } + } + return nil +} diff --git a/admin/node/config.go b/admin/node/config.go new file mode 100644 index 0000000000000000000000000000000000000000..9befefe69b99f8952fc0ec7621f716b906497d6b --- /dev/null +++ b/admin/node/config.go @@ -0,0 +1,17 @@ +package node + +import ( + "github.com/eolinker/goku-api-gateway/admin/cmd" +) + + +func (c *TcpConsole)OnConfigChange(code cmd.Code,data []byte) error { + + conf,err:= cmd.DecodeConfig(data) + if err!=nil{ + return err + } + c.lastConfig.Set(conf) + c.listener.Call(conf) + return nil +} \ No newline at end of file diff --git a/admin/node/console.go b/admin/node/console.go new file mode 100644 index 0000000000000000000000000000000000000000..88f0bdae7085ebcf36fb62ea1c3e1d12448e6e5b --- /dev/null +++ b/admin/node/console.go @@ -0,0 +1,181 @@ +package node + +import ( + "context" + "errors" + "net" + "sync" + "time" + + "github.com/eolinker/goku-api-gateway/admin/cmd" + "github.com/eolinker/goku-api-gateway/common/listener" + "github.com/eolinker/goku-api-gateway/common/manager" + "github.com/eolinker/goku-api-gateway/config" + "github.com/eolinker/goku-api-gateway/node/console" +) + +type TcpConsole struct { + conn *cmd.Connect + addr string + lock sync.Mutex + instance string + register *Register + listener *listener.Listener + lastConfig *manager.Value + + ctx context.Context + cancel context.CancelFunc + + listenOnce sync.Once +} + +func (c *TcpConsole) SendMonitor(data []byte) error { + + return c.conn.Send(cmd.Monitor, data) + +} + +func (c *TcpConsole) GetConfig() (*config.GokuConfig, error) { + conf, b := c.lastConfig.Get() + if b { + + return conf.(*config.GokuConfig), nil + } + return nil, errors.New("not register to console") +} + +func (c *TcpConsole) Close() { + c.cancel() +} + +func (c *TcpConsole) AddListen(callback console.ConfigCallbackFunc) { + c.listener.Listen(func(event interface{}) { + conf := event.(*config.GokuConfig) + callback(conf) + }) +} + +func NewConsole(addr string, instance string) *TcpConsole { + c := &TcpConsole{ + addr: addr, + instance: instance, + conn: nil, + register: NewRegister(), + listener: listener.New(), + + lastConfig: manager.NewValue(), + } + c.register.RegisterFunc(cmd.Config, c.OnConfigChange) + c.register.RegisterFunc(cmd.Restart, Restart) + c.register.RegisterFunc(cmd.Stop, Stop) + + return c +} + +func connect(addr string) net.Conn { + sleeps := []time.Duration{time.Second * 0, time.Second * 1, time.Second * 5, time.Second * 10} + maxSleep := sleeps[len(sleeps)-1] + retry := 0 + + for { + if retry > 0 { + if retry > len(sleeps)-1 { + time.Sleep(maxSleep) + } else { + time.Sleep(sleeps[retry]) + } + } + conn, err := net.Dial("tcp", addr) + if err != nil { + continue + } + return conn + } +} + +func (c *TcpConsole) RegisterToConsole() (*config.GokuConfig, error) { + data, err := cmd.EncodeRegister(c.instance) + if err != nil { + return nil, err + } + for { + + conn := connect(c.addr) + e := cmd.SendFrame(conn, cmd.NodeRegister, data) + if e != nil { + conn.Close() + continue + } + + frame, err := cmd.ReadFrame(conn) + + if err != nil { + conn.Close() + continue + } + + code, data, err := cmd.GetCmd(frame) + if err != nil { + conn.Close() + return nil, err + } + if code != cmd.NodeRegisterResult { + conn.Close() + return nil, ErrorNeedReadRegisterResult + } + + result, err := cmd.DecodeRegisterResult(data) + + if err != nil { + conn.Close() + return nil, err + } + if result.Code != 0 { + conn.Close() + return nil, errors.New(result.Error) + } + + c.conn = cmd.NewConnect(conn) + + return result.Config, nil + } +} +func (c *TcpConsole) Listen() { + + c.listenOnce.Do( + func() { + go func() { + for { + c.listenRead() + c.RegisterToConsole() + } + }() + }) + +} + +func (c *TcpConsole) listenRead() { + defer c.conn.Close() + for { + select { + case <-c.conn.Done(): + return + case frame, ok := <-c.conn.ReadC(): + { + if !ok { + return + } + + code, data, e := cmd.GetCmd(frame) + if e != nil { + return + } + + err := c.register.Callback(code, data) + if err != nil { + return + } + } + } + } +} diff --git a/admin/node/error.go b/admin/node/error.go new file mode 100644 index 0000000000000000000000000000000000000000..6fd0303043ad17a74d25601603cfdbc3e180291c --- /dev/null +++ b/admin/node/error.go @@ -0,0 +1,9 @@ +package node + +import "errors" + +var ( + ErrorReadRegisterResultTimeOut = errors.New("read register result timeout") + ErrorNeedReadRegisterResult = errors.New("need register-result but not") + ErrorConsoleRefuse = errors.New("console refuse") +) diff --git a/admin/node/register.go b/admin/node/register.go new file mode 100644 index 0000000000000000000000000000000000000000..2b4023a62f5ba71acbe18c727b306af17fc15baf --- /dev/null +++ b/admin/node/register.go @@ -0,0 +1 @@ +package node diff --git a/admin/node/restart.go b/admin/node/restart.go new file mode 100644 index 0000000000000000000000000000000000000000..d2dfd89e12fb44c1aab57354943af8bbc77423d0 --- /dev/null +++ b/admin/node/restart.go @@ -0,0 +1,21 @@ +package node + +import ( + goku_log "github.com/eolinker/goku-api-gateway/goku-log" + + "github.com/eolinker/goku-api-gateway/admin/cmd" +) + +func Restart(code cmd.Code, data []byte) error { + goku_log.Info("restart") + //endless.RestartServer() + + return nil +} + +func Stop(code cmd.Code, data []byte) error { + goku_log.Info("stop") + //endless.StopServer() + + return nil +} diff --git a/app/console/cluster.go b/app/console/cluster.go new file mode 100644 index 0000000000000000000000000000000000000000..12173adecac7cf11eafc87290595cea6c47f2625 --- /dev/null +++ b/app/console/cluster.go @@ -0,0 +1,44 @@ +package main + +import ( + "github.com/eolinker/goku-api-gateway/common/database" + "strconv" + + "github.com/pkg/errors" + + "github.com/eolinker/goku-api-gateway/common/conf" + "github.com/eolinker/goku-api-gateway/server/entity" +) + +func getDefaultDatabase() (*entity.ClusterDB, error) { + dbType := conf.MastValue("db_type", "sqlite3") + switch dbType { + case database.MysqlDriver: + { + dbPort, err := strconv.Atoi(conf.MastValue("db_port", "3306")) + if err != nil { + return nil, err + } + return &entity.ClusterDB{ + Driver: dbType, + Host: conf.Value("db_host"), + Port: dbPort, + UserName: conf.Value("db_user"), + Password: conf.Value("db_password"), + Database: conf.Value("db_name"), + }, nil + } + case database.Sqlite3Driver: + { + return &entity.ClusterDB{ + Driver: dbType, + Path: conf.MastValue("db_path", "./work/goku.db"), + }, nil + } + default: + { + return nil, errors.New("unsupported database type") + } + } + +} diff --git a/app/console/databse.go b/app/console/databse.go new file mode 100644 index 0000000000000000000000000000000000000000..db78484a5540f2bd19a766fcec00b9469cca0991 --- /dev/null +++ b/app/console/databse.go @@ -0,0 +1,64 @@ +package main + +import ( + "fmt" + "github.com/eolinker/goku-api-gateway/common/database" + "github.com/eolinker/goku-api-gateway/common/pdao" + console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" + "github.com/eolinker/goku-api-gateway/server/entity" +) + + + +//ClusterDatabaseConfig 集群数据库配置 +type ClusterDatabaseConfig entity.ClusterDB + +//GetDriver 获取驱动类型 +func (c *ClusterDatabaseConfig) GetDriver() string { + return c.Driver +} + +//GetSource 获取连接字符串 +func (c *ClusterDatabaseConfig) GetSource() string { + + switch c.Driver { + case database.MysqlDriver: + { + return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8", c.UserName, c.Password, c.Host, c.Port, c.Database) + } + case database.Sqlite3Driver: + { + return c.Path + } + default: + { + return "" + } + } + +} + +//InitDatabase 初始化数据库 +func InitDatabase() { + console_sqlite3.DoRegister() + + def, err := getDefaultDatabase() + if err != nil { + panic(err) + } + c := ClusterDatabaseConfig(*def) + db,e := database.InitConnection(&c) + if e != nil { + panic(e) + } + err =pdao.Build(c.GetDriver(),db) + if err!=nil{ + panic(err) + } + + err =pdao.Check() + if err!=nil{ + panic(err) + } +} + diff --git a/app/console/log.go b/app/console/log.go new file mode 100644 index 0000000000000000000000000000000000000000..8131b5f9952d65040d6fb5f9e3c16a873a81f908 --- /dev/null +++ b/app/console/log.go @@ -0,0 +1,16 @@ +package main + +import ( + module "github.com/eolinker/goku-api-gateway/console/module/config-log" + log "github.com/eolinker/goku-api-gateway/goku-log" +) + +//InitLog 初始化日志 +func InitLog() { + c, _ := module.Get(module.ConsoleLog) + + period, _ := log.ParsePeriod(c.Period) + log.SetOutPut(c.Enable, c.Dir, c.File, period, c.Expire) + l, _ := log.ParseLevel(c.Level) + log.SetLevel(l) +} diff --git a/app/console/main.go b/app/console/main.go index 05c82e0557507fa0d2664a6ec3624f591831aae7..0d587bbc688cee9b80414a64d9822757041b2ab5 100644 --- a/app/console/main.go +++ b/app/console/main.go @@ -2,13 +2,11 @@ package main import ( "flag" - - "github.com/eolinker/goku-api-gateway/console/module/account" log "github.com/eolinker/goku-api-gateway/goku-log" "github.com/eolinker/goku-api-gateway/common/conf" "github.com/eolinker/goku-api-gateway/common/general" - "github.com/eolinker/goku-api-gateway/console" + "github.com/eolinker/goku-api-gateway/console/module/account" "github.com/eolinker/goku-api-gateway/utils" ) @@ -33,21 +31,20 @@ func main() { log.Panic(err) return } + + // 初始化db - console.InitDatabase() - console.InitLog() + InitDatabase() + InitLog() - //console.InitClusters() // 其他需要初始化的模块 _ = general.General() // 检测是否安装 s, err := account.CheckSuperAdminCount() if err != nil { - err = console.InitTable() - if err != nil { log.Panic(err) return - } + } if s == 0 { if userName == "" { @@ -62,13 +59,13 @@ func main() { // 用户注册 password := utils.Md5(utils.Md5(userPassword)) - f := console.Register(userName, password) + f := account.Register(userName, password) if !f { log.Fatal("[ERROR] Fail to create administrator. Please try again or contact technical support of eoLinker GOKU API Gateway.") return } } - - console.Router() - console.Server() + Server() + //console.Router() + //console.Server() } diff --git a/app/console/module.go b/app/console/module.go new file mode 100644 index 0000000000000000000000000000000000000000..b2834c540aad1a0eb0690af1932c75d40d11c651 --- /dev/null +++ b/app/console/module.go @@ -0,0 +1,12 @@ +package main + +import ( + graphite "github.com/eolinker/goku-api-gateway/module/graphite/config" + prometheus "github.com/eolinker/goku-api-gateway/module/prometheus/config" +) + +func moduleRegister() { + prometheus.Register() + graphite.Register() + +} diff --git a/app/console/redis_config.go b/app/console/redis_config.go new file mode 100644 index 0000000000000000000000000000000000000000..06ab7d0f9a35a7d1070711496d6ca1cb892a258f --- /dev/null +++ b/app/console/redis_config.go @@ -0,0 +1 @@ +package main diff --git a/app/console/router.go b/app/console/router.go new file mode 100644 index 0000000000000000000000000000000000000000..43eca27301da5bd8c503437c9db3e76b29476df7 --- /dev/null +++ b/app/console/router.go @@ -0,0 +1,90 @@ +package main + +import ( + "net/http" + + account_default "github.com/eolinker/goku-api-gateway/console/account" + "github.com/eolinker/goku-api-gateway/console/controller/account" + "github.com/eolinker/goku-api-gateway/console/controller/api" + "github.com/eolinker/goku-api-gateway/console/controller/auth" + "github.com/eolinker/goku-api-gateway/console/controller/balance" + "github.com/eolinker/goku-api-gateway/console/controller/cluster" + config_log "github.com/eolinker/goku-api-gateway/console/controller/config-log" + "github.com/eolinker/goku-api-gateway/console/controller/discovery" + "github.com/eolinker/goku-api-gateway/console/controller/gateway" + "github.com/eolinker/goku-api-gateway/console/controller/monitor" + "github.com/eolinker/goku-api-gateway/console/controller/node" + "github.com/eolinker/goku-api-gateway/console/controller/plugin" + "github.com/eolinker/goku-api-gateway/console/controller/project" + "github.com/eolinker/goku-api-gateway/console/controller/strategy" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" +) + +var ( + accountFactory = goku_handler.NewAccountHandlerFactory(account_default.NewDefaultAccount()) +) + +func router() http.Handler { + s := goku_handler.NewGokuServer(accountFactory) + + // 账号管理模块 + s.Add("/guest", account.NewAccountController()) + s.Add("/user", account.NewUserController()) + + // 接口管理模块 + s.Add("/apis", api.NewAPIHandlers()) + s.Add("/apis/group", api.NewGroupHandlers()) + s.Add("/import/ams", api.NewImportHandlers()) + s.Add("/plugin/api", api.NewPluginHandlers()) + + // 鉴权模块 + s.Add("/auth", auth.NewHandlers()) + + // 负载模块 + s.Add("/balance", balance.NewHandlers()) + + // 集群模块 + s.Add("/cluster", cluster.NewHandlers()) + s.Add("/version/config", cluster.NewVersionHandlers()) + + // 日志配置模块 + s.Add("/config/log", config_log.NewHandlers()) + + // 服务发现模块 + s.Add("/balance/service", discovery.NewHandlers()) + + // 网关模块 + s.Add("/monitor/gateway", gateway.NewHandlers()) + + // 监控模块 + s.Add("/monitor/module/config", monitor.NewHandlers()) + + // 节点模块 + s.Add("/node", node.NewNodeHandlers()) + s.Add("/node/group", node.NewGroupHandlers()) + + // 插件模块 + s.Add("/plugin", plugin.NewHandlers()) + + // 项目模块 + s.Add("/project", project.NewHandlers()) + + // 策略模块 + s.Add("/strategy", strategy.NewStrategyHandlers()) + s.Add("/strategy/group", strategy.NewGroupHandlers()) + s.Add("/strategy/api", strategy.NewAPIStrategyHandlers()) + s.Add("/plugin/strategy", strategy.NewPluginHandlers()) + + // 前端接入 + s.Add("/", new(staticHandlers)) + return s +} + +type staticHandlers struct { +} + +func (s *staticHandlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/": http.StripPrefix("/", http.FileServer(http.Dir("./static"))), + } +} diff --git a/app/console/server.go b/app/console/server.go new file mode 100644 index 0000000000000000000000000000000000000000..375413c24ea461e1a1a9bde6a54c8ce7f5af5fd8 --- /dev/null +++ b/app/console/server.go @@ -0,0 +1,50 @@ +package main + +import ( + "log" + "net/http" + + "github.com/eolinker/goku-api-gateway/admin/console" + "github.com/eolinker/goku-api-gateway/common/conf" +) + +//Server 控制台服务 +func Server() { + moduleRegister() + bind, has := conf.Get("admin_bind") + if !has { + log.Panic("[ERROR] Illegal admin_bind!") + return + } + err := console.Start(bind) + if err != nil { + log.Fatal(err) + return + } + + ec := make(chan error, 1) + + port, has := conf.Get("listen_port") + if has { + go func() { + log.Print("Listen: ", port) + log.Print("Start Successfully!") + err := http.ListenAndServe(":7000", router()) + + ec <- err + }() + } else { + log.Panic("[ERROR] Illegal listen port!") + } + + for { + select { + case e, ok := <-ec: + if !ok { + break + } + log.Fatal(e) + } + + } +} diff --git a/app/node/driver.go b/app/node/driver.go index 88a81bee97c52eb37de396f064d19a65849ceb5d..38fb5c4e7cdb9313b48642147086de60c6bd284d 100644 --- a/app/node/driver.go +++ b/app/node/driver.go @@ -1,15 +1,13 @@ package main import ( - - "github.com/eolinker/goku-api-gateway/goku-service/driver/consul" - "github.com/eolinker/goku-api-gateway/goku-service/driver/eureka" - "github.com/eolinker/goku-api-gateway/goku-service/driver/static" - + "github.com/eolinker/goku-api-gateway/goku-service/driver/consul" + "github.com/eolinker/goku-api-gateway/goku-service/driver/eureka" + "github.com/eolinker/goku-api-gateway/goku-service/driver/static" ) func init() { consul.Register() eureka.Register() static.Register() -} \ No newline at end of file +} diff --git a/app/node/init.go b/app/node/init.go index ab81d2a91638e82cdfd0a664722a56c48e46f475..3b5b67f38af116e0add94831479ac98d48f3e13d 100644 --- a/app/node/init.go +++ b/app/node/init.go @@ -9,4 +9,4 @@ func init() { prometheus.Register() graphite.Register() -} \ No newline at end of file +} diff --git a/app/node/main.go b/app/node/main.go index 002d46f64dff3e2f8fbaf1057b0e6cc922154382..1e4c4ac3415f0e4f2d3eaa04866ba37e5794ad76 100644 --- a/app/node/main.go +++ b/app/node/main.go @@ -2,9 +2,9 @@ package main import ( "flag" + "github.com/eolinker/goku-api-gateway/admin/node" "github.com/eolinker/goku-api-gateway/config" log "github.com/eolinker/goku-api-gateway/goku-log" - console2 "github.com/eolinker/goku-api-gateway/node/console" "github.com/eolinker/goku-api-gateway/node/server" "runtime" ) @@ -20,7 +20,8 @@ func main() { if admin != "" && instance != ""{ - console := console2.NewConsole(instance, admin) + console := node.NewConsole(admin,instance) + ser := server.NewServer() log.Fatal(ser.ServerWidthConsole(console)) return diff --git a/build/cmd/build-console.sh b/build/cmd/build-console.sh index 74d01be28a30904593573122c5e9be49d588b312..b6811c259755bc42a1551670b1bb5eef04001b6a 100755 --- a/build/cmd/build-console.sh +++ b/build/cmd/build-console.sh @@ -12,7 +12,7 @@ OUTPATH="${BasePath}/out/console-${VERSION}" buildApp console $VERSION mkdir ${OUTPATH}/static -cp -a ${BasePath}/app/console/static/* ${OUTPATH}/static/ + cp -a ${BasePath}/build/console/resources/* ${OUTPATH}/ chmod +x ${OUTPATH}/install.sh ${OUTPATH}/run.sh diff --git a/build/console/.gitignore b/build/console/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..b6edfe90a45425683b592934cc4caf01f6284a8e --- /dev/null +++ b/build/console/.gitignore @@ -0,0 +1 @@ +/static/ diff --git a/build/console/resources/sql/goku_ce.sql b/build/console/resources/sql/goku_ce.sql index 6c143f500c3a2a05e7a44b451ccc7510a1dae8d9..0274ae698c080c4c1aab4f0313ce0b44942c04d6 100644 --- a/build/console/resources/sql/goku_ce.sql +++ b/build/console/resources/sql/goku_ce.sql @@ -5,13 +5,13 @@ PRAGMA foreign_keys = false; -- ---------------------------- DROP TABLE IF EXISTS "goku_admin"; CREATE TABLE "goku_admin" ( - "userID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "loginCall" text(255) NOT NULL, - "loginPassword" text(255) NOT NULL, - "userType" integer(4) NOT NULL DEFAULT 0, - "groupID" integer(11) NOT NULL DEFAULT 0, - "remark" text(255), - "permissions" text + "userID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "loginCall" text(255) NOT NULL, + "loginPassword" text(255) NOT NULL, + "userType" integer(4) NOT NULL DEFAULT 0, + "groupID" integer(11) NOT NULL DEFAULT 0, + "remark" text(255), + "permissions" text ); -- ---------------------------- @@ -19,18 +19,18 @@ CREATE TABLE "goku_admin" ( -- ---------------------------- DROP TABLE IF EXISTS "goku_balance"; CREATE TABLE "goku_balance" ( - "balanceID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "balanceName" text(255) NOT NULL, - "serviceName" text(255) NOT NULL, - "balanceConfig" text, - "createTime" text, - "updateTime" text, - "balanceDesc" text(255), - "defaultConfig" text NOT NULL, - "clusterConfig" text NOT NULL DEFAULT '', - "appName" text(255) NOT NULL DEFAULT '', - "static" text, - "staticCluster" text + "balanceID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "balanceName" text(255) NOT NULL, + "serviceName" text(255) NOT NULL, + "balanceConfig" text, + "createTime" text, + "updateTime" text, + "balanceDesc" text(255), + "defaultConfig" text NOT NULL, + "clusterConfig" text NOT NULL DEFAULT '', + "appName" text(255) NOT NULL DEFAULT '', + "static" text, + "staticCluster" text ); -- ---------------------------- @@ -38,12 +38,12 @@ CREATE TABLE "goku_balance" ( -- ---------------------------- DROP TABLE IF EXISTS "goku_cluster"; CREATE TABLE "goku_cluster" ( - "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "name" text(20) NOT NULL, - "title" text(50) NOT NULL, - "note" text(255), - "db" text, - "redis" text + "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "name" text(20) NOT NULL, + "title" text(50) NOT NULL, + "note" text(255), + "db" text, + "redis" text ); -- ---------------------------- @@ -51,15 +51,15 @@ CREATE TABLE "goku_cluster" ( -- ---------------------------- DROP TABLE IF EXISTS "goku_config_log"; CREATE TABLE "goku_config_log" ( - "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "name" text(20) NOT NULL, - "enable" integer(11) NOT NULL DEFAULT 1, - "dir" text(255) NOT NULL, - "file" text(255) NOT NULL, - "period" text(10) NOT NULL, - "level" text(10) NOT NULL, - "fields" text NOT NULL, - "expire" integer(11) NOT NULL DEFAULT 3 + "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "name" text(20) NOT NULL, + "enable" integer(11) NOT NULL DEFAULT 1, + "dir" text(255) NOT NULL, + "file" text(255) NOT NULL, + "period" text(10) NOT NULL, + "level" text(10) NOT NULL, + "fields" text NOT NULL, + "expire" integer(11) NOT NULL DEFAULT 3 ); -- ---------------------------- @@ -67,17 +67,17 @@ CREATE TABLE "goku_config_log" ( -- ---------------------------- DROP TABLE IF EXISTS "goku_conn_plugin_api"; CREATE TABLE "goku_conn_plugin_api" ( - "connID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "apiID" integer(11) NOT NULL, - "pluginName" text(255) NOT NULL, - "pluginConfig" text, - "strategyID" text(255) NOT NULL, - "pluginInfo" text, - "createTime" text, - "updateTime" text, - "pluginStatus" integer(4), - "updateTag" text(32), - "updaterID" integer(11) NOT NULL DEFAULT 0 + "connID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "apiID" integer(11) NOT NULL, + "pluginName" text(255) NOT NULL, + "pluginConfig" text, + "strategyID" text(255) NOT NULL, + "pluginInfo" text, + "createTime" text, + "updateTime" text, + "pluginStatus" integer(4), + "updateTag" text(32), + "updaterID" integer(11) NOT NULL DEFAULT 0 ); -- ---------------------------- @@ -85,16 +85,16 @@ CREATE TABLE "goku_conn_plugin_api" ( -- ---------------------------- DROP TABLE IF EXISTS "goku_conn_plugin_strategy"; CREATE TABLE "goku_conn_plugin_strategy" ( - "connID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "strategyID" text(255) NOT NULL, - "pluginName" text(255) NOT NULL, - "pluginConfig" text, - "pluginInfo" text, - "createTime" text, - "updateTime" text, - "pluginStatus" integer(4), - "updateTag" text(32), - "updaterID" integer(11) NOT NULL DEFAULT 0 + "connID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "strategyID" text(255) NOT NULL, + "pluginName" text(255) NOT NULL, + "pluginConfig" text, + "pluginInfo" text, + "createTime" text, + "updateTime" text, + "pluginStatus" integer(4), + "updateTag" text(32), + "updaterID" integer(11) NOT NULL DEFAULT 0 ); -- ---------------------------- @@ -102,13 +102,13 @@ CREATE TABLE "goku_conn_plugin_strategy" ( -- ---------------------------- DROP TABLE IF EXISTS "goku_conn_strategy_api"; CREATE TABLE "goku_conn_strategy_api" ( - "connID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "strategyID" text(255) NOT NULL, - "apiID" integer(11) NOT NULL, - "apiMonitorStatus" integer(11) NOT NULL DEFAULT 0, - "strategyMonitorStatus" integer(11) NOT NULL DEFAULT 0, - "target" text(255), - "updateTime" text + "connID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "strategyID" text(255) NOT NULL, + "apiID" integer(11) NOT NULL, + "apiMonitorStatus" integer(11) NOT NULL DEFAULT 0, + "strategyMonitorStatus" integer(11) NOT NULL DEFAULT 0, + "target" text(255), + "updateTime" text ); -- ---------------------------- @@ -116,26 +116,26 @@ CREATE TABLE "goku_conn_strategy_api" ( -- ---------------------------- DROP TABLE IF EXISTS "goku_gateway"; CREATE TABLE "goku_gateway" ( - "id" integer(11) NOT NULL, - "successCode" text(255) NOT NULL, - "nodeUpdatePeriod" integer(11) NOT NULL, - "monitorUpdatePeriod" integer(11) NOT NULL, - "alertStatus" integer(4) NOT NULL, - "alertPeriodType" integer(4) NOT NULL, - "alertAddress" text(255), - "alertLogPath" text(255), - "sender" text(255), - "senderPassword" text(255), - "smtpAddress" text(255), - "smtpPort" integer(11) NOT NULL, - "smtpProtocol" integer(4) NOT NULL, - "receiverList" text(255), - "monitorTimeout" integer(4) NOT NULL, - "apiAlertInfo" text, - "nodeAlertInfo" text, - "redisAlertInfo" text, - "versionID" INTEGER NOT NULL DEFAULT 0, - PRIMARY KEY ("id") + "id" integer(11) NOT NULL, + "successCode" text(255) NOT NULL, + "nodeUpdatePeriod" integer(11) NOT NULL, + "monitorUpdatePeriod" integer(11) NOT NULL, + "alertStatus" integer(4) NOT NULL, + "alertPeriodType" integer(4) NOT NULL, + "alertAddress" text(255), + "alertLogPath" text(255), + "sender" text(255), + "senderPassword" text(255), + "smtpAddress" text(255), + "smtpPort" integer(11) NOT NULL, + "smtpProtocol" integer(4) NOT NULL, + "receiverList" text(255), + "monitorTimeout" integer(4) NOT NULL, + "apiAlertInfo" text, + "nodeAlertInfo" text, + "redisAlertInfo" text, + "versionID" INTEGER NOT NULL DEFAULT 0, + PRIMARY KEY ("id") ); INSERT INTO "goku_gateway" VALUES (1, 200, 1, 30, 0, 0, NULL, NULL, NULL, NULL, NULL, 25, 0, NULL, 0, NULL, NULL, NULL, 0); @@ -145,15 +145,15 @@ INSERT INTO "goku_gateway" VALUES (1, 200, 1, 30, 0, 0, NULL, NULL, NULL, NULL, -- ---------------------------- DROP TABLE IF EXISTS "goku_gateway_alert"; CREATE TABLE "goku_gateway_alert" ( - "alertID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "requestURL" text(255) NOT NULL, - "targetServer" text(255) NOT NULL, - "alertPeriodType" integer(4) NOT NULL, - "alertCount" integer(11) NOT NULL, - "updateTime" text, - "targetURL" text(255) NOT NULL, - "clusterName" text(255), - "nodeIP" text(255) + "alertID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "requestURL" text(255) NOT NULL, + "targetServer" text(255) NOT NULL, + "alertPeriodType" integer(4) NOT NULL, + "alertCount" integer(11) NOT NULL, + "updateTime" text, + "targetURL" text(255) NOT NULL, + "clusterName" text(255), + "nodeIP" text(255) ); -- ---------------------------- @@ -161,33 +161,34 @@ CREATE TABLE "goku_gateway_alert" ( -- ---------------------------- DROP TABLE IF EXISTS "goku_gateway_api"; CREATE TABLE "goku_gateway_api" ( - "apiID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "groupID" integer(11) NOT NULL, - "projectID" integer(11) NOT NULL, - "requestURL" text(255) NOT NULL, - "apiName" text(255) NOT NULL, - "requestMethod" text(255) NOT NULL, - "targetServer" text(255), - "targetURL" text(255), - "targetMethod" text(255), - "isFollow" text(32) NOT NULL, - "stripPrefix" text(32), - "timeout" integer(11), - "retryCount" integer(11), - "createTime" text, - "updateTime" text, - "alertValve" integer(11) NOT NULL DEFAULT 0, - "monitorStatus" integer(11) NOT NULL DEFAULT 1, - "managerID" integer(11) NOT NULL, - "lastUpdateUserID" integer(11) NOT NULL, - "createUserID" integer(11) NOT NULL, - "balanceName" text(255), - "protocol" text(20), - "stripSlash" text(32), - "apiType" integer NOT NULL DEFAULT 0, - "responseDataType" text NOT NULL DEFAULT origin, - "linkApis" TEXT, - "staticResponse" TEXT + "apiID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "groupID" integer(11) NOT NULL, + "projectID" integer(11) NOT NULL, + "requestURL" text(255) NOT NULL, + "apiName" text(255) NOT NULL, + "alias" text(255), + "requestMethod" text(255) NOT NULL, + "targetServer" text(255), + "targetURL" text(255), + "targetMethod" text(255), + "isFollow" text(32) NOT NULL, + "stripPrefix" text(32), + "timeout" integer(11), + "retryCount" integer(11), + "createTime" text, + "updateTime" text, + "alertValve" integer(11) NOT NULL DEFAULT 0, + "monitorStatus" integer(11) NOT NULL DEFAULT 1, + "managerID" integer(11) NOT NULL, + "lastUpdateUserID" integer(11) NOT NULL, + "createUserID" integer(11) NOT NULL, + "balanceName" text(255), + "protocol" text(20), + "stripSlash" text(32), + "apiType" integer NOT NULL DEFAULT 0, + "responseDataType" text NOT NULL DEFAULT origin, + "linkApis" TEXT, + "staticResponse" TEXT ); -- ---------------------------- @@ -195,12 +196,12 @@ CREATE TABLE "goku_gateway_api" ( -- ---------------------------- DROP TABLE IF EXISTS "goku_gateway_api_group"; CREATE TABLE "goku_gateway_api_group" ( - "groupID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "projectID" integer(11) NOT NULL, - "groupName" text(255) NOT NULL, - "groupPath" text(255), - "groupDepth" text(255), - "parentGroupID" integer(11) NOT NULL DEFAULT 0 + "groupID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "projectID" integer(11) NOT NULL, + "groupName" text(255) NOT NULL, + "groupPath" text(255), + "groupDepth" text(255), + "parentGroupID" integer(11) NOT NULL DEFAULT 0 ); -- ---------------------------- @@ -208,9 +209,9 @@ CREATE TABLE "goku_gateway_api_group" ( -- ---------------------------- DROP TABLE IF EXISTS "goku_gateway_permission_group"; CREATE TABLE "goku_gateway_permission_group" ( - "groupID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "groupName" text(255) NOT NULL, - "permissions" text + "groupID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "groupName" text(255) NOT NULL, + "permissions" text ); -- ---------------------------- @@ -218,10 +219,10 @@ CREATE TABLE "goku_gateway_permission_group" ( -- ---------------------------- DROP TABLE IF EXISTS "goku_gateway_project"; CREATE TABLE "goku_gateway_project" ( - "projectID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "projectName" text(255) NOT NULL, - "createTime" text, - "updateTime" text + "projectID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "projectName" text(255) NOT NULL, + "createTime" text, + "updateTime" text ); -- ---------------------------- @@ -229,16 +230,16 @@ CREATE TABLE "goku_gateway_project" ( -- ---------------------------- DROP TABLE IF EXISTS "goku_gateway_strategy"; CREATE TABLE "goku_gateway_strategy" ( - "strategyID" text(32) NOT NULL, - "strategyName" text(255) NOT NULL, - "updateTime" text, - "createTime" text, - "auth" text(255), - "groupID" integer(11) NOT NULL DEFAULT 0, - "monitorStatus" integer(4) NOT NULL DEFAULT 0, - "enableStatus" integer(11) NOT NULL DEFAULT 0, - "strategyType" integer(11) NOT NULL DEFAULT 0, - PRIMARY KEY ("strategyID") + "strategyID" text(32) NOT NULL, + "strategyName" text(255) NOT NULL, + "updateTime" text, + "createTime" text, + "auth" text(255), + "groupID" integer(11) NOT NULL DEFAULT 0, + "monitorStatus" integer(4) NOT NULL DEFAULT 0, + "enableStatus" integer(11) NOT NULL DEFAULT 0, + "strategyType" integer(11) NOT NULL DEFAULT 0, + PRIMARY KEY ("strategyID") ); -- ---------------------------- @@ -251,9 +252,9 @@ INSERT INTO "goku_gateway_strategy" VALUES ('RGAtKBd', '开放策略', '2019-10- -- ---------------------------- DROP TABLE IF EXISTS "goku_gateway_strategy_group"; CREATE TABLE "goku_gateway_strategy_group" ( - "groupID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "groupName" text(255) NOT NULL, - "groupType" integer(11) NOT NULL DEFAULT 0 + "groupID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "groupName" text(255) NOT NULL, + "groupType" integer(11) NOT NULL DEFAULT 0 ); -- ---------------------------- @@ -266,16 +267,16 @@ INSERT INTO "goku_gateway_strategy_group" VALUES (1, '开放分组', 1); -- ---------------------------- DROP TABLE IF EXISTS "goku_gateway_version_config"; CREATE TABLE "goku_gateway_version_config" ( - "versionID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "name" TEXT NOT NULL, - "version" TEXT, - "remark" TEXT, - "createTime" TEXT, - "updateTime" TEXT, - "publishTime" TEXT, - "config" TEXT, - "balanceConfig" TEXT, - "discoverConfig" TEXT + "versionID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "name" TEXT NOT NULL, + "version" TEXT, + "remark" TEXT, + "createTime" TEXT, + "updateTime" TEXT, + "publishTime" TEXT, + "config" TEXT, + "balanceConfig" TEXT, + "discoverConfig" TEXT ); -- ---------------------------- @@ -283,23 +284,23 @@ CREATE TABLE "goku_gateway_version_config" ( -- ---------------------------- DROP TABLE IF EXISTS "goku_monitor_cluster"; CREATE TABLE "goku_monitor_cluster" ( - "recordID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "strategyID" text(20) NOT NULL, - "apiID" integer(11) NOT NULL, - "clusterID" integer(11) NOT NULL, - "hour" integer(11) NOT NULL, - "gatewayRequestCount" integer(11) NOT NULL, - "gatewaySuccessCount" integer(11) NOT NULL, - "gatewayStatus2xxCount" integer(11) NOT NULL, - "gatewayStatus4xxCount" integer(11) NOT NULL, - "gatewayStatus5xxCount" integer(11) NOT NULL, - "proxyRequestCount" integer(11) NOT NULL, - "proxySuccessCount" integer(11) NOT NULL, - "proxyStatus2xxCount" integer(11) NOT NULL, - "proxyStatus4xxCount" integer(11) NOT NULL, - "proxyStatus5xxCount" integer(11) NOT NULL, - "proxyTimeoutCount" integer(11) NOT NULL, - "updateTime" text NOT NULL + "recordID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "strategyID" text(20) NOT NULL, + "apiID" integer(11) NOT NULL, + "clusterID" integer(11) NOT NULL, + "hour" integer(11) NOT NULL, + "gatewayRequestCount" integer(11) NOT NULL, + "gatewaySuccessCount" integer(11) NOT NULL, + "gatewayStatus2xxCount" integer(11) NOT NULL, + "gatewayStatus4xxCount" integer(11) NOT NULL, + "gatewayStatus5xxCount" integer(11) NOT NULL, + "proxyRequestCount" integer(11) NOT NULL, + "proxySuccessCount" integer(11) NOT NULL, + "proxyStatus2xxCount" integer(11) NOT NULL, + "proxyStatus4xxCount" integer(11) NOT NULL, + "proxyStatus5xxCount" integer(11) NOT NULL, + "proxyTimeoutCount" integer(11) NOT NULL, + "updateTime" text NOT NULL ); -- ---------------------------- @@ -307,10 +308,10 @@ CREATE TABLE "goku_monitor_cluster" ( -- ---------------------------- DROP TABLE IF EXISTS "goku_node_group"; CREATE TABLE "goku_node_group" ( - "groupID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "groupName" text(255) NOT NULL, - "groupType" integer(4) NOT NULL, - "clusterID" integer(11) NOT NULL + "groupID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "groupName" text(255) NOT NULL, + "groupType" integer(4) NOT NULL, + "clusterID" integer(11) NOT NULL ); -- ---------------------------- @@ -318,23 +319,23 @@ CREATE TABLE "goku_node_group" ( -- ---------------------------- DROP TABLE IF EXISTS "goku_node_info"; CREATE TABLE "goku_node_info" ( - "nodeID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "nodeIP" text(255) NOT NULL, - "updateStatus" integer(4) NOT NULL DEFAULT 0, - "createTime" text, - "updateTime" text, - "groupID" integer(11) NOT NULL DEFAULT 0, - "nodeName" text(255) NOT NULL, - "nodePort" text(255), - "nodeStatus" integer(11) NOT NULL, - "version" text(255), - "sshPort" text(255) DEFAULT 22, - "userName" text(255), - "password" text(255), - "gatewayPath" text(255), - "key" text, - "authMethod" integer(4) NOT NULL DEFAULT 0, - "clusterID" integer(11) NOT NULL DEFAULT 0 + "nodeID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "nodeIP" text(255) NOT NULL, + "updateStatus" integer(4) NOT NULL DEFAULT 0, + "createTime" text, + "updateTime" text, + "groupID" integer(11) NOT NULL DEFAULT 0, + "nodeName" text(255) NOT NULL, + "nodePort" text(255), + "nodeStatus" integer(11) NOT NULL, + "version" text(255), + "sshPort" text(255) DEFAULT 22, + "userName" text(255), + "password" text(255), + "gatewayPath" text(255), + "key" text, + "authMethod" integer(4) NOT NULL DEFAULT 0, + "clusterID" integer(11) NOT NULL DEFAULT 0 ); -- ---------------------------- @@ -342,19 +343,19 @@ CREATE TABLE "goku_node_info" ( -- ---------------------------- DROP TABLE IF EXISTS "goku_plugin"; CREATE TABLE "goku_plugin" ( - "pluginID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "pluginName" text(255) NOT NULL, - "chineseName" text(255), - "pluginStatus" integer(4) NOT NULL, - "pluginPriority" integer(4) NOT NULL, - "pluginConfig" text, - "pluginInfo" text, - "isStop" integer(4) NOT NULL, - "pluginType" integer(4) NOT NULL, - "official" text(255) NOT NULL, - "pluginDesc" text(255), - "version" text(255) NOT NULL, - "isCheck" integer(4) NOT NULL + "pluginID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "pluginName" text(255) NOT NULL, + "chineseName" text(255), + "pluginStatus" integer(4) NOT NULL, + "pluginPriority" integer(4) NOT NULL, + "pluginConfig" text, + "pluginInfo" text, + "isStop" integer(4) NOT NULL, + "pluginType" integer(4) NOT NULL, + "official" text(255) NOT NULL, + "pluginDesc" text(255), + "version" text(255) NOT NULL, + "isCheck" integer(4) NOT NULL ); @@ -363,20 +364,20 @@ CREATE TABLE "goku_plugin" ( -- ---------------------------- DROP TABLE IF EXISTS "goku_service_config"; CREATE TABLE "goku_service_config" ( - "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "name" text(255) NOT NULL, - "default" integer(4), - "driver" text(20) NOT NULL, - "desc" text NOT NULL, - "config" text NOT NULL, - "clusterConfig" text NOT NULL, - "healthCheck" integer(4) NOT NULL, - "healthCheckPath" text(255) NOT NULL, - "healthCheckPeriod" integer(11) NOT NULL, - "healthCheckCode" text(255) NOT NULL, - "healthCheckTimeOut" integer(11) NOT NULL, - "createTime" text NOT NULL, - "updateTime" text NOT NULL + "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "name" text(255) NOT NULL, + "default" integer(4), + "driver" text(20) NOT NULL, + "desc" text NOT NULL, + "config" text NOT NULL, + "clusterConfig" text NOT NULL, + "healthCheck" integer(4) NOT NULL, + "healthCheckPath" text(255) NOT NULL, + "healthCheckPeriod" integer(11) NOT NULL, + "healthCheckCode" text(255) NOT NULL, + "healthCheckTimeOut" integer(11) NOT NULL, + "createTime" text NOT NULL, + "updateTime" text NOT NULL ); -- ---------------------------- @@ -384,14 +385,14 @@ CREATE TABLE "goku_service_config" ( -- ---------------------------- DROP TABLE IF EXISTS "goku_service_discovery"; CREATE TABLE "goku_service_discovery" ( - "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, - "name" text(30), - "type" text(20), - "remark" text(500), - "config" text, - "default" text(255), - "createTime" text, - "updateTime" text + "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "name" text(30), + "type" text(20), + "remark" text(500), + "config" text, + "default" text(255), + "createTime" text, + "updateTime" text ); -- ---------------------------- @@ -399,9 +400,9 @@ CREATE TABLE "goku_service_discovery" ( -- ---------------------------- DROP TABLE IF EXISTS "goku_table_update_record"; CREATE TABLE "goku_table_update_record" ( - "name" text(64) NOT NULL, - "updateTime" text NOT NULL, - "tableID" integer NOT NULL PRIMARY KEY AUTOINCREMENT + "name" text(64) NOT NULL, + "updateTime" text NOT NULL, + "tableID" integer NOT NULL PRIMARY KEY AUTOINCREMENT ); @@ -427,17 +428,17 @@ UPDATE "sqlite_sequence" SET seq = 1 WHERE name = 'goku_admin'; -- Indexes structure for table goku_balance -- ---------------------------- CREATE INDEX "balanceName" - ON "goku_balance" ( - "balanceName" ASC - ); +ON "goku_balance" ( + "balanceName" ASC +); -- ---------------------------- -- Indexes structure for table goku_cluster -- ---------------------------- CREATE INDEX "name" - ON "goku_cluster" ( - "name" ASC - ); +ON "goku_cluster" ( + "name" ASC +); -- ---------------------------- -- Auto increment value for goku_config_log diff --git a/build/node/resources/run.sh b/build/node/resources/run.sh index c08bf731476ecae72cd59acef7199fecbce2822b..273c35f5fe5efd0cf9aef0efa1c0fe942b3a22a0 100644 --- a/build/node/resources/run.sh +++ b/build/node/resources/run.sh @@ -26,34 +26,32 @@ start() { ADMIN=$1 INSTANCE=$2 - - if [[ "INSTANCE" = "" ]] ;then - PORT=${ENV_INSTANCE} + CONFIG_PATH=$WORK_PATH/goku-node.json + RUN_MODEL="console" + if [ -f "$CONFIG_PATH" ]; then + RUN_MODEL="config" fi if [[ "$ADMIN" = "" ]] ; then ADMIN=${ENV_ADMIN} fi + + if [[ "$INSTANCE" = "" ]]; then + INSTANCE = ${ENV_INSTANCE} + fi - if [[ "$ADMIN" = "" ]] ; then + if [[ "$ADMIN" == "" && "$RUN_MODEL" == "console" ]] ; then echo "start fail :need admin url" exit 1 fi mkdir -p $WORK_PATH/logs echo -e "ENV_PORT=$PORT\nENV_ADMIN=$ADMIN" > $WORK_PATH/$PROG.env - - if [[ -e "$WORK_PATH/$PROG.pid" ]]; then - ## Program is running, exit with error. - echo "Error! $PROG is currently running!" 1>&2 - exit 1 - else - time=$(date "+%Y%m%d-%H%M%S") - ## Change from /dev/null to something like /var/log/$PROG if you want to save output. - nohup $PROG_PATH/$PROG --instance=$INSTANCE --admin=$ADMIN 2>&1 >"$WORK_PATH/logs/stdout-$PROG-$time.log" & pid=$! - - echo "$PROG started" - echo $pid > "$WORK_PATH/$PROG.pid" + + if [[ "$ADMIN" != "NULL" ]]; then + $PROG_PATH/$PROG --admin=$ADMIN --instance=$INSTANCE + else + $PROG_PATH/$PROG --config=$CONFIG_PATH fi } @@ -104,3 +102,4 @@ case "$1" in exit 1 ;; esac + diff --git a/common/database/conn.go b/common/database/conn.go index 1a57a29acfcd22741fd82782c1f9a493169ddf80..16f1d91a26a4c6f0dd94dff0e2f2a45024d4060f 100644 --- a/common/database/conn.go +++ b/common/database/conn.go @@ -2,8 +2,6 @@ package database import ( "database/sql" - "io/ioutil" - "strings" log "github.com/eolinker/goku-api-gateway/goku-log" @@ -13,15 +11,9 @@ import ( _ "github.com/mattn/go-sqlite3" ) -var ( - defaultDB *sql.DB -) - //InitConnection 初始化数据库连接 -func InitConnection(config Config) error { - db, e := getConnection(config) - defaultDB = db - return e +func InitConnection(config Config) (*sql.DB, error) { + return getConnection(config) } func getConnection(config Config) (*sql.DB, error) { @@ -34,7 +26,6 @@ func getConnection(config Config) (*sql.DB, error) { } db.SetMaxOpenConns(1000) db.SetMaxIdleConns(100) - defaultDB = db return db, nil } log.Info(e) @@ -42,25 +33,17 @@ func getConnection(config Config) (*sql.DB, error) { } -//GetConnection 获取数据库连接 -func GetConnection() *sql.DB { - return defaultDB -} - -//InitTable 初始化表 -func InitTable() error { +//CheckConnection 检查数据库连接 +func CheckConnection(driver string, source string) error { - content, err := ioutil.ReadFile("sql/goku_ce.sql") - sqls := strings.Split(string(content), ";") - Tx, _ := GetConnection().Begin() - for _, sql := range sqls { - _, err = Tx.Exec(sql) - if err != nil { - Tx.Rollback() - log.Error("InitTable error:",err,"\t sql:",sql) + db, e := sql.Open(driver, source) + defer db.Close() + if e == nil { + if err := db.Ping(); err != nil { return err } + return nil } - Tx.Commit() - return nil + return e + } diff --git a/common/database/database.go b/common/database/database.go index 2cb4da111131060d810b13f6654619dffa522d41..8777ad6fb164f13ada5099511deab48aa127a834 100644 --- a/common/database/database.go +++ b/common/database/database.go @@ -1,5 +1,12 @@ package database +const ( + //MysqlDriver mysql驱动器 + MysqlDriver = "mysql" + //Sqlite3Driver Sqlite3Driver驱动 + Sqlite3Driver = "sqlite3" +) + //Config 数据库配置结构体 type Config interface { GetDriver() string diff --git a/common/endless/endless.go b/common/endless/endless.go index ae63fba279a8d3debf8f8abbe0a3752585ddf1d2..9909a3eaee691ab286cb11d229121c715cef566b 100644 --- a/common/endless/endless.go +++ b/common/endless/endless.go @@ -4,7 +4,6 @@ import ( "crypto/tls" "errors" "fmt" - log "github.com/eolinker/goku-api-gateway/goku-log" "net" "net/http" "os" @@ -15,6 +14,8 @@ import ( "sync" "syscall" "time" + + log "github.com/eolinker/goku-api-gateway/goku-log" ) const ( @@ -39,9 +40,10 @@ var ( DefaultMaxHeaderBytes int DefaultHammerTime time.Duration - isChild bool - socketOrder string - + isChild bool + socketOrder string + adminServer *endlessServer + nodeServer *endlessServer hookableSignals []os.Signal ) @@ -71,15 +73,24 @@ func init() { type endlessServer struct { http.Server - EndlessListener net.Listener - SignalHooks map[int]map[os.Signal][]func() - tlsInnerListener *endlessListener - wg sync.WaitGroup - sigChan chan os.Signal - isChild bool - state uint8 - lock *sync.RWMutex - BeforeBegin func(add string) + EndlessListener net.Listener + SignalHooks map[int]map[os.Signal][]func() + tlsInnerListener *endlessListener + wg sync.WaitGroup + sigChan chan os.Signal + isChild bool + state uint8 + lock *sync.RWMutex + BeforeBegin func(add string) + runningServersForked bool +} + +func SetAdminServer(server *endlessServer) { + adminServer = server +} + +func SetNodeServer(server *endlessServer) { + nodeServer = server } /* @@ -140,17 +151,25 @@ func NewServer(addr string, handler http.Handler) (srv *endlessServer) { runningServersOrder = append(runningServersOrder, addr) runningServers[addr] = srv - return } -/* +func RestartServer() { + nodeServer.sigChan <- syscall.SIGHUP +} + +func StopServer() { + nodeServer.sigChan <- syscall.SIGTERM +} + +/*F ListenAndServe listens on the TCP network address addr and then calls Serve with handler to handle requests on incoming connections. Handler is typically nil, in which case the DefaultServeMux is used. */ func ListenAndServe(addr string, handler http.Handler) error { server := NewServer(addr, handler) + nodeServer = server return server.ListenAndServe() } @@ -338,7 +357,7 @@ func (srv *endlessServer) handleSignals() { log.Info(pid, "Received SIGINT.") srv.shutdown() case syscall.SIGTERM: - log.Info(pid, "Received SIGTERM.") + log.Info(``, "Received SIGTERM.") srv.shutdown() case syscall.SIGTSTP: log.Info(pid, "Received SIGTSTP.") @@ -418,15 +437,15 @@ func (srv *endlessServer) hammerTime(d time.Duration) { func (srv *endlessServer) fork() (err error) { - runningServerReg.Lock() defer runningServerReg.Unlock() + log.Info(1234) // only one server instance should fork! - if runningServersForked { + if srv.runningServersForked { return errors.New("Another process already forked. Ignoring this one.") } - - runningServersForked = true + log.Info(5456) + srv.runningServersForked = true var files = make([]*os.File, len(runningServers)) var orderArgs = make([]string, len(runningServers)) @@ -443,7 +462,7 @@ func (srv *endlessServer) fork() (err error) { } orderArgs[socketPtrOffsetMap[srvPtr.Server.Addr]] = srvPtr.Server.Addr } - + log.Info(123) env := append( os.Environ(), "ENDLESS_CONTINUE=1", @@ -458,7 +477,7 @@ func (srv *endlessServer) fork() (err error) { if len(os.Args) > 1 { args = os.Args[1:] } - + log.Info(path, args) cmd := exec.Command(path, args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr @@ -476,6 +495,7 @@ func (srv *endlessServer) fork() (err error) { log.Fatalf("Restart: Failed to launch, error: %v", err) } + srv.runningServersForked = false return } diff --git a/common/ioutils/utils.go b/common/ioutils/utils.go new file mode 100644 index 0000000000000000000000000000000000000000..a0e1c374513fdc32df9fe71bcc542344cfa384af --- /dev/null +++ b/common/ioutils/utils.go @@ -0,0 +1,44 @@ +package ioutils + +import ( + "encoding/binary" + "io" +) + +//WriteLField 写域内容 +func WriteLField(writer io.Writer, s []byte) (int, error) { + + l := uint8(len(s)) + + e := binary.Write(writer, binary.BigEndian, l) + if e != nil { + return 0, e + } + n, err := writer.Write(s) + if err != nil { + return n + 1, err + } + return n + 1, nil +} + +//ReadLField 读取域内容 +func ReadLField(reader io.Reader, buf []byte) ([]byte, int, error) { + l := uint8(0) + + e := binary.Read(reader, binary.BigEndian, &l) + if e != nil { + return nil, 0, e + } + tmpbuf := buf + if int(l) > len(buf) { + tmpbuf = make([]byte, l, l) + } else { + tmpbuf = buf[:l] + } + + _, err := reader.Read(tmpbuf) + if err != nil { + return nil, 0, err + } + return tmpbuf, int(l) + 1, nil +} diff --git a/common/listener/intercept.go b/common/listener/intercept.go new file mode 100644 index 0000000000000000000000000000000000000000..dbf5f5093cc994d35816fc6a8947116e999f8f16 --- /dev/null +++ b/common/listener/intercept.go @@ -0,0 +1,43 @@ +package listener + +import "sync" + +//InterceptFunc 拦截函数 +type InterceptFunc func(event interface{}) error + +//Intercept 拦截器 +type Intercept struct { + callbacks []InterceptFunc + locker sync.RWMutex +} + +//NewIntercept 创建拦截器 +func NewIntercept() *Intercept { + return &Intercept{ + callbacks: nil, + locker: sync.RWMutex{}, + } +} + +//Add add +func (i *Intercept) Add(f func(v interface{}) error) { + i.locker.Lock() + i.callbacks = append(i.callbacks, InterceptFunc(f)) + i.locker.Unlock() +} + +//Call call +func (i *Intercept) Call(v interface{}) error { + i.locker.RLock() + fs := i.callbacks + i.locker.RUnlock() + + for _, f := range fs { + err := f(v) + if err != nil { + + return err + } + } + return nil +} diff --git a/common/listener/listener.go b/common/listener/listener.go index 7a06c9b374379f02601f11d4c214fd4113d292a4..3eab1a5e252b1784d4fcde70677882c03018714f 100644 --- a/common/listener/listener.go +++ b/common/listener/listener.go @@ -5,7 +5,7 @@ import "sync" //CallbackFunc 回调函数 type CallbackFunc func(event interface{}) -//Listener +//Listener 监听者 type Listener struct { callbacks []CallbackFunc callbacksOnce []CallbackFunc diff --git a/common/manager/manager.go b/common/manager/manager.go new file mode 100644 index 0000000000000000000000000000000000000000..e3c40ead8d4273f0b046c39033de2ecd3491bada --- /dev/null +++ b/common/manager/manager.go @@ -0,0 +1,67 @@ +package manager + +import "sync" + +//Manager manager +type Manager struct { + locker sync.RWMutex + objs map[string]interface{} +} + +//NewManager new manager +func NewManager() *Manager { + return &Manager{ + locker: sync.RWMutex{}, + objs: make(map[string]interface{}), + } +} + +//Get get +func (m *Manager) Get(key string) (interface{}, bool) { + + m.locker.RLock() + v, has := m.objs[key] + m.locker.RUnlock() + return v, has +} + +//Set set +func (m *Manager) Set(key string, value interface{}) { + m.locker.Lock() + m.objs[key] = value + m.locker.Unlock() +} + +//Value value +type Value struct { + locker sync.RWMutex + isHas bool + value interface{} +} + +//NewValue new value +func NewValue() *Value { + return &Value{ + locker: sync.RWMutex{}, + isHas: false, + value: nil, + } +} + +//Set set +func (v *Value) Set(value interface{}) { + v.locker.Lock() + + v.value = value + v.isHas = true + v.locker.Unlock() +} + +//Get get +func (v *Value) Get() (interface{}, bool) { + v.locker.RLock() + value, has := v.value, v.isHas + + v.locker.RUnlock() + return value, has +} diff --git a/common/pdao/demo/demo.go b/common/pdao/demo/demo.go new file mode 100644 index 0000000000000000000000000000000000000000..6f9cc409ee1ca8551f94429842e228d579d289d6 --- /dev/null +++ b/common/pdao/demo/demo.go @@ -0,0 +1,62 @@ +package main + +import ( + "fmt" + "github.com/eolinker/goku-api-gateway/common/pdao" +) + +type DemoGetDao interface { + GetNameById(id int) string + GetIdByName(name string) int +} +type DemoSetDao interface { + Set(id int,name string) + +} + +type Demo struct { + names map[string]int + ids map[int]string +} + +func NewDemo() *Demo { + return &Demo{ + names: make(map[string]int), + ids: make(map[int]string), + }} + +func (d *Demo) Set(id int, name string) { + d.names[name]=id + d.ids[id]=name +} + +func (d *Demo) GetNameById(id int) string { + return d.ids[id] +} + +func (d *Demo) GetIdByName(name string) int { + return d.names[name] +} +var ( + getDao DemoGetDao + setDao DemoSetDao +) + +func init() { + pdao.Need(&getDao) + pdao.Need(&setDao) +} +func main() { + + demo:=NewDemo() + var seter DemoSetDao = demo + pdao.Set(&seter) + var getter DemoGetDao = demo + pdao.Set(&getter) + + pdao.Check() + + setDao.Set(1,"test") + fmt.Println(getDao.GetNameById(1)) + fmt.Println(getDao.GetIdByName("test")) +} \ No newline at end of file diff --git a/common/pdao/factory.go b/common/pdao/factory.go new file mode 100644 index 0000000000000000000000000000000000000000..5b0ad7962b257f08d2d6da9f022860867a3fa353 --- /dev/null +++ b/common/pdao/factory.go @@ -0,0 +1,21 @@ +package pdao + +import "database/sql" + +//FactoryFunc factoryFunc +type FactoryFunc func(db *sql.DB) (interface{}, error) + +//Create create +func (f FactoryFunc) Create(db *sql.DB) (interface{}, error) { + return f(db) +} + +//Factory factory +type Factory interface { + Create(db *sql.DB) (interface{}, error) +} + +//DBBuilder dbBuilder +type DBBuilder interface { + Build(db *sql.DB) error +} diff --git a/common/pdao/needs.go b/common/pdao/needs.go new file mode 100644 index 0000000000000000000000000000000000000000..d84f7df222a09541259b7c26d637d83d8d4cb4c7 --- /dev/null +++ b/common/pdao/needs.go @@ -0,0 +1,93 @@ +package pdao + +import ( + "fmt" + "reflect" + "sync" +) + +//NeedsManager needsManager +type NeedsManager struct { + daoInterfaces map[string][]*reflect.Value + lock sync.Mutex +} + +//NewNeedsManager 创建新的needsManager +func NewNeedsManager() *NeedsManager { + return &NeedsManager{ + daoInterfaces: make(map[string][]*reflect.Value), + lock: sync.Mutex{}, + } +} + +func (m *NeedsManager) add(key string, v *reflect.Value) { + m.lock.Lock() + m.daoInterfaces[key] = append(m.daoInterfaces[key], v) + m.lock.Unlock() +} + +func (m *NeedsManager) set(key string, v reflect.Value) { + m.lock.Lock() + for _, e := range m.daoInterfaces[key] { + e.Set(v) + } + delete(m.daoInterfaces, key) + m.lock.Unlock() +} +func (m *NeedsManager) check() []string { + m.lock.Lock() + r := make([]string, 0, len(m.daoInterfaces)) + for pkg := range m.daoInterfaces { + + r = append(r, pkg) + } + m.lock.Unlock() + return r +} + +//Need 声明 +func (m *NeedsManager) Need(p interface{}) { + + v := reflect.ValueOf(p) + + if v.Kind() != reflect.Ptr { + panic("must ptr") + } + e := v.Elem() + pkg := key(e.Type()) + if pkg == "" { + panic("invalid interface") + } + + if !e.CanSet() { + panic("invalid interface") + } + m.add(pkg, &e) +} + +//Set 注入 +func (m *NeedsManager) Set(i interface{}) { + v := reflect.ValueOf(i) + if v.Kind() != reflect.Ptr { + panic("must ptr") + } + e := v.Elem() + pkg := key(e.Type()) + + if pkg == "" { + panic("invalid interface") + } + m.set(pkg, e) +} +func key(t reflect.Type) string { + return fmt.Sprintf("%s.%s", t.PkgPath(), t.String()) +} + +//Check 检查是否实现相关dao类 +func (m *NeedsManager) Check() error { + rs := m.check() + if len(rs) > 0 { + return fmt.Errorf("need:%v", rs) + } + return nil +} diff --git a/common/pdao/needs_test.go b/common/pdao/needs_test.go new file mode 100644 index 0000000000000000000000000000000000000000..1388a2dc912b500707751636347164822f77ac2b --- /dev/null +++ b/common/pdao/needs_test.go @@ -0,0 +1,66 @@ +package pdao + +import ( + "fmt" + "testing" + + test1 "github.com/eolinker/goku-api-gateway/common/pdao/test/test/test/test" +) + +type T1 struct { +} + +func (t *T1) Test4() { + fmt.Println("implement me") +} + +type T2 struct { +} + +func (t *T2) Test3() { + fmt.Println("implement me") +} + +type T3 struct { +} + +func (t *T3) Test2() { + + fmt.Println("implement me") +} + +type T4 struct { +} + +func (t *T4) Test1() { + fmt.Println("implement me") +} + +func Test(t *testing.T) { + + t.Run("all", func(t *testing.T) { + var t1 test1.Test + //var t2 test2.Test = nil + //var t3 test3.Test = nil + //var t4 test4.Test = nil + Need(&t1) + //Need(&t2) + //Need(&t3) + //Need(&t4) + + var t1v test1.Test = new(T4) + Set(&t1v) + //Set(test2.Test(new(T3))) + // + //Set(test3.Test(new(T2))) + //Set(test4.Test(new(T1))) + + t1.Test1() + //t2.Test2() + //t3.Test3() + //t4.Test4() + Check() + + }) + +} diff --git a/common/pdao/pdao.go b/common/pdao/pdao.go new file mode 100644 index 0000000000000000000000000000000000000000..b8aa7a35a5afed58f403b6e20d2227f7c0aa8116 --- /dev/null +++ b/common/pdao/pdao.go @@ -0,0 +1,116 @@ +package pdao + +import ( + "database/sql" + "sync" +) + +var ( + needsManager = NewNeedsManager() + factoryManage = NewFactoryManager() +) + +//Need need +func Need(is ...interface{}) { + for _, i := range is { + needsManager.Need(i) + } +} + +//Check check +func Check() error { + return needsManager.Check() +} + +//RegisterDao 注册dao类 +func RegisterDao(driver string, factories ...Factory) { + for _, factory := range factories { + factoryManage.RegisterDao(driver, factory) + } + +} + +//RegisterDBBuilder 注册dbBuilder +func RegisterDBBuilder(driver string, builders ...DBBuilder) { + for _, builder := range builders { + factoryManage.RegisterDBBuilder(driver, builder) + + } +} + +//Build build +func Build(driver string, db *sql.DB) error { + return factoryManage.Build(driver, db, needsManager) +} + +//FactoryManager 工厂管理者 +type FactoryManager struct { + factories map[string][]Factory + builders map[string][]DBBuilder + locker sync.Mutex +} + +//NewFactoryManager new工厂管理者 +func NewFactoryManager() *FactoryManager { + return &FactoryManager{ + factories: make(map[string][]Factory), + builders: make(map[string][]DBBuilder), + locker: sync.Mutex{}, + } +} + +//RegisterDBBuilder dbBuilder注册器 +func (f *FactoryManager) RegisterDBBuilder(driver string, builder DBBuilder) { + f.locker.Lock() + f.builders[driver] = append(f.builders[driver], builder) + f.locker.Unlock() +} + +//RegisterDao dao类注册器 +func (f *FactoryManager) RegisterDao(driver string, factory Factory) { + f.locker.Lock() + f.factories[driver] = append(f.factories[driver], factory) + f.locker.Unlock() +} + +func (f *FactoryManager) get(driver string) []Factory { + f.locker.Lock() + fs := f.factories[driver] + delete(f.factories, driver) + f.locker.Unlock() + return fs +} + +func (f *FactoryManager) callBuild(driver string, db *sql.DB) error { + f.locker.Lock() + + bs := f.builders[driver] + for _, b := range bs { + err := b.Build(db) + if err != nil { + f.locker.Unlock() + return err + } + } + f.locker.Unlock() + return nil +} + +//Build build +func (f *FactoryManager) Build(driver string, db *sql.DB, m *NeedsManager) error { + err := f.callBuild(driver, db) + if err != nil { + return err + } + fs := f.get(driver) + for _, factory := range fs { + + i, err := factory.Create(db) + if err != nil { + return err + } + m.Set(i) + } + return nil + +} diff --git a/common/pdao/test/t.go b/common/pdao/test/t.go new file mode 100644 index 0000000000000000000000000000000000000000..532bcfaf6a304ce72470312a3c76ad483896f569 --- /dev/null +++ b/common/pdao/test/t.go @@ -0,0 +1,6 @@ +package test + + +type Test interface { + Test4() +} \ No newline at end of file diff --git a/common/pdao/test/test/t.go b/common/pdao/test/test/t.go new file mode 100644 index 0000000000000000000000000000000000000000..2aa08133485c6db31f4e6c0fe6285df6a3a09ce6 --- /dev/null +++ b/common/pdao/test/test/t.go @@ -0,0 +1,6 @@ +package test + + +type Test interface { + Test3() +} \ No newline at end of file diff --git a/common/pdao/test/test/test/t.go b/common/pdao/test/test/test/t.go new file mode 100644 index 0000000000000000000000000000000000000000..6508d58eee17b2bdbc25e9c1a457ece2b8a18805 --- /dev/null +++ b/common/pdao/test/test/test/t.go @@ -0,0 +1,6 @@ +package test + + +type Test interface { + Test2() +} \ No newline at end of file diff --git a/common/pdao/test/test/test/test/t.go b/common/pdao/test/test/test/test/t.go new file mode 100644 index 0000000000000000000000000000000000000000..036cbee6213da3e1e2a426b982becc549e37e1a0 --- /dev/null +++ b/common/pdao/test/test/test/test/t.go @@ -0,0 +1,6 @@ +package test + + +type Test interface { + Test1() +} \ No newline at end of file diff --git a/common/redis-manager/manager.go b/common/redis-manager/manager.go index 73eac1a2c7275b49af7734212a9159fb132ff747..1a3ba75af512830a413889a203d28458b2d3dd4a 100644 --- a/common/redis-manager/manager.go +++ b/common/redis-manager/manager.go @@ -54,3 +54,18 @@ func Get(name string) (Redis, bool) { return nil, false } + +func del(name string) { + locker.RLock() + defer locker.RUnlock() + + delete(redisOfCluster, name) + + return +} + +//Delete delete +func Delete(name string) { + del(name) + return +} diff --git a/common/redis-manager/redis.go b/common/redis-manager/redis.go index a54482af9d2c43cf55fd11cf3aeb41ae4c621ea7..08e8e06fd2dc4e4a72f1f7aea17ec194d72fa551 100644 --- a/common/redis-manager/redis.go +++ b/common/redis-manager/redis.go @@ -5,6 +5,9 @@ import "github.com/go-redis/redis" const ( //RedisModeCluster cluster模式 RedisModeCluster = "cluster" + + //RedisModeSentinel sentinel模式 + RedisModeSentinel = "sentinel" //RedisModeStand stand模式 RedisModeStand = "stand" ) diff --git a/common/redis-manager/redis_conn.go b/common/redis-manager/redis_conn.go index 484e30f214aa847fcdf344263eb9c05c87836e95..1e52f043813dc7e4e3e87f7baf6300608e1f3514 100644 --- a/common/redis-manager/redis_conn.go +++ b/common/redis-manager/redis_conn.go @@ -1,7 +1,12 @@ package redis_manager import ( + "fmt" + "sort" + "strings" "sync" + + "github.com/go-redis/redis" ) var ( @@ -17,17 +22,77 @@ func SetDefault(r Redis) { //GetConnection 获取redis连接 func GetConnection() Redis { - if def != nil { - return def - } + //if def != nil { + return def + //} + //defLocker.Lock() + //defer defLocker.Unlock() + // + //def = Create(defaultConfig) + //return def +} - defLocker.Lock() - defer defLocker.Unlock() +//CheckConnection 获取redis连接 +func CheckConnection(mode, addrs, password, masters string, dbIndex int) bool { + switch mode { + case RedisModeCluster: + { + a := strings.Split(addrs, ",") + option := &redis.ClusterOptions{ + Addrs: a, + Password: password, + PoolSize: 2000, + ReadOnly: true, + RouteByLatency: true, + } + r := redis.NewClusterClient(option) + defer r.Close() + if _, err := r.Ping().Result(); err != nil { + return false + } + return true + } + case RedisModeSentinel: + { + a := strings.Split(addrs, ",") + option := redis.FailoverOptions{ + SentinelAddrs: a, + MasterName: masters, + Password: password, + DB: dbIndex, + PoolSize: _PoolSize, + } + r := redis.NewFailoverClient(&option) + defer r.Close() + if _, err := r.Ping().Result(); err != nil { + return false + } + return true + } + case RedisModeStand: + { - if def != nil { - return def + a := strings.Split(addrs, ",") + + option := redis.RingOptions{ + Addrs: make(map[string]string), + Password: password, + DB: dbIndex, + + PoolSize: _PoolSize, + } + sort.Strings(a) + for i, ad := range a { + option.Addrs[fmt.Sprintf("shad:%d", i)] = ad + } + r := redis.NewRing(&option) + defer r.Close() + if _, err := r.Ping().Result(); err != nil { + return false + } + return true + } } + return false - def = Create(defaultConfig) - return def } diff --git a/common/telegraph/telegraph.go b/common/telegraph/telegraph.go index b1a881229bf00471887905321b33e09482fc3a9e..a9d8abd5d08ad96e4d09d2e91eda154d00f659ad 100644 --- a/common/telegraph/telegraph.go +++ b/common/telegraph/telegraph.go @@ -5,9 +5,12 @@ import ( "errors" "sync" ) + var ( + //ErrorContextDone context done error ErrorContextDone = errors.New("context done") ) + //Telegraph telegraph type Telegraph struct { value interface{} @@ -50,7 +53,7 @@ func (t *Telegraph) get() (string, <-chan struct{}, interface{}) { } //Get get -func (t *Telegraph) Get(version string) (interface{},error) { +func (t *Telegraph) Get(version string) (interface{}, error) { return t.GetWidthContext(context.Background(), version) } @@ -63,21 +66,21 @@ func (t *Telegraph) Close() { } //GetWidthContext 获取上下文 -func (t *Telegraph) GetWidthContext(ctx context.Context, version string) (interface{} ,error){ +func (t *Telegraph) GetWidthContext(ctx context.Context, version string) (interface{}, error) { v, c, value := t.get() if v == "" { // closed - return nil,nil + return nil, nil } if version != v { - return value,nil + return value, nil } select { case <-c: return t.GetWidthContext(ctx, version) case <-ctx.Done(): - return nil,ErrorContextDone + return nil, ErrorContextDone } } diff --git a/common/version/version.go b/common/version/version.go index 07c258fbaaa71e176ed30705c1208b71d4dbd1eb..d3d23285468e5adb28a6823764a2d1963396e9ea 100644 --- a/common/version/version.go +++ b/common/version/version.go @@ -1,4 +1,4 @@ package version //Version 版本号 -const Version = "3.1.1" +const Version = "3.1.3" diff --git a/config/config.go b/config/config.go index 90597c5bed9c9d798cca79d9937ba196e7bad218..5d6f49e70183ebe76ba53af41cdcf16611a49404 100644 --- a/config/config.go +++ b/config/config.go @@ -1,27 +1,42 @@ package config - //GokuConfig goku根配置 type GokuConfig struct { - Version string `json:"version"` - Cluster string `json:"cluster"` - Instance string `json:"instance"` - BindAddress string `json:"bind"` + Version string `json:"version"` + Cluster string `json:"cluster"` + Instance string `json:"instance"` + BindAddress string `json:"bind"` AdminAddress string `json:"admin"` //Port int `json:"port"` DiscoverConfig map[string]*DiscoverConfig `json:"discover,omitempty"` Balance map[string]*BalanceConfig `json:"balance,omitempty"` - Plugins *GatewayPluginConfig `json:"plugins,omitempty"` + Plugins GatewayPluginConfig `json:"plugins,omitempty"` APIS []*APIContent `json:"apis,omitempty"` Strategy []*StrategyConfig `json:"strategy,omitempty"` AnonymousStrategyID string `json:"anonymousStrategyID,omitempty"` AuthPlugin map[string]string `json:"authPlugin,omitempty"` + GatewayBasicInfo *Gateway `json:"gatewayBasicInfo"` + //RouterRule map[string]*RouterRule `json:"routerRule"` + Log *LogConfig `json:"log,omitempty"` + AccessLog *AccessLogConfig `json:"access_log,omitempty"` + Routers []*Router `json:"routers"` + MonitorModules map[string]string `json:"monitor_modules"` + RedisConfig map[string]interface{} `json:"redisConfig"` + ExtendsConfig map[string]interface{} `json:"extends_config"` +} - Log *LogConfig `json:"log,omitempty"` - AccessLog *AccessLogConfig `json:"access_log,omitempty"` +//Router 路由 +type Router struct { + Rules string `json:"routerRules"` + Target string `json:"target"` + Priority int `json:"priority"` +} - MonitorModules map[string]string `json:"monitor_modules"` +//RouterRule 路由规则 +type RouterRule struct { + Host string `json:"host"` + StrategyID string `json:"strategyID"` } //AccessLogConfig access日志配置 @@ -82,12 +97,15 @@ type PluginConfig struct { IsStop bool `json:"stop"` Config string `json:"config"` UpdateTag string `json:"updateTag"` + IsAuth bool `json:"isAuth"` } //APIContent api详情 type APIContent struct { - ID int `json:"id"` - Name string `json:"name"` + ID int `json:"id"` + Name string `json:"name"` + Alias string `json:"alias"` + OutPutEncoder string `json:"output"` RequestURL string `json:"requestUrl"` Methods []string `json:"methods"` @@ -177,6 +195,11 @@ type StrategyConfig struct { Plugins []*PluginConfig `json:"plugins"` } +//Gateway 网关配置 +type Gateway struct { + SkipCertificate int `json:"skipCertificate"` +} + //APIOfStrategy 策略接口配置 type APIOfStrategy struct { ID int `json:"id"` @@ -193,6 +216,7 @@ type VersionConfig struct { CreateTime string `json:"createTime"` PublishStatus int `json:"publishStatus"` PublishTime string `json:"publishTime"` + Publisher string `json:"publisher"` } //Project 项目 diff --git a/console/account/account-default.go b/console/account/account-default.go new file mode 100644 index 0000000000000000000000000000000000000000..0bfe3d0ab1b28fde5d0d57f85c27294eb2627198 --- /dev/null +++ b/console/account/account-default.go @@ -0,0 +1,48 @@ +package account + +import ( + "errors" + "net/http" + "strconv" + + "github.com/eolinker/goku-api-gateway/console/module/account" +) + +//DefaultAccount default +type DefaultAccount struct { +} + +//NewDefaultAccount new defaultAccount +func NewDefaultAccount() *DefaultAccount { + return &DefaultAccount{} +} + +//CheckLogin 判断是否登录 +func (d *DefaultAccount) CheckLogin(r *http.Request) (int, error) { + + userIDCookie, idErr := r.Cookie("userID") + userCookie, userErr := r.Cookie("userToken") + if idErr != nil || userErr != nil { + e := errors.New("user not logged in") + return 0, e + } + userID, err := strconv.Atoi(userIDCookie.Value) + if err != nil { + return 0, err + } + flag := account.CheckLogin(userCookie.Value, userID) + if !flag { + e := errors.New("illegal users") + return userID, e + } + + return userID, nil +} + +//CheckPermission 检查操作权限 +func (d *DefaultAccount) CheckPermission(pre string, isEdit bool, userID int) (bool, error) { + if isEdit { + return true, nil + } + return true, nil +} diff --git a/console/controller/account/guest.go b/console/controller/account/guest.go index 03e05632c6d068cd586bbb4b3cef1376e39bff9b..4c91c486ee5d7d268c8d4cfaf49bfa2316c7601b 100644 --- a/console/controller/account/guest.go +++ b/console/controller/account/guest.go @@ -2,6 +2,9 @@ package account import ( "errors" + + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "net/http" "strconv" @@ -10,6 +13,22 @@ import ( "github.com/eolinker/goku-api-gateway/utils" ) +//Account 账号类 +type Account struct { +} + +//Handlers 处理器 +func (c *Account) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/login": http.HandlerFunc(Login), + } +} + +//NewAccountController 新建账号控制类 +func NewAccountController() *Account { + return &Account{} +} + //Login 用户登录 func Login(httpResponse http.ResponseWriter, httpRequest *http.Request) { @@ -24,7 +43,7 @@ func Login(httpResponse http.ResponseWriter, httpRequest *http.Request) { "100000", "guest", "[ERROR]Wrong username or password!", - errors.New("Wrong username or password")) + errors.New("wrong username or password")) return } diff --git a/console/controller/account/user.go b/console/controller/account/user.go index fceecd9840e2f308b31fdd681c1225738f1e2a41..6bab0d14c71bb7766f70c0bc5635b0f6e94e54a7 100644 --- a/console/controller/account/user.go +++ b/console/controller/account/user.go @@ -6,11 +6,38 @@ import ( "regexp" "strconv" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/account" "github.com/eolinker/goku-api-gateway/utils" ) +//OperationUser 用户权限 +const OperationUser = "user" + +//UserController 用户控制器 +type UserController struct { +} + +//NewUserController 新建用户控制器 +func NewUserController() *UserController { + return &UserController{} +} + +//Handlers 处理类 +func (u *UserController) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + + return map[string]http.Handler{ + "/logout": factory.NewAccountHandleFunction(OperationUser, false, Logout), + "/password/edit": factory.NewAccountHandleFunction(OperationUser, false, EditPassword), + "/getInfo": factory.NewAccountHandleFunction(OperationUser, false, GetUserInfo), + "/getUserType": factory.NewAccountHandleFunction(OperationUser, false, GetUserType), + "/checkIsAdmin": factory.NewAccountHandleFunction(OperationUser, false, CheckUserIsAdmin), + "/checkIsSuperAdmin": factory.NewAccountHandleFunction(OperationUser, false, CheckUserIsSuperAdmin), + } +} + //Logout 用户注销 func Logout(httpResponse http.ResponseWriter, httpRequest *http.Request) { @@ -25,10 +52,6 @@ func Logout(httpResponse http.ResponseWriter, httpRequest *http.Request) { //EditPassword 修改账户信息 func EditPassword(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationEDIT) - if e != nil { - return - } oldPassword := httpRequest.PostFormValue("oldPassword") newPassword := httpRequest.PostFormValue("newPassword") @@ -50,6 +73,7 @@ func EditPassword(httpResponse http.ResponseWriter, httpRequest *http.Request) { errors.New("[ERROR]Illegal newPassword")) return } + userID := goku_handler.UserIDFromRequest(httpRequest) flag, result, err := account.EditPassword(oldPassword, newPassword, userID) if !flag { controller.WriteError(httpResponse, @@ -72,10 +96,7 @@ func EditPassword(httpResponse http.ResponseWriter, httpRequest *http.Request) { //GetUserInfo 获取用户信息 func GetUserInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationEDIT) - if e != nil { - return - } + userID := goku_handler.UserIDFromRequest(httpRequest) flag, result, err := account.GetUserInfo(userID) if !flag { @@ -91,11 +112,8 @@ func GetUserInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { //GetUserType 获取用户类型 func GetUserType(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationEDIT) - if e != nil { - return - } + userID := goku_handler.UserIDFromRequest(httpRequest) flag, result, err := account.GetUserType(userID) if !flag { @@ -109,10 +127,7 @@ func GetUserType(httpResponse http.ResponseWriter, httpRequest *http.Request) { //CheckUserIsAdmin 判断是否是管理员 func CheckUserIsAdmin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationEDIT) - if e != nil { - return - } + userID := goku_handler.UserIDFromRequest(httpRequest) flag, _, err := account.CheckUserIsAdmin(userID) if !flag { @@ -132,10 +147,7 @@ func CheckUserIsAdmin(httpResponse http.ResponseWriter, httpRequest *http.Reques //CheckUserIsSuperAdmin 判断是否是超级管理员 func CheckUserIsSuperAdmin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationEDIT) - if e != nil { - return - } + userID := goku_handler.UserIDFromRequest(httpRequest) flag, _, err := account.CheckUserIsSuperAdmin(userID) @@ -153,29 +165,3 @@ func CheckUserIsSuperAdmin(httpResponse http.ResponseWriter, httpRequest *http.R controller.WriteResultInfo(httpResponse, "user", "", nil) return } - -//CheckUserPermission 检查用户权限 -func CheckUserPermission(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationEDIT) - if e != nil { - return - } - - operationType := httpRequest.PostFormValue("operationType") - operation := httpRequest.PostFormValue("operation") - flag, result, err := account.CheckUserPermission(operationType, operation, userID) - - if !flag { - - controller.WriteError(httpResponse, - "110000", - "user", - result, - err) - return - - } - - controller.WriteResultInfo(httpResponse, "user", "", nil) - return -} diff --git a/console/controller/api/api-balance-batch.go b/console/controller/api/api-balance-batch.go index 2d46593f41ebc8d666190c2150a7fe01a7b51bbe..e817326bba53999023caafbf6c60f2c1031f6d32 100644 --- a/console/controller/api/api-balance-batch.go +++ b/console/controller/api/api-balance-batch.go @@ -1,19 +1,15 @@ package api import ( - "net/http" - "strings" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/api" + "net/http" + "strings" ) //BatchSetBalanceAPI 批量设置接口负载 func BatchSetBalanceAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } + apiIDList := httpRequest.PostFormValue("apiIDList") balanceName := httpRequest.PostFormValue("balance") diff --git a/console/controller/api/api.go b/console/controller/api/api.go index 22c96218e188a57cc6c0256100c31263a6801c5d..a97573caae35c030dc570662b58572a7d0c8ce7c 100644 --- a/console/controller/api/api.go +++ b/console/controller/api/api.go @@ -6,19 +6,47 @@ import ( "strconv" "strings" + "github.com/eolinker/goku-api-gateway/utils" + + "github.com/pkg/errors" + + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" - "github.com/eolinker/goku-api-gateway/console/module/account" "github.com/eolinker/goku-api-gateway/console/module/api" ) +const operationAPI = "apiManagement" + +//Handlers handlers +type Handlers struct { +} + +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationAPI, true, AddAPI), + "/edit": factory.NewAccountHandleFunction(operationAPI, true, EditAPI), + "/copy": factory.NewAccountHandleFunction(operationAPI, true, CopyAPI), + "/getInfo": factory.NewAccountHandleFunction(operationAPI, false, GetAPIInfo), + "/getList": factory.NewAccountHandleFunction(operationAPI, false, GetAPIList), + "/id/getList": factory.NewAccountHandleFunction(operationAPI, false, GetAPIIDList), + "/batchEditGroup": factory.NewAccountHandleFunction(operationAPI, true, BatchEditAPIGroup), + "/batchDelete": factory.NewAccountHandleFunction(operationAPI, true, BatchDeleteAPI), + "/batchEditBalance": factory.NewAccountHandleFunction(operationAPI, true, BatchSetBalanceAPI), + } +} + +//NewAPIHandlers API处理器 +func NewAPIHandlers() *Handlers { + return &Handlers{} +} + //AddAPI 新增接口 func AddAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } apiName := httpRequest.PostFormValue("apiName") + alias := httpRequest.PostFormValue("alias") requestURL := httpRequest.PostFormValue("requestURL") requestMethod := httpRequest.PostFormValue("requestMethod") protocol := httpRequest.PostFormValue("protocol") @@ -36,7 +64,7 @@ func AddAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { linkApis := httpRequest.PostFormValue("linkApis") staticResponse := httpRequest.PostFormValue("staticResponse") responseDataType := httpRequest.PostFormValue("responseDataType") - + userID := goku_handler.UserIDFromRequest(httpRequest) if apiName == "" { controller.WriteError(httpResponse, "190002", "api", "[ERROR]Illegal apiName!", nil) return @@ -55,6 +83,15 @@ func AddAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { controller.WriteError(httpResponse, "190012", "api", "[ERROR]Illegal apiType!", err) return } + + if !utils.ValidateURL(requestURL) { + controller.WriteError(httpResponse, "190021", "api", "[ERROR]Illegal requestURL!", nil) + return + } + if aType == 1 && !utils.ValidateURL(targetURL) { + controller.WriteError(httpResponse, "190022", "api", "[ERROR]Illegal requestURL!", nil) + return + } if responseDataType != "origin" && responseDataType != "json" && responseDataType != "xml" { controller.WriteError(httpResponse, "190013", "api", "[ERROR]Illegal responseDataType!", err) return @@ -102,8 +139,13 @@ func AddAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { if managerID == "" { mgID = userID } + if api.CheckAliasIsExist(0, alias) { + errInfo := "[ERROR]duplicate alias!" + controller.WriteError(httpResponse, "190020", "api", errInfo, errors.New(errInfo)) + return + } - flag, id, err := api.AddAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol, pjID, gID, t, count, apiValve, mgID, userID, aType) + flag, id, err := api.AddAPI(apiName, alias, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol, pjID, gID, t, count, apiValve, mgID, userID, aType) if !flag { controller.WriteError(httpResponse, @@ -117,13 +159,10 @@ func AddAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { //EditAPI 编辑接口 func EditAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } apiID := httpRequest.PostFormValue("apiID") apiName := httpRequest.PostFormValue("apiName") + alias := httpRequest.PostFormValue("alias") requestURL := httpRequest.PostFormValue("requestURL") targetURL := httpRequest.PostFormValue("targetURL") requestMethod := httpRequest.PostFormValue("requestMethod") @@ -140,6 +179,8 @@ func EditAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { linkApis := httpRequest.PostFormValue("linkApis") staticResponse := httpRequest.PostFormValue("staticResponse") responseDataType := httpRequest.PostFormValue("responseDataType") + userID := goku_handler.UserIDFromRequest(httpRequest) + if apiName == "" { controller.WriteError(httpResponse, "190002", "api", "[ERROR]Illegal apiName!", nil) return @@ -207,8 +248,13 @@ func EditAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { if managerID == "" { mgID = userID } + if api.CheckAliasIsExist(aID, alias) { + errInfo := "[ERROR]duplicate alias!" + controller.WriteError(httpResponse, "190020", "api", errInfo, errors.New(errInfo)) + return + } - flag, err := api.EditAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol, pjID, gID, t, count, apiValve, aID, mgID, userID) + flag, err := api.EditAPI(apiName, alias, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol, pjID, gID, t, count, apiValve, aID, mgID, userID) if !flag { controller.WriteError(httpResponse, "190000", "api", "[ERROR]apiID does not exist!", err) @@ -223,10 +269,6 @@ func EditAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { //GetAPIInfo 获取接口信息 func GetAPIInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } apiID := httpRequest.PostFormValue("apiID") @@ -249,10 +291,6 @@ func GetAPIInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { // GetAPIIDList 获取接口ID列表 func GetAPIIDList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } httpRequest.ParseForm() projectID := httpRequest.Form.Get("projectID") @@ -284,8 +322,11 @@ func GetAPIIDList(httpResponse http.ResponseWriter, httpRequest *http.Request) { ids := make([]int, 0) json.Unmarshal([]byte(idsStr), &ids) - _, result, _ := api.GetAPIIDList(pjID, gID, keyword, op, ids) - + _, result, err := api.GetAPIIDList(pjID, gID, keyword, op, ids) + if err != nil { + controller.WriteError(httpResponse, "190020", "api", "[ERROR]db error!", err) + return + } // controller.WriteResultInfo(httpResponse, "api", "apiList", result) controller.WriteResultInfoWithPage(httpResponse, "api", "apiIDList", result, &controller.PageInfo{ ItemNum: len(result), @@ -296,10 +337,6 @@ func GetAPIIDList(httpResponse http.ResponseWriter, httpRequest *http.Request) { //GetAPIList 获取接口列表 func GetAPIList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } httpRequest.ParseForm() projectID := httpRequest.Form.Get("projectID") @@ -343,8 +380,11 @@ func GetAPIList(httpResponse http.ResponseWriter, httpRequest *http.Request) { ids := make([]int, 0) json.Unmarshal([]byte(idsStr), &ids) - _, result, count, _ := api.GetAPIList(pjID, gID, keyword, op, p, pSize, ids) - + _, result, count, err := api.GetAPIList(pjID, gID, keyword, op, p, pSize, ids) + if err != nil { + controller.WriteError(httpResponse, "190019", "api", "[Error]db error", err) + return + } // controller.WriteResultInfo(httpResponse, "api", "apiList", result) controller.WriteResultInfoWithPage(httpResponse, "api", "apiList", result, &controller.PageInfo{ ItemNum: len(result), @@ -357,10 +397,6 @@ func GetAPIList(httpResponse http.ResponseWriter, httpRequest *http.Request) { // BatchEditAPIGroup 批量修改接口分组 func BatchEditAPIGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } apiIDList := httpRequest.PostFormValue("apiIDList") groupID := httpRequest.PostFormValue("groupID") @@ -381,10 +417,6 @@ func BatchEditAPIGroup(httpResponse http.ResponseWriter, httpRequest *http.Reque //BatchDeleteAPI 批量删除接口 func BatchDeleteAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } apiIDList := httpRequest.PostFormValue("apiIDList") @@ -400,30 +432,11 @@ func BatchDeleteAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) return } -//GetAPIManagerList 获取接口负责人列表 -func GetAPIManagerList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } - - flag, result, err := account.GetUserListWithPermission("apiManagement", "edit") - if !flag { - controller.WriteError(httpResponse, "190000", "api", err.Error(), err) - return - } - controller.WriteResultInfo(httpResponse, "api", "userList", result) - return -} - //CopyAPI 复制接口 func CopyAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } apiID := httpRequest.PostFormValue("apiID") + alisa := httpRequest.PostFormValue("alisa") apiName := httpRequest.PostFormValue("apiName") requestURL := httpRequest.PostFormValue("requestURL") targetURL := httpRequest.PostFormValue("targetURL") @@ -434,6 +447,7 @@ func CopyAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { isFollow := httpRequest.PostFormValue("isFollow") groupID := httpRequest.PostFormValue("groupID") projectID := httpRequest.PostFormValue("projectID") + userID := goku_handler.UserIDFromRequest(httpRequest) if apiName == "" { controller.WriteError(httpResponse, "190002", "api", "[ERROR]Illegal apiName!", nil) return @@ -465,13 +479,21 @@ func CopyAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { return } + if !utils.ValidateURL(requestURL) { + controller.WriteError(httpResponse, "190021", "api", "[ERROR]Illegal requestURL!", nil) + return + } flag, apiInfo, err := api.GetAPIInfo(aID) if !flag { controller.WriteError(httpResponse, "190000", "api", "[ERROR]apiID does not exist!", nil) return } + if apiInfo.APIType == 1 && !utils.ValidateURL(targetURL) { + controller.WriteError(httpResponse, "190022", "api", "[ERROR]Illegal targetURL!", nil) + return + } linkApis, _ := json.Marshal(apiInfo.LinkAPIs) - flag, id, err := api.AddAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, string(linkApis), apiInfo.StaticResponse, apiInfo.ResponseDataType, balanceName, protocol, pjID, gID, apiInfo.Timeout, apiInfo.RetryConut, apiInfo.Valve, apiInfo.ManagerID, userID, apiInfo.APIType) + flag, id, err := api.AddAPI(apiName, alisa, requestURL, targetURL, requestMethod, targetMethod, isFollow, string(linkApis), apiInfo.StaticResponse, apiInfo.ResponseDataType, balanceName, protocol, pjID, gID, apiInfo.Timeout, apiInfo.RetryConut, apiInfo.Valve, apiInfo.ManagerID, userID, apiInfo.APIType) if !flag { controller.WriteError(httpResponse, "190000", "api", "[ERROR]Fail to add api!", err) return diff --git a/console/controller/api/apiGroup.go b/console/controller/api/apiGroup.go index 1b7942f61a13067259d4e649ad529d0eab69039d..607242f3f6c22178ebbdc525f7b2f563ba61c6e1 100644 --- a/console/controller/api/apiGroup.go +++ b/console/controller/api/apiGroup.go @@ -7,14 +7,32 @@ import ( "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/api" "github.com/eolinker/goku-api-gateway/console/module/project" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" ) +const operationAPIGroup = "apiManagement" + +//GroupHandlers 接口分组处理器 +type GroupHandlers struct { +} + +//Handlers 处理器 +func (g *GroupHandlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationAPIGroup, true, AddAPIGroup), + "/edit": factory.NewAccountHandleFunction(operationAPIGroup, true, EditAPIGroup), + "/delete": factory.NewAccountHandleFunction(operationAPIGroup, true, DeleteAPIGroup), + "/getList": factory.NewAccountHandleFunction(operationAPIGroup, false, GetAPIGroupList), + } +} + +//NewGroupHandlers new 接口分组处理器 +func NewGroupHandlers() *GroupHandlers { + return &GroupHandlers{} +} + //AddAPIGroup 新建接口分组 func AddAPIGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } groupName := httpRequest.PostFormValue("groupName") projectID := httpRequest.PostFormValue("projectID") @@ -68,10 +86,6 @@ func AddAPIGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { //EditAPIGroup 修改接口分组 func EditAPIGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } groupName := httpRequest.PostFormValue("groupName") groupID := httpRequest.PostFormValue("groupID") @@ -120,10 +134,6 @@ func EditAPIGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { //DeleteAPIGroup 删除接口分组 func DeleteAPIGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } groupID := httpRequest.PostFormValue("groupID") projectID := httpRequest.PostFormValue("projectID") @@ -158,10 +168,6 @@ func DeleteAPIGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) //GetAPIGroupList 获取接口分组列表 func GetAPIGroupList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } projectID := httpRequest.PostFormValue("projectID") pjID, err := strconv.Atoi(projectID) diff --git a/console/controller/api/apiPlugin.go b/console/controller/api/apiPlugin.go index c11e14125d94419e269dff45cf26aed2134b8dda..eaab20ad0944ff2af557021297938ef4973f1083 100644 --- a/console/controller/api/apiPlugin.go +++ b/console/controller/api/apiPlugin.go @@ -10,20 +10,44 @@ import ( "github.com/eolinker/goku-api-gateway/console/module/plugin" plugin_config "github.com/eolinker/goku-api-gateway/console/module/plugin/plugin-config" "github.com/eolinker/goku-api-gateway/console/module/strategy" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" ) +const operationAPIPlugin = "strategyManagement" + +//PluginHandlers 插件处理器 +type PluginHandlers struct { +} + +//Handlers handlers +func (p *PluginHandlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/addPluginToApi": factory.NewAccountHandleFunction(operationAPIPlugin, true, AddPluginToAPI), + "/edit": factory.NewAccountHandleFunction(operationAPIPlugin, true, EditAPIPluginConfig), + "/getInfo": factory.NewAccountHandleFunction(operationAPIPlugin, false, GetAPIPluginConfig), + "/getList": factory.NewAccountHandleFunction(operationAPIPlugin, false, GetAPIPluginList), + "/getListByStrategy": factory.NewAccountHandleFunction(operationAPIPlugin, false, GetAllAPIPluginInStrategy), + "/batchStart": factory.NewAccountHandleFunction(operationAPIPlugin, true, BatchStartAPIPlugin), + "/batchStop": factory.NewAccountHandleFunction(operationAPIPlugin, true, BatchStopAPIPlugin), + "/batchDelete": factory.NewAccountHandleFunction(operationAPIPlugin, true, BatchDeleteAPIPlugin), + "/notAssign/getList": factory.NewAccountHandleFunction(operationAPIPlugin, false, GetAPIPluginListWithNotAssignAPIList), + } +} + +//NewPluginHandlers new插件处理器 +func NewPluginHandlers() *PluginHandlers { + return &PluginHandlers{} + +} + //AddPluginToAPI 新增插件到接口 func AddPluginToAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") pluginConfig := httpRequest.PostFormValue("pluginConfig") strategyID := httpRequest.PostFormValue("strategyID") apiID := httpRequest.PostFormValue("apiID") - + userID := goku_handler.UserIDFromRequest(httpRequest) aID, err := strconv.Atoi(apiID) if err != nil { controller.WriteError(httpResponse, "240002", "apiPlugin", "[ERROR]Illegal apiID!", err) @@ -81,15 +105,13 @@ func AddPluginToAPI(httpResponse http.ResponseWriter, httpRequest *http.Request) //EditAPIPluginConfig 修改接口插件 func EditAPIPluginConfig(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") pluginConfig := httpRequest.PostFormValue("pluginConfig") strategyID := httpRequest.PostFormValue("strategyID") apiID := httpRequest.PostFormValue("apiID") + userID := goku_handler.UserIDFromRequest(httpRequest) + flag, err := plugin_config.CheckConfig(pluginName, []byte(pluginConfig)) if !flag { controller.WriteError(httpResponse, "500000", "apiPlugin", "[ERROR]插件配置无效:"+err.Error(), err) @@ -153,10 +175,6 @@ func EditAPIPluginConfig(httpResponse http.ResponseWriter, httpRequest *http.Req //GetAPIPluginConfig 获取接口插件配置 func GetAPIPluginConfig(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") strategyID := httpRequest.PostFormValue("strategyID") @@ -198,10 +216,6 @@ func GetAPIPluginConfig(httpResponse http.ResponseWriter, httpRequest *http.Requ //GetAPIPluginList 获取接口插件配置 func GetAPIPluginList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") apiID := httpRequest.PostFormValue("apiID") @@ -230,60 +244,8 @@ func GetAPIPluginList(httpResponse http.ResponseWriter, httpRequest *http.Reques return } -// GetAPIPluginInStrategyByAPIID 获取策略组中所有接口插件列表 -func GetAPIPluginInStrategyByAPIID(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } - httpRequest.ParseForm() - strategyID := httpRequest.Form.Get("strategyID") - apiID := httpRequest.Form.Get("apiID") - keyword := httpRequest.Form.Get("keyword") - condition := httpRequest.Form.Get("condition") - - aID, err := strconv.Atoi(apiID) - if err != nil { - controller.WriteError(httpResponse, "240002", "apiPlugin", "[ERROR]Illegal condition!", err) - return - } - op, err := strconv.Atoi(condition) - if err != nil && condition != "" { - controller.WriteError(httpResponse, "270006", "apiPlugin", "[ERROR]Illegal condition!", err) - return - } - - flag, pluginList, apiInfo, err := api.GetAPIPluginInStrategyByAPIID(strategyID, aID, keyword, op) - if !flag { - controller.WriteError(httpResponse, - "240000", - "apiPlugin", - "[ERROR]Empty api plugin list!", - err) - return - - } - result := map[string]interface{}{ - "statusCode": "000000", - "type": "apiPlugin", - "resultDesc": "", - "apiPluginList": pluginList, - "apiInfo": apiInfo, - "page": controller.PageInfo{ - ItemNum: len(pluginList), - }, - } - resultStr, _ := json.Marshal(result) - httpResponse.Write(resultStr) - // controller.WriteResultInfo(httpResponse, "apiPlugin", "apiPluginList", result) -} - //GetAllAPIPluginInStrategy 获取策略组中所有接口插件列表 func GetAllAPIPluginInStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") @@ -305,13 +267,11 @@ func GetAllAPIPluginInStrategy(httpResponse http.ResponseWriter, httpRequest *ht //BatchStartAPIPlugin 批量修改策略组插件状态 func BatchStartAPIPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") connIDList := httpRequest.PostFormValue("connIDList") + userID := goku_handler.UserIDFromRequest(httpRequest) + if connIDList == "" { controller.WriteError(httpResponse, "240001", @@ -338,13 +298,11 @@ func BatchStartAPIPlugin(httpResponse http.ResponseWriter, httpRequest *http.Req //BatchStopAPIPlugin 批量修改策略组插件状态 func BatchStopAPIPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") connIDList := httpRequest.PostFormValue("connIDList") + userID := goku_handler.UserIDFromRequest(httpRequest) + if connIDList == "" { controller.WriteError(httpResponse, "240001", @@ -371,13 +329,10 @@ func BatchStopAPIPlugin(httpResponse http.ResponseWriter, httpRequest *http.Requ //BatchDeleteAPIPlugin 批量删除策略组插件 func BatchDeleteAPIPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") connIDList := httpRequest.PostFormValue("connIDList") + if connIDList == "" { controller.WriteError(httpResponse, "240001", @@ -401,10 +356,6 @@ func BatchDeleteAPIPlugin(httpResponse http.ResponseWriter, httpRequest *http.Re //GetAPIPluginListWithNotAssignAPIList 获取没有分配接口插件的接口列表 func GetAPIPluginListWithNotAssignAPIList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") if strategyID == "" { diff --git a/console/controller/api/import.go b/console/controller/api/import.go index c2d9e8e7571f1eef7da21deab027b7edb2b35a59..fec2a76aee6da3351bfd11b91bf181792576218b 100644 --- a/console/controller/api/import.go +++ b/console/controller/api/import.go @@ -2,6 +2,7 @@ package api import ( "encoding/json" + "fmt" "io/ioutil" "net/http" "strconv" @@ -9,18 +10,36 @@ import ( "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/api" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +const operationImportAMS = "apiManagement" + +//ImportHandlers 导入handlers +type ImportHandlers struct { +} + +//Handlers handler +func (i *ImportHandlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + + return map[string]http.Handler{ + "/api": factory.NewAccountHandleFunction(operationImportAMS, true, ImportAPIFromAms), + "/group": factory.NewAccountHandleFunction(operationImportAMS, true, ImportAPIGroupFromAms), + "/project": factory.NewAccountHandleFunction(operationImportAMS, true, ImportProjectFromAms), + } +} + +//NewImportHandlers new导入处理器 +func NewImportHandlers() *ImportHandlers { + return &ImportHandlers{} +} + //ImportAPIGroupFromAms 导入分组 func ImportAPIGroupFromAms(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } contentType := httpRequest.Header.Get("Content-Type") - + userID := goku_handler.UserIDFromRequest(httpRequest) if !strings.Contains(contentType, "multipart/form-data") { controller.WriteError(httpResponse, "310001", @@ -98,13 +117,9 @@ func ImportAPIGroupFromAms(httpResponse http.ResponseWriter, httpRequest *http.R //ImportProjectFromAms 导入项目 func ImportProjectFromAms(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } contentType := httpRequest.Header.Get("Content-Type") - + userID := goku_handler.UserIDFromRequest(httpRequest) if !strings.Contains(contentType, "multipart/form-data") { controller.WriteError(httpResponse, "310001", @@ -170,12 +185,9 @@ func ImportProjectFromAms(httpResponse http.ResponseWriter, httpRequest *http.Re //ImportAPIFromAms 导入接口 func ImportAPIFromAms(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } contentType := httpRequest.Header.Get("Content-Type") + userID := goku_handler.UserIDFromRequest(httpRequest) if !strings.Contains(contentType, "multipart/form-data") { controller.WriteError(httpResponse, "310001", @@ -229,6 +241,7 @@ func ImportAPIFromAms(httpResponse http.ResponseWriter, httpRequest *http.Reques } apiList := make([]entity.AmsAPIInfo, 0) + fmt.Println(string(body)) err = json.Unmarshal(body, &apiList) if err != nil { controller.WriteError(httpResponse, diff --git a/console/controller/auth/auth.go b/console/controller/auth/auth.go index 37af6dd5284f3f631ad95ca84c0d1edb6c97f75e..62c42aff417270bcb231ccb9f33bc3c273b12803 100644 --- a/console/controller/auth/auth.go +++ b/console/controller/auth/auth.go @@ -5,23 +5,40 @@ import ( "net/http" "strings" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/auth" log "github.com/eolinker/goku-api-gateway/goku-log" ) +const operationAuth = "strategyManagement" + +//Handlers handlers +type Handlers struct { +} + +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/getStatus": factory.NewAccountHandleFunction(operationAuth, true, GetAuthStatus), + "/getInfo": factory.NewAccountHandleFunction(operationAuth, true, GetAuthInfo), + "/editInfo": factory.NewAccountHandleFunction(operationAuth, true, EditAuthInfo), + } +} + +//NewHandlers new handlers +func NewHandlers() *Handlers { + return &Handlers{} +} + //GetAuthStatus 获取认证状态 func GetAuthStatus(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") flag, result, err := auth.GetAuthStatus(strategyID) if !flag { - controller.WriteError(httpResponse, "250000", "auth", "[ERROR]The auth info of the strategy does not exist!", err) return } @@ -37,10 +54,6 @@ func GetAuthStatus(httpResponse http.ResponseWriter, httpRequest *http.Request) //GetAuthInfo 获取认证信息 func GetAuthInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") @@ -64,10 +77,6 @@ func GetAuthInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { //EditAuthInfo 编辑认证信息 func EditAuthInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") strategyName := httpRequest.PostFormValue("strategyName") diff --git a/console/controller/balance/add.go b/console/controller/balance/add.go index ef9487421b95666859917bd88f89344ccf4f78f9..a78211d4ab6e1af886045a5f5aee6f7a0315cd82 100644 --- a/console/controller/balance/add.go +++ b/console/controller/balance/add.go @@ -2,10 +2,11 @@ package balance import ( "fmt" + "github.com/eolinker/goku-api-gateway/console/controller" + "net/http" "github.com/eolinker/goku-api-gateway/common/auto-form" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/balance" "github.com/go-sql-driver/mysql" ) @@ -13,10 +14,7 @@ import ( //AddBalance 新增负载配置 func AddBalance(w http.ResponseWriter, r *http.Request) { - _, e := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationEDIT) - if e != nil { - return - } + if err := r.ParseForm(); err != nil { controller.WriteError(w, "260000", diff --git a/console/controller/balance/delete.go b/console/controller/balance/delete.go index 0fac567e6e08359fdfd5c4aa3838e9a853fedf46..5dd1787ec90ae689be3b67048c0ca52d520cc47f 100644 --- a/console/controller/balance/delete.go +++ b/console/controller/balance/delete.go @@ -1,19 +1,16 @@ package balance import ( + "github.com/eolinker/goku-api-gateway/console/controller" "net/http" "strings" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/balance" ) //DeleteBalance 删除负载配置 func DeleteBalance(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationLoadBalance, controller.OperationEDIT) - if e != nil { - return - } + if err := httpRequest.ParseForm(); err != nil { controller.WriteError(httpResponse, "260000", "data", "[param_check] Parse form body error | 解析form表单参数错误", err) @@ -37,10 +34,7 @@ func DeleteBalance(httpResponse http.ResponseWriter, httpRequest *http.Request) //BatchDeleteBalance 批量删除负载 func BatchDeleteBalance(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationLoadBalance, controller.OperationEDIT) - if e != nil { - return - } + balanceNames := httpRequest.PostFormValue("balanceNames") result, err := balance.BatchDeleteBalance(strings.Split(balanceNames, ",")) if err != nil { diff --git a/console/controller/balance/get.go b/console/controller/balance/get.go index a726bf08882fee8f48b0a98a1a3f866e8f086c01..035289548f72b312eef8496a9538883417ddae37 100644 --- a/console/controller/balance/get.go +++ b/console/controller/balance/get.go @@ -1,18 +1,14 @@ package balance import ( - "net/http" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/balance" + "net/http" ) //GetBalanceInfo 获取负载信息 func GetBalanceInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationLoadBalance, controller.OperationREAD) - if e != nil { - return - } + if err := httpRequest.ParseForm(); err != nil { controller.WriteError(httpResponse, "501", "balance", "[ERROR]参数解析错误t!", err) return diff --git a/console/controller/balance/handle.go b/console/controller/balance/handle.go new file mode 100644 index 0000000000000000000000000000000000000000..dd6a839e8a04003990be2d9df487d10b83d1a474 --- /dev/null +++ b/console/controller/balance/handle.go @@ -0,0 +1,31 @@ +package balance + +import ( + "net/http" + + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" +) + +const operationBalance = "balanceManagement" + +//Handlers handlers +type Handlers struct { +} + +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationBalance, true, AddBalance), + "/edit": factory.NewAccountHandleFunction(operationBalance, true, SaveBalance), + "/delete": factory.NewAccountHandleFunction(operationBalance, true, DeleteBalance), + "/getInfo": factory.NewAccountHandleFunction(operationBalance, false, GetBalanceInfo), + "/getList": factory.NewAccountHandleFunction(operationBalance, false, GetBalanceList), + "/batchDelete": factory.NewAccountHandleFunction(operationBalance, true, BatchDeleteBalance), + "/simple": factory.NewAccountHandleFunction(operationBalance, true, GetSimpleList), + } +} + +//NewHandlers new handlers +func NewHandlers() *Handlers { + return &Handlers{} +} diff --git a/console/controller/balance/list.go b/console/controller/balance/list.go index a581df98466dbad3d474ee5c0924cea817a69315..d3334f1de72907e5c8d13d64bd4d2cd02a1f1bc2 100644 --- a/console/controller/balance/list.go +++ b/console/controller/balance/list.go @@ -2,18 +2,14 @@ package balance import ( "fmt" - "net/http" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/balance" + "net/http" ) //GetBalanceList 获取负载列表 func GetBalanceList(w http.ResponseWriter, r *http.Request) { - _, e := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationREAD) - if e != nil { - return - } + _ = r.ParseForm() keyword := r.FormValue("keyword") diff --git a/console/controller/balance/save.go b/console/controller/balance/save.go index 8ec187f848bdfbd815dddf57b6ead5902e4171af..1dc9b9bc8839714088c2c6b8bd13a64e0c91769f 100644 --- a/console/controller/balance/save.go +++ b/console/controller/balance/save.go @@ -2,21 +2,17 @@ package balance import ( "fmt" - "net/http" - "github.com/eolinker/goku-api-gateway/common/auto-form" "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/balance" "github.com/go-sql-driver/mysql" + "net/http" ) //SaveBalance 新增负载配置 func SaveBalance(w http.ResponseWriter, r *http.Request) { - _, e := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationEDIT) - if e != nil { - return - } + if err := r.ParseForm(); err != nil { controller.WriteError(w, "260000", "data", "[param_check] Parse form body error | 解析form表单参数错误", err) diff --git a/console/controller/balance/simple.go b/console/controller/balance/simple.go index 43de34aa2f3e64c0a13bdfb57eb5f4c55ac19201..28c5183ff0065bacf9f1817f6402c6dd35ca7105 100644 --- a/console/controller/balance/simple.go +++ b/console/controller/balance/simple.go @@ -1,18 +1,14 @@ package balance import ( - "net/http" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/balance" + "net/http" ) //GetSimpleList 获取简易列表 func GetSimpleList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationLoadBalance, controller.OperationREAD) - if e != nil { - return - } + flag, result, err := balance.GetBalancNames() diff --git a/console/controller/cluster/cluster.go b/console/controller/cluster/cluster.go index 6f9d0ab1f90234dcc53733e2f73ad97edd4e6519..f5750548fe0e5e939b47c716daeb81264a2ac823 100644 --- a/console/controller/cluster/cluster.go +++ b/console/controller/cluster/cluster.go @@ -4,18 +4,39 @@ import ( "net/http" "regexp" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/pkg/errors" "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/cluster" ) +const operationCluster = "nodeManagement" + +//Handlers handlers +type Handlers struct { +} + +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationCluster, true, AddCluster), + "/edit": factory.NewAccountHandleFunction(operationCluster, true, EditCluster), + "/delete": factory.NewAccountHandleFunction(operationCluster, true, DeleteCluster), + "/list": factory.NewAccountHandleFunction(operationCluster, false, GetClusterInfoList), + "/simpleList": factory.NewAccountHandleFunction(operationCluster, false, GetClusterList), + } +} + +//NewHandlers new handlers +func NewHandlers() *Handlers { + return &Handlers{} +} + //GetClusterList 获取集群列表 func GetClusterList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } + list, _ := cluster.GetClusters() controller.WriteResultInfo(httpResponse, @@ -26,10 +47,7 @@ func GetClusterList(httpResponse http.ResponseWriter, httpRequest *http.Request) //GetCluster 获取集群信息 func GetCluster(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() name := httpRequest.Form.Get("name") @@ -47,10 +65,7 @@ func GetCluster(httpResponse http.ResponseWriter, httpRequest *http.Request) { //AddCluster 新增集群 func AddCluster(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() name := httpRequest.Form.Get("name") title := httpRequest.Form.Get("title") @@ -78,10 +93,7 @@ func AddCluster(httpResponse http.ResponseWriter, httpRequest *http.Request) { //EditCluster 新增集群 func EditCluster(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() name := httpRequest.Form.Get("name") title := httpRequest.Form.Get("title") @@ -105,10 +117,7 @@ func EditCluster(httpResponse http.ResponseWriter, httpRequest *http.Request) { //DeleteCluster 新增集群 func DeleteCluster(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() name := httpRequest.Form.Get("name") match, err := regexp.MatchString(`^[a-zA-Z][a-zA-z0-9_]*$`, name) @@ -135,10 +144,7 @@ func DeleteCluster(httpResponse http.ResponseWriter, httpRequest *http.Request) //GetClusterInfoList 获取集群信息列表 func GetClusterInfoList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } + result, _ := cluster.GetClusters() controller.WriteResultInfo(httpResponse, diff --git a/console/controller/cluster/version.go b/console/controller/cluster/version.go index e40735b1cccae6a891f52da0738176467d6e7954..a9bb52d079562aa3a0a8bb7dc75c3a3382259964 100644 --- a/console/controller/cluster/version.go +++ b/console/controller/cluster/version.go @@ -6,17 +6,38 @@ import ( "strconv" "time" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/module/versionConfig" "github.com/eolinker/goku-api-gateway/console/controller" ) +const operationVersion = "versionManagement" + +//VersionHandlers 版本处理器 +type VersionHandlers struct { +} + +//Handlers handlers +func (h *VersionHandlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationVersion, true, AddVersionConfig), + "/basic/edit": factory.NewAccountHandleFunction(operationVersion, true, EditVersionBasicConfig), + "/delete": factory.NewAccountHandleFunction(operationVersion, true, BatchDeleteVersionConfig), + "/getList": factory.NewAccountHandleFunction(operationVersion, false, GetVersionList), + "/publish": factory.NewAccountHandleFunction(operationVersion, true, PublishVersion), + } +} + +//NewVersionHandlers new versionHandlers +func NewVersionHandlers() *VersionHandlers { + return &VersionHandlers{} +} + //GetVersionList 获取版本列表 func GetVersionList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() keyword := httpRequest.Form.Get("keyword") result, _ := versionConfig.GetVersionList(keyword) @@ -28,10 +49,7 @@ func GetVersionList(httpResponse http.ResponseWriter, httpRequest *http.Request) //AddVersionConfig 新增版本配置 func AddVersionConfig(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() name := httpRequest.Form.Get("name") version := httpRequest.Form.Get("version") @@ -44,14 +62,15 @@ func AddVersionConfig(httpResponse http.ResponseWriter, httpRequest *http.Reques } //count := cluster.GetVersionConfigCount() now := time.Now().Format("2006-01-02 15:04:05") - id, err := versionConfig.AddVersionConfig(name, version, remark, now) + userID := goku_handler.UserIDFromRequest(httpRequest) + id, err := versionConfig.AddVersionConfig(name, version, remark, now, userID) if err != nil { controller.WriteError(httpResponse, "380000", "versionConfig", err.Error(), err) return } if p == 1 { - versionConfig.PublishVersion(id, now) + versionConfig.PublishVersion(id, userID, now) } controller.WriteResultInfo(httpResponse, "versionConfig", @@ -60,12 +79,37 @@ func AddVersionConfig(httpResponse http.ResponseWriter, httpRequest *http.Reques return } -//BatchDeleteVersionConfig 批量删除版本配置 -func BatchDeleteVersionConfig(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { +//EditVersionBasicConfig 新增版本配置 +func EditVersionBasicConfig(httpResponse http.ResponseWriter, httpRequest *http.Request) { + + httpRequest.ParseForm() + name := httpRequest.Form.Get("name") + version := httpRequest.Form.Get("version") + remark := httpRequest.Form.Get("remark") + versionID := httpRequest.Form.Get("versionID") + id, err := strconv.Atoi(versionID) + if err != nil { + controller.WriteError(httpResponse, "380000", "versionConfig", err.Error(), err) return } + + userID := goku_handler.UserIDFromRequest(httpRequest) + err = versionConfig.EditVersionBasicConfig(name, version, remark, userID, id) + if err != nil { + controller.WriteError(httpResponse, "380000", "versionConfig", err.Error(), err) + return + } + + controller.WriteResultInfo(httpResponse, + "versionConfig", + "", + nil) + return +} + +//BatchDeleteVersionConfig 批量删除版本配置 +func BatchDeleteVersionConfig(httpResponse http.ResponseWriter, httpRequest *http.Request) { + httpRequest.ParseForm() ids := httpRequest.Form.Get("ids") idList := make([]int, 0, 10) @@ -93,13 +137,14 @@ func BatchDeleteVersionConfig(httpResponse http.ResponseWriter, httpRequest *htt func PublishVersion(httpResponse http.ResponseWriter, httpRequest *http.Request) { httpRequest.ParseForm() versionID := httpRequest.Form.Get("versionID") + userID := goku_handler.UserIDFromRequest(httpRequest) id, err := strconv.Atoi(versionID) if err != nil { controller.WriteError(httpResponse, "380002", "versionConfig", "[ERROR]Illegal versionID", err) return } now := time.Now().Format("2006-01-02 15:04:05") - err = versionConfig.PublishVersion(id, now) + err = versionConfig.PublishVersion(id, userID, now) if err != nil { controller.WriteError(httpResponse, "380000", "versionConfig", err.Error(), err) return diff --git a/console/controller/config-log/access.go b/console/controller/config-log/access.go index acd43af1da59c6469af5d6d89c824a62e601f72b..492a2561589712f593b571133112280e13fdacd0 100644 --- a/console/controller/config-log/access.go +++ b/console/controller/config-log/access.go @@ -4,39 +4,38 @@ import ( "fmt" "net/http" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/common/auto-form" "github.com/eolinker/goku-api-gateway/console/controller" module "github.com/eolinker/goku-api-gateway/console/module/config-log" ) -//AccessLogHandler access日志处理器 -type AccessLogHandler struct { +//LogHandler access日志处理器 +type LogHandler struct { + getHandler http.Handler + setHandler http.Handler } -func (h *AccessLogHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - _, err := controller.CheckLogin(w, r, controller.OperationGatewayConfig, controller.OperationEDIT) - if err != nil { - return - } +func (h *LogHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: { - h.get(w, r) - + h.getHandler.ServeHTTP(w, r) } case http.MethodPut: { - h.set(w, r) - + h.setHandler.ServeHTTP(w, r) } default: w.WriteHeader(404) } } -func (h *AccessLogHandler) get(w http.ResponseWriter, r *http.Request) { +//AccessLogGet 获取access日志配置 +func AccessLogGet(w http.ResponseWriter, r *http.Request) { config, e := module.GetAccess() if e = r.ParseForm(); e != nil { controller.WriteError(w, "270000", "data", "[Get]未知错误:"+e.Error(), e) @@ -49,7 +48,9 @@ func (h *AccessLogHandler) get(w http.ResponseWriter, r *http.Request) { config) } -func (h *AccessLogHandler) set(w http.ResponseWriter, r *http.Request) { + +//AccessLogSet 设置access日志内容 +func AccessLogSet(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err = r.ParseForm(); err != nil { controller.WriteError(w, "260000", "data", "[param_check] Parse form body error | 解析form表单参数错误", err) @@ -82,7 +83,7 @@ func (h *AccessLogHandler) set(w http.ResponseWriter, r *http.Request) { err = module.Set(module.AccessLog, paramBase) if err != nil { - controller.WriteError(w, "260000", "data", fmt.Sprintf("[mysql_error] %s", err.Error()), err) + controller.WriteError(w, "260000", "data", fmt.Sprintf("[db_error] %s", err.Error()), err) return } controller.WriteResultInfo(w, @@ -90,3 +91,11 @@ func (h *AccessLogHandler) set(w http.ResponseWriter, r *http.Request) { "", nil) } + +//NewAccessHandler accessHandler +func NewAccessHandler(factory *goku_handler.AccountHandlerFactory) http.Handler { + return &LogHandler{ + getHandler: factory.NewAccountHandleFunction(operationLog, false, AccessLogGet), + setHandler: factory.NewAccountHandleFunction(operationLog, true, AccessLogSet), + } +} diff --git a/console/controller/config-log/handle.go b/console/controller/config-log/handle.go index 6ab955aa7bcc292635500f31723790f6f87e1809..2063c0eca5befcfbbf9dc10d33c7bc8990575ab2 100644 --- a/console/controller/config-log/handle.go +++ b/console/controller/config-log/handle.go @@ -1,32 +1,27 @@ package config_log import ( - "fmt" "net/http" - "strings" - module "github.com/eolinker/goku-api-gateway/console/module/config-log" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" ) -//Handle handle -func Handle(prefix string) http.Handler { +const operationLog = "logManagement" - pre := strings.TrimSuffix(prefix, "/") - serveMux := http.NewServeMux() - consoleLogHandler := &LogHandler{ - name: module.ConsoleLog, - } +//Handlers handlers +type Handlers struct { +} - serveMux.Handle(fmt.Sprintf("%s/%s", pre, "console"), consoleLogHandler) - nodeLogHandler := &LogHandler{ - name: module.NodeLog, +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/console": NewLogHandler("console", factory), + "/node": NewLogHandler("node", factory), + "/access": NewAccessHandler(factory), } - serveMux.Handle(fmt.Sprintf("%s/%s", pre, "node"), nodeLogHandler) - - accessLogHandler := &AccessLogHandler{} - - serveMux.Handle(fmt.Sprintf("%s/%s", pre, "access"), accessLogHandler) - - return serveMux +} +//NewHandlers new handlers +func NewHandlers() *Handlers { + return &Handlers{} } diff --git a/console/controller/config-log/log.go b/console/controller/config-log/log.go index 55ec5b7bd46ac79578b7a14dbfba074d4e476e85..312e483fcb205c0dd5f50a72347e961ff789a854 100644 --- a/console/controller/config-log/log.go +++ b/console/controller/config-log/log.go @@ -4,39 +4,20 @@ import ( "fmt" "net/http" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/common/auto-form" "github.com/eolinker/goku-api-gateway/console/controller" module "github.com/eolinker/goku-api-gateway/console/module/config-log" ) -//LogHandler 日志处理器 -type LogHandler struct { +//LogHandlerGet 日志配置获取处理器 +type LogHandlerGet struct { name string } -func (h *LogHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - _, err := controller.CheckLogin(w, r, controller.OperationGatewayConfig, controller.OperationEDIT) - if err != nil { - return - } - - switch r.Method { - case http.MethodGet: - { - h.get(w, r) - - } +func (h *LogHandlerGet) ServeHTTP(w http.ResponseWriter, r *http.Request) { - case http.MethodPut: - { - h.set(w, r) - - } - default: - w.WriteHeader(404) - } -} -func (h *LogHandler) get(w http.ResponseWriter, r *http.Request) { config, e := module.Get(h.name) if e = r.ParseForm(); e != nil { controller.WriteError(w, "270000", "data", "[Get]未知错误:"+e.Error(), e) @@ -50,7 +31,12 @@ func (h *LogHandler) get(w http.ResponseWriter, r *http.Request) { } -func (h *LogHandler) set(w http.ResponseWriter, r *http.Request) { +//LogHandlerSet 设置日志处理器 +type LogHandlerSet struct { + name string +} + +func (h *LogHandlerSet) ServeHTTP(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err = r.ParseForm(); err != nil { @@ -83,7 +69,7 @@ func (h *LogHandler) set(w http.ResponseWriter, r *http.Request) { } err = module.Set(h.name, paramBase) if err != nil { - controller.WriteError(w, "260000", "data", fmt.Sprintf("[mysql_error] %s", err.Error()), err) + controller.WriteError(w, "260000", "data", fmt.Sprintf("[db_error] %s", err.Error()), err) return } controller.WriteResultInfo(w, @@ -91,3 +77,11 @@ func (h *LogHandler) set(w http.ResponseWriter, r *http.Request) { "", nil) } + +//NewLogHandler 日志handler +func NewLogHandler(name string, factory *goku_handler.AccountHandlerFactory) http.Handler { + return &LogHandler{ + getHandler: factory.NewAccountHandler(operationLog, false, &LogHandlerGet{name: name}), + setHandler: factory.NewAccountHandler(operationLog, true, &LogHandlerSet{name: name}), + } +} diff --git a/console/controller/discovery/add.go b/console/controller/discovery/add.go index b8544102e019c6f0422fa2006a67072ee71a65b8..584101ba920aeacc57d078f5e265ef7f1352675d 100644 --- a/console/controller/discovery/add.go +++ b/console/controller/discovery/add.go @@ -2,27 +2,24 @@ package discovery import ( "fmt" + "github.com/eolinker/goku-api-gateway/console/controller" "net/http" "github.com/eolinker/goku-api-gateway/common/auto-form" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/service" driver2 "github.com/eolinker/goku-api-gateway/server/driver" ) func add(w http.ResponseWriter, r *http.Request) { - _, err := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationEDIT) - if err != nil { - return - } - if err = r.ParseForm(); err != nil { + + if err := r.ParseForm(); err != nil { controller.WriteError(w, "260000", "data", "[param_check] Parse form body error | 解析form表单参数错误", err) return } param := new(service.AddParam) - err = auto.SetValues(r.PostForm, param) + err := auto.SetValues(r.PostForm, param) if err != nil { controller.WriteError(w, "260000", "data", fmt.Sprintf("[param_check] %s", err.Error()), err) return diff --git a/console/controller/discovery/default.go b/console/controller/discovery/default.go index 8f34d6fc596d1c6a0b2b955c5f9282ab921e2612..64db9bfed666f6eb3a0b1aec5f751f3fa138ba82 100644 --- a/console/controller/discovery/default.go +++ b/console/controller/discovery/default.go @@ -2,19 +2,16 @@ package discovery import ( "fmt" + "github.com/eolinker/goku-api-gateway/console/controller" "net/http" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/service" ) func setDefault(w http.ResponseWriter, r *http.Request) { - _, err := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationEDIT) - if err != nil { - return - } - if err != r.ParseForm() { + + if err := r.ParseForm() ; err!= nil{ controller.WriteError(w, "260000", "data", "[param_check] Parse form body error | 解析form表单参数错误", err) return } @@ -24,7 +21,7 @@ func setDefault(w http.ResponseWriter, r *http.Request) { return } - err = service.SetDefaut(name) + err := service.SetDefaut(name) if err != nil { controller.WriteError(w, "260000", "data", fmt.Sprintf("[error] %s", err.Error()), err) return diff --git a/console/controller/discovery/delete.go b/console/controller/discovery/delete.go index 8522856d8140ce1375278a6ff1f903656a8225a6..bdebea13ee17d295c0d9116db0de7536596f9d1e 100644 --- a/console/controller/discovery/delete.go +++ b/console/controller/discovery/delete.go @@ -2,21 +2,16 @@ package discovery import ( "fmt" - "net/http" - "strings" - - dao_service2 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-service" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/service" + dao_service2 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-service" + "net/http" + "strings" ) func delete(w http.ResponseWriter, r *http.Request) { - _, err := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationEDIT) - if err != nil { - return - } - if err != r.ParseForm() { + + if err := r.ParseForm() ; err!= nil{ controller.WriteError(w, "260000", "serviceDiscovery", "[param_check] Parse form body error | 解析form表单参数错误", err) return } @@ -24,7 +19,7 @@ func delete(w http.ResponseWriter, r *http.Request) { names := strings.Split(nameStr, ",") - err = service.Delete(names) + err := service.Delete(names) if err != nil { if en, ok := err.(dao_service2.DeleteError); ok { diff --git a/console/controller/discovery/driver.go b/console/controller/discovery/driver.go index 440255edf3bffdf1adc4826441c2afed82321df3..277ce2dfc0d6be3cf2ded2c85318b3f300f7ce59 100644 --- a/console/controller/discovery/driver.go +++ b/console/controller/discovery/driver.go @@ -1,20 +1,14 @@ package discovery import ( - "net/http" - "github.com/eolinker/goku-api-gateway/console/controller" driver2 "github.com/eolinker/goku-api-gateway/server/driver" + "net/http" ) func getDrivices(w http.ResponseWriter, r *http.Request) { ds := driver2.GetByType(driver2.Discovery) - _, err := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationREAD) - if err != nil { - return - } - controller.WriteResultInfo(w, "serviceDiscovery", "data", ds) } diff --git a/console/controller/discovery/edit.go b/console/controller/discovery/edit.go index 74f17bc852669a42719514da44c549a616912363..11e9bd0ae44615b8785049af9595db7ba5070f93 100644 --- a/console/controller/discovery/edit.go +++ b/console/controller/discovery/edit.go @@ -2,26 +2,22 @@ package discovery import ( "fmt" - "net/http" - "github.com/eolinker/goku-api-gateway/common/auto-form" "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/service" driver2 "github.com/eolinker/goku-api-gateway/server/driver" + "net/http" ) func edit(w http.ResponseWriter, r *http.Request) { - _, err := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationEDIT) - if err != nil { - return - } - if err != r.ParseForm() { + + if err := r.ParseForm() ; err!= nil{ controller.WriteError(w, "260000", "serviceDiscovery", "[param_check] Parse form body error | 解析form表单参数错误", err) return } param := new(service.AddParam) - err = auto.SetValues(r.PostForm, param) + err := auto.SetValues(r.PostForm, param) if err != nil { controller.WriteError(w, "260000", "data", fmt.Sprintf("[param_check] %s", err.Error()), err) return diff --git a/console/controller/discovery/get.go b/console/controller/discovery/get.go index d55efa9272fd2f7307ea6600099fdf2fe913c82b..6b9237e293346bced39796fa329c9232b0ec18db 100644 --- a/console/controller/discovery/get.go +++ b/console/controller/discovery/get.go @@ -2,17 +2,13 @@ package discovery import ( "fmt" - "net/http" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/service" + "net/http" ) func getInfo(w http.ResponseWriter, r *http.Request) { - _, err := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationREAD) - if err != nil { - return - } + name := r.URL.Query().Get("name") if !service.ValidateName(name) { diff --git a/console/controller/discovery/handle.go b/console/controller/discovery/handle.go index 79703c8592e389f72617a3bd8187d8163b7d5e7e..e8b0ca4cdeacaec20b415a5d8cb1a6b27f3b625c 100644 --- a/console/controller/discovery/handle.go +++ b/console/controller/discovery/handle.go @@ -2,24 +2,31 @@ package discovery import ( "net/http" -) - -//Handle 服务发现处理器 -func Handle(prefix string) http.Handler { - - serveMux := http.NewServeMux() - serveMux.HandleFunc("/drivers", getDrivices) - - serveMux.HandleFunc("/add", add) - serveMux.HandleFunc("/delete", delete) - serveMux.HandleFunc("/save", edit) - serveMux.HandleFunc("/info", getInfo) - serveMux.HandleFunc("/simple", simple) - serveMux.HandleFunc("/list", list) + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" +) - serveMux.HandleFunc("/default", setDefault) +//Handlers handlers +type Handlers struct { +} - return http.StripPrefix(prefix, serveMux) +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationDiscovery, true, add), + "/save": factory.NewAccountHandleFunction(operationDiscovery, true, edit), + "/delete": factory.NewAccountHandleFunction(operationDiscovery, true, delete), + "/info": factory.NewAccountHandleFunction(operationDiscovery, false, getInfo), + "/list": factory.NewAccountHandleFunction(operationDiscovery, false, list), + "/default": factory.NewAccountHandleFunction(operationDiscovery, true, setDefault), + "/drivers": factory.NewAccountHandleFunction(operationDiscovery, false, getDrivices), + "/simple": factory.NewAccountHandleFunction(operationDiscovery, false, simple), + } +} +//NewHandlers new handlers +func NewHandlers() *Handlers { + return &Handlers{} } + +const operationDiscovery = "balanceManagement" diff --git a/console/controller/discovery/list.go b/console/controller/discovery/list.go index 24cc84a867586a3dc06eb330f4c21410c8c9dff1..16a86167e6898d373a781c2980a54e2e3c5aed97 100644 --- a/console/controller/discovery/list.go +++ b/console/controller/discovery/list.go @@ -1,17 +1,12 @@ package discovery import ( - "net/http" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/service" + "net/http" ) func list(w http.ResponseWriter, r *http.Request) { - _, err := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationREAD) - if err != nil { - return - } _ = r.ParseForm() diff --git a/console/controller/discovery/simple.go b/console/controller/discovery/simple.go index c80a764437f5db6b49ae61dd745247d4ad5d500a..d1ecd95d7cfac02a90975160af73047184d54f0a 100644 --- a/console/controller/discovery/simple.go +++ b/console/controller/discovery/simple.go @@ -1,17 +1,14 @@ package discovery import ( + "github.com/eolinker/goku-api-gateway/console/controller" "net/http" - "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/service" ) func simple(w http.ResponseWriter, r *http.Request) { - _, err := controller.CheckLogin(w, r, controller.OperationLoadBalance, controller.OperationREAD) - if err != nil { - return - } + vs, def, err := service.SimpleList() if err != nil { diff --git a/console/controller/gateway/gateway.go b/console/controller/gateway/gateway.go index 6a62cab51f43a2433ae10896d6f0602d9bb9de25..6427eecef3b217e125eba3ac1a1c8698256b2796 100644 --- a/console/controller/gateway/gateway.go +++ b/console/controller/gateway/gateway.go @@ -4,16 +4,32 @@ import ( "encoding/json" "net/http" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/gateway" ) +const operationGateway = "gateway" + +//Handlers hendlers +type Handlers struct { +} + +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/getSummaryInfo": factory.NewAccountHandleFunction(operationGateway, false, GetGatewayBasicInfo), + } +} + +//NewHandlers new handlers +func NewHandlers() *Handlers { + return &Handlers{} +} + //GetGatewayBasicInfo 获取网关基本信息 func GetGatewayBasicInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } flag, result, err := gateway.GetGatewayMonitorSummaryByPeriod() if !flag { diff --git a/console/controller/monitor/module.go b/console/controller/monitor/module.go index c469c198125650dcb26591973f9fddd7bc0c80b0..787642ccd7c18b23710f0eb4a38872108fc7a8fa 100644 --- a/console/controller/monitor/module.go +++ b/console/controller/monitor/module.go @@ -4,19 +4,36 @@ import ( "net/http" "strconv" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/ksitigarbha" + "github.com/pkg/errors" "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/monitor" ) -//GetMonitorModules 获取监控模块列表 -func GetMonitorModules(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return +const operationMonitorModule = "monitorModuleManagement" + +//Handlers handlers +type Handlers struct { +} + +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/get": factory.NewAccountHandleFunction(operationMonitorModule, false, GetMonitorModules), + "/set": factory.NewAccountHandleFunction(operationMonitorModule, true, SetMonitorModule), } +} +//NewHandlers new handlers +func NewHandlers() *Handlers { + return &Handlers{} +} + +//GetMonitorModules 获取监控模块列表 +func GetMonitorModules(httpResponse http.ResponseWriter, httpRequest *http.Request) { result, err := monitor.GetMonitorModules() if err != nil { controller.WriteError(httpResponse, @@ -25,18 +42,14 @@ func GetMonitorModules(httpResponse http.ResponseWriter, httpRequest *http.Reque err.Error(), err) return - } controller.WriteResultInfo(httpResponse, "monitorModule", "moduleList", result) return } +//SetMonitorModule 设置监控模块 func SetMonitorModule(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNone, controller.OperationREAD) - if e != nil { - return - } httpRequest.ParseForm() moduleName := httpRequest.Form.Get("moduleName") moduleStatus := httpRequest.Form.Get("moduleStatus") @@ -62,7 +75,11 @@ func SetMonitorModule(httpResponse http.ResponseWriter, httpRequest *http.Reques err) return } - + if status == 1 { + ksitigarbha.Open(moduleName, config) + } else { + ksitigarbha.Close(moduleName) + } controller.WriteResultInfo(httpResponse, "monitorModule", "", nil) return } diff --git a/console/controller/node/node.go b/console/controller/node/node.go index f1979306f6432eee394f09d0eda92dacd843315a..e584a728c0e1d1d53538e2a5915ba806fdcd6e81 100644 --- a/console/controller/node/node.go +++ b/console/controller/node/node.go @@ -3,8 +3,10 @@ package node import ( "encoding/json" "errors" - "github.com/eolinker/goku-api-gateway/common/auto-form" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + + "github.com/eolinker/goku-api-gateway/common/auto-form" "github.com/eolinker/goku-api-gateway/console/module/cluster" log "github.com/eolinker/goku-api-gateway/goku-log" @@ -17,13 +19,32 @@ import ( "github.com/eolinker/goku-api-gateway/utils" ) -//AddNode 新增节点信息 -func AddNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { +const operationNode = "nodeManagement" - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationEDIT) - if e != nil { - return +//Handlers Handlers +type Handlers struct { +} + +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationNode, true, AddNode), + "/edit": factory.NewAccountHandleFunction(operationNode, true, EditNode), + "/delete": factory.NewAccountHandleFunction(operationNode, true, DeleteNode), + "/getInfo": factory.NewAccountHandleFunction(operationNode, false, GetNodeInfo), + "/getList": factory.NewAccountHandleFunction(operationNode, false, GetNodeList), + "/batchEditGroup": factory.NewAccountHandleFunction(operationNode, true, BatchEditNodeGroup), + "/batchDelete": factory.NewAccountHandleFunction(operationNode, true, BatchDeleteNode), } +} + +//NewNodeHandlers new nodeHandlers +func NewNodeHandlers() *Handlers { + return &Handlers{} +} + +//AddNode 新增节点信息 +func AddNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { cluserName := httpRequest.PostFormValue("cluster") @@ -35,27 +56,16 @@ func AddNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { //nodeNumber := rsa.CertConf["nodeNumber"].(int) type NodeParam struct { - NodeName string `opt:"nodeName,require"` + NodeName string `opt:"nodeName,require"` ListenAddress string `opt:"listenAddress,require"` - AdminAddress string `opt:"adminAddress,require"` - GroupID int `opt:"groupID,require"` - Path string `opt:"gatewayPath"` + AdminAddress string `opt:"adminAddress,require"` + GroupID int `opt:"groupID,require"` + Path string `opt:"gatewayPath"` } - // - //nodeName := httpRequest.PostFormValue("nodeName") - //listenAddress := httpRequest.PostFormValue("listenAddress") - //adminAddress := httpRequest.PostFormValue("adminAddress") - //groupID := httpRequest.PostFormValue("groupID") - //gatewayPath := httpRequest.PostFormValue("gatewayPath") - // - //gID, err := strconv.Atoi(groupID) - //if err != nil && groupID != "" { - // controller.WriteError(httpResponse, "230015", "", "[ERROR]Illegal groupID!", err) - // return - //} - param:=new(NodeParam) - err:=auto.SetValues(httpRequest.Form,param) - if err!= nil{ + + param := new(NodeParam) + err := auto.SetValues(httpRequest.Form, param) + if err != nil { controller.WriteError(httpResponse, "230015", "", "[ERROR]", err) return } @@ -88,37 +98,32 @@ func AddNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { } } - flag, result, err := node.AddNode(clusterID, param.NodeName, param.ListenAddress, param.AdminAddress, param.Path, param.GroupID) + id, v, result, err := node.AddNode(clusterID, param.NodeName, param.ListenAddress, param.AdminAddress, param.Path, param.GroupID) - if !flag { + if err != nil { controller.WriteError(httpResponse, "330000", "node", - result["error"].(string), + result, err) return } res := map[string]interface{}{ - "nodeID": result["nodeID"], - "version": result["version"], + "nodeID": id, + "version": v, "statusCode": "000000", "type": "node", "resultDesc": "", } data, _ := json.Marshal(res) - _,_=httpResponse.Write(data) + _, _ = httpResponse.Write(data) } //EditNode 修改节点信息 func EditNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationEDIT) - if e != nil { - return - } - nodeName := httpRequest.PostFormValue("nodeName") listenAddress := httpRequest.PostFormValue("listenAddress") adminAddress := httpRequest.PostFormValue("adminAddress") @@ -170,17 +175,9 @@ func EditNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { } } - //exits := node.CheckIsExistRemoteAddr(id, listenAddress, adminAddress) - //if exits { - // - // controller.WriteError(httpResponse, "230005", "node", "[ERROR]The remote address is existed!", nil) - // return - // - //} + result, err := node.EditNode(nodeName, listenAddress, adminAddress, gatewayPath, id, gID) - flag, result, _ := node.EditNode(nodeName, listenAddress, adminAddress, gatewayPath, id, gID) - - if !flag { + if err != nil { controller.WriteError(httpResponse, "330000", "node", result, nil) return } @@ -192,12 +189,6 @@ func EditNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { //DeleteNode 删除节点信息 func DeleteNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationEDIT) - if e != nil { - - return - } - nodeID := httpRequest.PostFormValue("nodeID") id, err := strconv.Atoi(nodeID) @@ -210,8 +201,8 @@ func DeleteNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { return } - flag, result, err := node.DeleteNode(id) - if !flag { + result, err := node.DeleteNode(id) + if err != nil { controller.WriteError(httpResponse, "330000", @@ -227,12 +218,8 @@ func DeleteNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { // GetNodeList 获取节点列表 func GetNodeList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationREAD) - if e != nil { - return - } httpRequest.ParseForm() - cluserName := httpRequest.Form.Get("cluster") + clusterName := httpRequest.Form.Get("cluster") groupID := httpRequest.Form.Get("groupID") keyword := httpRequest.Form.Get("keyword") @@ -245,21 +232,20 @@ func GetNodeList(httpResponse http.ResponseWriter, httpRequest *http.Request) { gID = -1 } - clusterID := cluster.GetClusterIDByName(cluserName) + clusterID := cluster.GetClusterIDByName(clusterName) if clusterID == 0 { controller.WriteError(httpResponse, "330003", "node", "[ERROR]The cluster dosen't exist!", nil) return } - flag, result, err := node.GetNodeList(clusterID, gID, keyword) - if !flag { + result, err := node.GetNodeList(clusterID, gID, keyword) + if err != nil { controller.WriteError(httpResponse, "330000", "node", "[ERROR]Empty node list!", err) return - } controller.WriteResultInfo(httpResponse, "node", "nodeList", result) // controller.WriteResultInfo(httpResponse, "nodeList", result) @@ -268,10 +254,6 @@ func GetNodeList(httpResponse http.ResponseWriter, httpRequest *http.Request) { //GetNodeInfo 获取节点信息 func GetNodeInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationREAD) - if e != nil { - return - } nodeID := httpRequest.PostFormValue("nodeID") @@ -286,8 +268,8 @@ func GetNodeInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { err) return } - result, err := node.GetNodeInfo(id) - if err!= nil { + result, err := node.GetNodeInfo(id) + if err != nil { controller.WriteError(httpResponse, "330000", @@ -302,16 +284,8 @@ func GetNodeInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { return } - - //BatchEditNodeGroup 批量修改节点分组 func BatchEditNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationEDIT) - if e != nil { - return - } - nodeIDList := httpRequest.PostFormValue("nodeIDList") groupID := httpRequest.PostFormValue("groupID") @@ -325,8 +299,8 @@ func BatchEditNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Requ return } - flag, result, err := node.BatchEditNodeGroup(nodeIDList, gID) - if !flag { + result, err := node.BatchEditNodeGroup(nodeIDList, gID) + if err != nil { controller.WriteError(httpResponse, "330000", @@ -345,16 +319,10 @@ func BatchEditNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Requ //BatchDeleteNode 批量删除节点 func BatchDeleteNode(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationEDIT) - if e != nil { - - return - } - nodeIDList := httpRequest.PostFormValue("nodeIDList") - flag, result, err := node.BatchDeleteNode(nodeIDList) - if !flag { + result, err := node.BatchDeleteNode(nodeIDList) + if err != nil { if result == "230013" { controller.WriteError(httpResponse, diff --git a/console/controller/node/nodeGroup.go b/console/controller/node/nodeGroup.go index 922f55d549d5f09ab737d1053e4a8b9f1cb4cbf1..68a629bd540902192ef53a4f472584073a2842ce 100644 --- a/console/controller/node/nodeGroup.go +++ b/console/controller/node/nodeGroup.go @@ -4,18 +4,35 @@ import ( "net/http" "strconv" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/cluster" "github.com/eolinker/goku-api-gateway/console/module/node" ) -//AddNodeGroup 新增节点分组 -func AddNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { +//GroupHandlers groupHandlers +type GroupHandlers struct { +} - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationEDIT) - if e != nil { - return +//Handlers handlers +func (h *GroupHandlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationNode, true, AddNodeGroup), + "/edit": factory.NewAccountHandleFunction(operationNode, true, EditNodeGroup), + "/delete": factory.NewAccountHandleFunction(operationNode, true, DeleteNodeGroup), + "/getInfo": factory.NewAccountHandleFunction(operationNode, false, GetNodeGroupInfo), + "/getList": factory.NewAccountHandleFunction(operationNode, false, GetNodeGroupList), } +} + +//NewGroupHandlers new groupHandlers +func NewGroupHandlers() *GroupHandlers { + return &GroupHandlers{} +} + +//AddNodeGroup 新增节点分组 +func AddNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { cluserName := httpRequest.PostFormValue("cluster") @@ -53,11 +70,6 @@ func AddNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { //EditNodeGroup 修改节点分组信息 func EditNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationEDIT) - if e != nil { - return - } - groupName := httpRequest.PostFormValue("groupName") groupID := httpRequest.PostFormValue("groupID") if groupName == "" { @@ -97,10 +109,6 @@ func EditNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) //DeleteNodeGroup 删除节点分组 func DeleteNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationEDIT) - if e != nil { - return - } groupID := httpRequest.PostFormValue("groupID") @@ -149,10 +157,6 @@ func DeleteNodeGroup(httpResponse http.ResponseWriter, httpRequest *http.Request //GetNodeGroupInfo 获取节点分组信息 func GetNodeGroupInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationREAD) - if e != nil { - return - } groupID := httpRequest.PostFormValue("groupID") @@ -182,10 +186,6 @@ func GetNodeGroupInfo(httpResponse http.ResponseWriter, httpRequest *http.Reques //GetNodeGroupList 获取节点分组列表 func GetNodeGroupList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationNode, controller.OperationREAD) - if e != nil { - return - } cluserName := httpRequest.FormValue("cluster") clusterID := cluster.GetClusterIDByName(cluserName) diff --git a/console/controller/plugin/plugin.go b/console/controller/plugin/plugin.go index 590ae90ec8ebe11bbf44a62fc6bf60420f11fca9..7075059b00dbb04333a95485566ec1130832c2c4 100644 --- a/console/controller/plugin/plugin.go +++ b/console/controller/plugin/plugin.go @@ -4,17 +4,47 @@ import ( "net/http" "strconv" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/plugin" plugin_config "github.com/eolinker/goku-api-gateway/console/module/plugin/plugin-config" ) +const operationPlugin = "pluginManagement" + +//Handlers handlers +type Handlers struct { +} + +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationPlugin, true, AddPlugin), + "/edit": factory.NewAccountHandleFunction(operationPlugin, true, EditPlugin), + "/delete": factory.NewAccountHandleFunction(operationPlugin, true, DeletePlugin), + "/checkNameIsExist": factory.NewAccountHandleFunction(operationPlugin, false, CheckNameIsExist), + "/checkIndexIsExist": factory.NewAccountHandleFunction(operationPlugin, false, CheckIndexIsExist), + "/getList": factory.NewAccountHandleFunction(operationPlugin, false, GetPluginList), + "/getInfo": factory.NewAccountHandleFunction(operationPlugin, false, GetPluginInfo), + "/getConfig": factory.NewAccountHandleFunction(operationPlugin, false, GetPluginConfig), + "/start": factory.NewAccountHandleFunction(operationPlugin, true, StartPlugin), + "/stop": factory.NewAccountHandleFunction(operationPlugin, true, StopPlugin), + "/getListByType": factory.NewAccountHandleFunction(operationPlugin, false, GetPluginListByPluginType), + "/batchStop": factory.NewAccountHandleFunction(operationPlugin, true, BatchStopPlugin), + "/batchStart": factory.NewAccountHandleFunction(operationPlugin, true, BatchStartPlugin), + "/availiable/check": factory.NewAccountHandleFunction(operationPlugin, false, CheckPluginIsAvailable), + } +} + +//NewHandlers new handlers +func NewHandlers() *Handlers { + return &Handlers{} +} + // GetPluginList 获取插件列表 func GetPluginList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() keyword := httpRequest.Form.Get("keyword") condition := httpRequest.Form.Get("condition") @@ -40,10 +70,6 @@ func GetPluginList(httpResponse http.ResponseWriter, httpRequest *http.Request) //AddPlugin 新增插件信息 func AddPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationEDIT) - if e != nil { - return - } pluginPriority := httpRequest.PostFormValue("pluginPriority") pluginName := httpRequest.PostFormValue("pluginName") @@ -106,10 +132,6 @@ func AddPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { //EditPlugin 修改插件信息 func EditPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationEDIT) - if e != nil { - return - } pluginPriority := httpRequest.PostFormValue("pluginPriority") pluginName := httpRequest.PostFormValue("pluginName") @@ -162,10 +184,6 @@ func EditPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { //DeletePlugin 删除插件信息 func DeletePlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationEDIT) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") flag, err := plugin.CheckNameIsExist(pluginName) @@ -195,10 +213,6 @@ func DeletePlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { //GetPluginInfo 获取插件信息 func GetPluginInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationREAD) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") @@ -228,10 +242,6 @@ func GetPluginInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) //GetPluginConfig 获取插件配置 func GetPluginConfig(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationREAD) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") flag, result, err := plugin.GetPluginConfig(pluginName) @@ -252,10 +262,6 @@ func GetPluginConfig(httpResponse http.ResponseWriter, httpRequest *http.Request //CheckIndexIsExist 判断插件优先级是否存在 func CheckIndexIsExist(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationEDIT) - if e != nil { - return - } pluginPriority := httpRequest.PostFormValue("pluginPriority") @@ -286,10 +292,6 @@ func CheckIndexIsExist(httpResponse http.ResponseWriter, httpRequest *http.Reque //CheckNameIsExist 检查插件名称是否存在 func CheckNameIsExist(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationEDIT) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") @@ -309,10 +311,6 @@ func CheckNameIsExist(httpResponse http.ResponseWriter, httpRequest *http.Reques //StartPlugin 开启插件 func StartPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationEDIT) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") @@ -332,10 +330,6 @@ func StartPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { //StopPlugin 关闭插件 func StopPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationEDIT) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") @@ -354,10 +348,6 @@ func StopPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { //GetPluginListByPluginType 获取不同类型的插件列表 func GetPluginListByPluginType(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationREAD) - if e != nil { - return - } pluginType := httpRequest.PostFormValue("pluginType") @@ -387,10 +377,6 @@ func GetPluginListByPluginType(httpResponse http.ResponseWriter, httpRequest *ht //BatchStopPlugin 批量关闭插件 func BatchStopPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationEDIT) - if e != nil { - return - } pluginNameList := httpRequest.PostFormValue("pluginNameList") @@ -411,10 +397,6 @@ func BatchStopPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request //BatchStartPlugin 批量关闭插件 func BatchStartPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationEDIT) - if e != nil { - return - } pluginNameList := httpRequest.PostFormValue("pluginNameList") @@ -435,10 +417,6 @@ func BatchStartPlugin(httpResponse http.ResponseWriter, httpRequest *http.Reques //CheckPluginIsAvailable 检测插件 func CheckPluginIsAvailable(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationPlugin, controller.OperationEDIT) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") if len(pluginName) < 2 { @@ -449,37 +427,5 @@ func CheckPluginIsAvailable(httpResponse http.ResponseWriter, httpRequest *http. nil) return } - //flag, nodeList, err := node.GetNodeIPList() - //if !flag { - // controller.WriteError(httpResponse, - // "210000", - // "plugin", - // "[ERROR]The Open node list is empty", - // err) - // return - //} - //flag, errPluginList := utils.CheckPluginIsAvailiable(pluginName, nodeList) - //if !flag { - // - // controller.WriteResultInfoWithCode(httpResponse, - // "210000", - // "plugin", - // "errNodeList", - // errPluginList) - // return - //} - //flag, res, _ := plugin.EditPluginCheckStatus(pluginName, 1) - //if !flag { - // - // controller.WriteError(httpResponse, - // "210000", - // "plugin", - // res, - // err) - // return - //} - // - //controller.WriteResultInfo(httpResponse, "plugin", "", nil) - return } diff --git a/console/controller/project/project.go b/console/controller/project/project.go index 675f599df323581c4b20f34b47c47748ba4b309c..5ea7038090b8f2184bf3236f07534e438ea3da97 100644 --- a/console/controller/project/project.go +++ b/console/controller/project/project.go @@ -4,16 +4,38 @@ import ( "net/http" "strconv" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/project" ) +const operationProject = "apiManagement" + +//Handlers handlers +type Handlers struct { +} + +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationProject, true, AddProject), + "/edit": factory.NewAccountHandleFunction(operationProject, true, EditProject), + "/delete": factory.NewAccountHandleFunction(operationProject, true, DeleteProject), + "/getInfo": factory.NewAccountHandleFunction(operationProject, false, GetProjectInfo), + "/getList": factory.NewAccountHandleFunction(operationProject, false, GetProjectList), + "/strategy/getList": factory.NewAccountHandleFunction(operationProject, false, GetAPIListFromProjectNotInStrategy), + "/batchDelete": factory.NewAccountHandleFunction(operationProject, true, BatchDeleteProject), + } +} + +//NewHandlers new handlers +func NewHandlers() *Handlers { + return &Handlers{} +} + //AddProject 新建项目 func AddProject(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } projectName := httpRequest.PostFormValue("projectName") if projectName == "" { @@ -43,10 +65,6 @@ func AddProject(httpResponse http.ResponseWriter, httpRequest *http.Request) { //EditProject 修改项目信息 func EditProject(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } projectName := httpRequest.PostFormValue("projectName") projectID := httpRequest.PostFormValue("projectID") @@ -87,10 +105,6 @@ func EditProject(httpResponse http.ResponseWriter, httpRequest *http.Request) { //DeleteProject 删除项目信息 func DeleteProject(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } projectID := httpRequest.PostFormValue("projectID") @@ -122,10 +136,6 @@ func DeleteProject(httpResponse http.ResponseWriter, httpRequest *http.Request) //BatchDeleteProject 删除项目信息 func BatchDeleteProject(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationEDIT) - if e != nil { - return - } projectIDList := httpRequest.PostFormValue("projectIDList") @@ -147,10 +157,6 @@ func BatchDeleteProject(httpResponse http.ResponseWriter, httpRequest *http.Requ //GetProjectInfo 获取项目信息 func GetProjectInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } projectID := httpRequest.PostFormValue("projectID") @@ -181,10 +187,7 @@ func GetProjectInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) //GetProjectList 获取项目列表 func GetProjectList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() keyword := httpRequest.FormValue("keyword") @@ -207,10 +210,6 @@ func GetProjectList(httpResponse http.ResponseWriter, httpRequest *http.Request) //GetAPIListFromProjectNotInStrategy 获取项目列表中没有被策略组绑定的接口 func GetAPIListFromProjectNotInStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationAPI, controller.OperationREAD) - if e != nil { - return - } flag, result, err := project.GetAPIListFromProjectNotInStrategy() if !flag { diff --git a/console/controller/reg.go b/console/controller/reg.go new file mode 100644 index 0000000000000000000000000000000000000000..8ca42e8b184d229a16aabf4362c70fc91133a72e --- /dev/null +++ b/console/controller/reg.go @@ -0,0 +1,4 @@ +// 控制台模块注册文件 +package controller + + diff --git a/console/controller/strategy/apiStrategy.go b/console/controller/strategy/apiStrategy.go index 424e1c2945db4f1e653a88c1b4e83cc7891b6dc9..e8c19b8874ae0079ed722fd9ada365d93630ff37 100644 --- a/console/controller/strategy/apiStrategy.go +++ b/console/controller/strategy/apiStrategy.go @@ -6,17 +6,41 @@ import ( "strconv" "strings" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/api" "github.com/eolinker/goku-api-gateway/console/module/strategy" ) +const operationAPIStrategy = "strategyManagement" + +//APIStrategyHandlers 接口策略handlers +type APIStrategyHandlers struct { +} + +//Handlers handlers +func (h *APIStrategyHandlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationAPIStrategy, true, AddAPIToStrategy), + "/target": factory.NewAccountHandleFunction(operationAPIStrategy, true, ResetAPITargetOfStrategy), + "/batchEditTarget": factory.NewAccountHandleFunction(operationAPIStrategy, true, BatchResetAPITargetOfStrategy), + "/getList": factory.NewAccountHandleFunction(operationAPIStrategy, false, GetAPIListFromStrategy), + "/id/getList": factory.NewAccountHandleFunction(operationAPIStrategy, false, GetAPIIDListFromStrategy), + "/getNotInList": factory.NewAccountHandleFunction(operationAPIStrategy, false, GetAPIListNotInStrategy), + "/id/getNotInList": factory.NewAccountHandleFunction(operationAPIStrategy, false, GetAPIIDListNotInStrategyByProject), + "/batchDelete": factory.NewAccountHandleFunction(operationAPIStrategy, true, BatchDeleteAPIInStrategy), + "/plugin/getList": factory.NewAccountHandleFunction(operationAPIStrategy, false, GetAPIPluginInStrategyByAPIID), + } +} + +//NewAPIStrategyHandlers new接口策略处理器 +func NewAPIStrategyHandlers() *APIStrategyHandlers { + return &APIStrategyHandlers{} +} + //AddAPIToStrategy 将接口加入策略组 func AddAPIToStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") apiID := httpRequest.PostFormValue("apiID") @@ -49,11 +73,6 @@ func AddAPIToStrategy(httpResponse http.ResponseWriter, httpRequest *http.Reques // ResetAPITargetOfStrategy 将接口加入策略组 func ResetAPITargetOfStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } - strategyID := httpRequest.PostFormValue("strategyID") target := httpRequest.PostFormValue("target") apiID := httpRequest.PostFormValue("apiID") @@ -93,10 +112,6 @@ func ResetAPITargetOfStrategy(httpResponse http.ResponseWriter, httpRequest *htt // BatchResetAPITargetOfStrategy 将接口加入策略组 func BatchResetAPITargetOfStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") target := httpRequest.PostFormValue("target") @@ -137,10 +152,6 @@ func BatchResetAPITargetOfStrategy(httpResponse http.ResponseWriter, httpRequest // GetAPIIDListFromStrategy 获取策略组接口ID列表 func GetAPIIDListFromStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } httpRequest.ParseForm() strategyID := httpRequest.Form.Get("strategyID") @@ -194,10 +205,6 @@ func GetAPIIDListFromStrategy(httpResponse http.ResponseWriter, httpRequest *htt // GetAPIListFromStrategy 获取策略组接口列表 func GetAPIListFromStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } httpRequest.ParseForm() strategyID := httpRequest.Form.Get("strategyID") @@ -266,10 +273,6 @@ func GetAPIListFromStrategy(httpResponse http.ResponseWriter, httpRequest *http. //CheckIsExistAPIInStrategy 检查插件是否添加进策略组 func CheckIsExistAPIInStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") apiID := httpRequest.PostFormValue("apiID") @@ -301,10 +304,7 @@ func CheckIsExistAPIInStrategy(httpResponse http.ResponseWriter, httpRequest *ht // GetAPIIDListNotInStrategyByProject 获取未被该策略组绑定的接口ID列表(通过项目) func GetAPIIDListNotInStrategyByProject(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() strategyID := httpRequest.Form.Get("strategyID") projectID := httpRequest.Form.Get("projectID") @@ -342,10 +342,7 @@ func GetAPIIDListNotInStrategyByProject(httpResponse http.ResponseWriter, httpRe //GetAPIListNotInStrategy 获取未被该策略组绑定的接口列表 func GetAPIListNotInStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() strategyID := httpRequest.Form.Get("strategyID") projectID := httpRequest.Form.Get("projectID") @@ -397,10 +394,6 @@ func GetAPIListNotInStrategy(httpResponse http.ResponseWriter, httpRequest *http //BatchDeleteAPIInStrategy 批量删除策略组接口 func BatchDeleteAPIInStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } apiIDList := httpRequest.PostFormValue("apiIDList") strategyID := httpRequest.PostFormValue("strategyID") @@ -418,3 +411,48 @@ func BatchDeleteAPIInStrategy(httpResponse http.ResponseWriter, httpRequest *htt } controller.WriteResultInfo(httpResponse, "apiStrategy", "", nil) } + +// GetAPIPluginInStrategyByAPIID 获取策略组中所有接口插件列表 +func GetAPIPluginInStrategyByAPIID(httpResponse http.ResponseWriter, httpRequest *http.Request) { + + httpRequest.ParseForm() + strategyID := httpRequest.Form.Get("strategyID") + apiID := httpRequest.Form.Get("apiID") + keyword := httpRequest.Form.Get("keyword") + condition := httpRequest.Form.Get("condition") + + aID, err := strconv.Atoi(apiID) + if err != nil { + controller.WriteError(httpResponse, "240002", "apiPlugin", "[ERROR]Illegal condition!", err) + return + } + op, err := strconv.Atoi(condition) + if err != nil && condition != "" { + controller.WriteError(httpResponse, "270006", "apiPlugin", "[ERROR]Illegal condition!", err) + return + } + + flag, pluginList, apiInfo, err := api.GetAPIPluginInStrategyByAPIID(strategyID, aID, keyword, op) + if !flag { + controller.WriteError(httpResponse, + "240000", + "apiPlugin", + "[ERROR]Empty api plugin list!", + err) + return + + } + result := map[string]interface{}{ + "statusCode": "000000", + "type": "apiPlugin", + "resultDesc": "", + "apiPluginList": pluginList, + "apiInfo": apiInfo, + "page": controller.PageInfo{ + ItemNum: len(pluginList), + }, + } + resultStr, _ := json.Marshal(result) + httpResponse.Write(resultStr) + // controller.WriteResultInfo(httpResponse, "apiPlugin", "apiPluginList", result) +} diff --git a/console/controller/strategy/strategy.go b/console/controller/strategy/strategy.go index dece7770d4ad537b16192ab39c7a7c24eb179366..cc698afd4dc4775af0ebe376f70486fc0d4d8f8e 100644 --- a/console/controller/strategy/strategy.go +++ b/console/controller/strategy/strategy.go @@ -4,20 +4,47 @@ import ( "net/http" "strconv" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/strategy" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +const operationStrategy = "strategyManagement" + +//Handlers 策略处理器 +type Handlers struct { +} + +//Handlers handlers +func (h *Handlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationStrategy, true, AddStrategy), + "/edit": factory.NewAccountHandleFunction(operationStrategy, true, EditStrategy), + "/copy": factory.NewAccountHandleFunction(operationStrategy, true, CopyStrategy), + "/delete": factory.NewAccountHandleFunction(operationStrategy, true, DeleteStrategy), + "/getInfo": factory.NewAccountHandleFunction(operationStrategy, false, GetStrategyInfo), + "/getList": factory.NewAccountHandleFunction(operationStrategy, false, GetStrategyList), + "/batchEditGroup": factory.NewAccountHandleFunction(operationStrategy, true, BatchEditStrategyGroup), + "/batchDelete": factory.NewAccountHandleFunction(operationStrategy, true, BatchDeleteStrategy), + "/batchStart": factory.NewAccountHandleFunction(operationStrategy, true, BatchStartStrategy), + "/batchStop": factory.NewAccountHandleFunction(operationStrategy, true, BatchStopStrategy), + "/id/getList": factory.NewAccountHandleFunction(operationStrategy, false, GetStrategyIDList), + } +} + +//NewStrategyHandlers new策略处理器 +func NewStrategyHandlers() *Handlers { + return &Handlers{} +} + //AddStrategy 新增策略组 func AddStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyName := httpRequest.PostFormValue("strategyName") groupID := httpRequest.PostFormValue("groupID") + userID := goku_handler.UserIDFromRequest(httpRequest) if strategyName == "" { controller.WriteError(httpResponse, "220006", @@ -37,7 +64,7 @@ func AddStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { return } - flag, result, err := strategy.AddStrategy(strategyName, gID) + flag, result, err := strategy.AddStrategy(strategyName, gID, userID) if !flag { controller.WriteError(httpResponse, @@ -54,14 +81,11 @@ func AddStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { //EditStrategy 修改策略组信息 func EditStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyName := httpRequest.PostFormValue("strategyName") strategyID := httpRequest.PostFormValue("strategyID") groupID := httpRequest.PostFormValue("groupID") + userID := goku_handler.UserIDFromRequest(httpRequest) if strategyName == "" { controller.WriteError(httpResponse, "220006", @@ -80,7 +104,7 @@ func EditStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { return } - flag, result, err := strategy.EditStrategy(strategyID, strategyName, gID) + flag, result, err := strategy.EditStrategy(strategyID, strategyName, gID, userID) if !flag { controller.WriteError(httpResponse, "220000", @@ -95,10 +119,6 @@ func EditStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { //DeleteStrategy 删除策略组 func DeleteStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") @@ -116,10 +136,6 @@ func DeleteStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) // GetOpenStrategy 获取策略组列表 func GetOpenStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } var flag bool var err error @@ -139,14 +155,22 @@ func GetOpenStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request //GetStrategyList 获取策略组列表 func GetStrategyList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() groupID := httpRequest.Form.Get("groupID") keyword := httpRequest.Form.Get("keyword") condition := httpRequest.Form.Get("condition") + page := httpRequest.Form.Get("page") + pageSize := httpRequest.Form.Get("pageSize") + + p, e := strconv.Atoi(page) + if e != nil { + p = 1 + } + pSize, e := strconv.Atoi(pageSize) + if e != nil { + pSize = 15 + } gID, err := strconv.Atoi(groupID) if err != nil { @@ -176,7 +200,7 @@ func GetStrategyList(httpResponse http.ResponseWriter, httpRequest *http.Request var flag bool err = nil result := make([]*entity.Strategy, 0) - flag, result, err = strategy.GetStrategyList(gID, keyword, op) + flag, result, count, err := strategy.GetStrategyList(gID, keyword, op, p, pSize) if !flag { controller.WriteError(httpResponse, "220000", @@ -185,15 +209,18 @@ func GetStrategyList(httpResponse http.ResponseWriter, httpRequest *http.Request err) return } - controller.WriteResultInfo(httpResponse, "strategy", "strategyList", result) + controller.WriteResultInfoWithPage(httpResponse, "strategy", "strategyList", result, &controller.PageInfo{ + ItemNum: len(result), + TotalNum: count, + Page: p, + PageSize: pSize, + }) + return } //GetStrategyIDList 获取策略组列表 func GetStrategyIDList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() groupID := httpRequest.Form.Get("groupID") keyword := httpRequest.Form.Get("keyword") @@ -238,10 +265,7 @@ func GetStrategyIDList(httpResponse http.ResponseWriter, httpRequest *http.Reque // GetStrategyInfo 获取策略组信息 func GetStrategyInfo(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() strategyID := httpRequest.Form.Get("strategyID") @@ -280,10 +304,6 @@ func GetStrategyInfo(httpResponse http.ResponseWriter, httpRequest *http.Request //BatchEditStrategyGroup 批量修改策略组分组 func BatchEditStrategyGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyIDList := httpRequest.PostFormValue("strategyIDList") groupID := httpRequest.PostFormValue("groupID") @@ -322,10 +342,6 @@ func BatchEditStrategyGroup(httpResponse http.ResponseWriter, httpRequest *http. //BatchDeleteStrategy 批量修改策略组 func BatchDeleteStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyIDList := httpRequest.PostFormValue("strategyIDList") if strategyIDList == "" { @@ -351,10 +367,6 @@ func BatchDeleteStrategy(httpResponse http.ResponseWriter, httpRequest *http.Req //BatchStartStrategy 批量开启策略 func BatchStartStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyIDList := httpRequest.PostFormValue("strategyIDList") if strategyIDList == "" { @@ -380,10 +392,6 @@ func BatchStartStrategy(httpResponse http.ResponseWriter, httpRequest *http.Requ //BatchStopStrategy 批量关闭策略 func BatchStopStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyIDList := httpRequest.PostFormValue("strategyIDList") if strategyIDList == "" { @@ -410,10 +418,7 @@ func BatchStopStrategy(httpResponse http.ResponseWriter, httpRequest *http.Reque // GetBalanceListInStrategy 获取在策略中的负载列表 func GetBalanceListInStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } + httpRequest.ParseForm() strategyID := httpRequest.Form.Get("strategyID") balanceType := httpRequest.Form.Get("balanceType") @@ -435,14 +440,11 @@ func GetBalanceListInStrategy(httpResponse http.ResponseWriter, httpRequest *htt // CopyStrategy 复制策略 func CopyStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - userID, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyName := httpRequest.PostFormValue("strategyName") strategyID := httpRequest.PostFormValue("strategyID") groupID := httpRequest.PostFormValue("groupID") + userID := goku_handler.UserIDFromRequest(httpRequest) if strategyID == "" { controller.WriteError(httpResponse, "220003", @@ -469,7 +471,7 @@ func CopyStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { return } - flag, result, err := strategy.AddStrategy(strategyName, gID) + flag, result, err := strategy.AddStrategy(strategyName, gID, userID) if !flag { controller.WriteError(httpResponse, "220000", diff --git a/console/controller/strategy/strategyGroup.go b/console/controller/strategy/strategyGroup.go index c2a8869d1a96ae37724989318ee3d139d3df6ad3..1f8b6b22967af66a0c1a8915f833af8885b5370b 100644 --- a/console/controller/strategy/strategyGroup.go +++ b/console/controller/strategy/strategyGroup.go @@ -4,16 +4,35 @@ import ( "net/http" "strconv" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/strategy" ) +const operationStrategyGroup = "strategyManagement" + +//GroupHandlers 策略分组处理器 +type GroupHandlers struct { +} + +//Handlers handlers +func (h *GroupHandlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/add": factory.NewAccountHandleFunction(operationStrategyGroup, true, AddStrategyGroup), + "/edit": factory.NewAccountHandleFunction(operationStrategyGroup, true, EditStrategyGroup), + "/delete": factory.NewAccountHandleFunction(operationStrategyGroup, true, DeleteStrategyGroup), + "/getList": factory.NewAccountHandleFunction(operationStrategyGroup, false, GetStrategyGroupList), + } +} + +//NewGroupHandlers new groupHandlers +func NewGroupHandlers() *GroupHandlers { + return &GroupHandlers{} +} + // AddStrategyGroup 新建接口分组 func AddStrategyGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } groupName := httpRequest.PostFormValue("groupName") if groupName == "" { @@ -39,10 +58,6 @@ func AddStrategyGroup(httpResponse http.ResponseWriter, httpRequest *http.Reques // EditStrategyGroup 修改接口分组 func EditStrategyGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } groupName := httpRequest.PostFormValue("groupName") groupID := httpRequest.PostFormValue("groupID") @@ -81,10 +96,6 @@ func EditStrategyGroup(httpResponse http.ResponseWriter, httpRequest *http.Reque // DeleteStrategyGroup 删除接口分组 func DeleteStrategyGroup(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } groupID := httpRequest.PostFormValue("groupID") @@ -113,10 +124,6 @@ func DeleteStrategyGroup(httpResponse http.ResponseWriter, httpRequest *http.Req // GetStrategyGroupList 获取接口分组列表 func GetStrategyGroupList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } flag, result, err := strategy.GetStrategyGroupList() if !flag { diff --git a/console/controller/strategy/strategyPlugin.go b/console/controller/strategy/strategyPlugin.go index 5c7f2b21b7df5ba028a904ae383d5ca476e0059b..c9c9733367b2dffdbeb57551bc0f1196aa2656de 100644 --- a/console/controller/strategy/strategyPlugin.go +++ b/console/controller/strategy/strategyPlugin.go @@ -4,18 +4,43 @@ import ( "net/http" "strconv" + goku_handler "github.com/eolinker/goku-api-gateway/goku-handler" + "github.com/eolinker/goku-api-gateway/console/controller" "github.com/eolinker/goku-api-gateway/console/module/plugin" plugin_config "github.com/eolinker/goku-api-gateway/console/module/plugin/plugin-config" "github.com/eolinker/goku-api-gateway/console/module/strategy" ) +const operationStrategyPlugin = "strategyManagement" + +//PluginHandlers 策略插件处理器 +type PluginHandlers struct { +} + +//Handlers handlers +func (h *PluginHandlers) Handlers(factory *goku_handler.AccountHandlerFactory) map[string]http.Handler { + return map[string]http.Handler{ + "/addPluginToStrategy": factory.NewAccountHandleFunction(operationAPIStrategy, true, AddPluginToStrategy), + "/edit": factory.NewAccountHandleFunction(operationAPIStrategy, true, EditStrategyPluginConfig), + "/getInfo": factory.NewAccountHandleFunction(operationAPIStrategy, false, GetStrategyPluginConfig), + "/getList": factory.NewAccountHandleFunction(operationAPIStrategy, false, GetStrategyPluginList), + "/checkPluginIsExist": factory.NewAccountHandleFunction(operationAPIStrategy, false, CheckPluginIsExistInStrategy), + "/getStatus": factory.NewAccountHandleFunction(operationAPIStrategy, false, GetStrategyPluginStatus), + "/batchStart": factory.NewAccountHandleFunction(operationAPIStrategy, false, BatchStartStrategyPlugin), + "/batchStop": factory.NewAccountHandleFunction(operationAPIStrategy, true, BatchStopStrategyPlugin), + "/batchDelete": factory.NewAccountHandleFunction(operationAPIStrategy, true, BatchDeleteStrategyPlugin), + } + +} + +//NewPluginHandlers new pluginHandlers +func NewPluginHandlers() *PluginHandlers { + return &PluginHandlers{} +} + //AddPluginToStrategy 新增插件到接口 func AddPluginToStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") pluginConfig := httpRequest.PostFormValue("pluginConfig") @@ -69,10 +94,6 @@ func AddPluginToStrategy(httpResponse http.ResponseWriter, httpRequest *http.Req //EditStrategyPluginConfig 修改插件信息 func EditStrategyPluginConfig(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } pluginName := httpRequest.PostFormValue("pluginName") pluginConfig := httpRequest.PostFormValue("pluginConfig") @@ -111,10 +132,7 @@ func EditStrategyPluginConfig(httpResponse http.ResponseWriter, httpRequest *htt //GetStrategyPluginList 获取策略组插件列表 func GetStrategyPluginList(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } + httpRequest.ParseForm() strategyID := httpRequest.Form.Get("strategyID") keyword := httpRequest.Form.Get("keyword") @@ -141,10 +159,6 @@ func GetStrategyPluginList(httpResponse http.ResponseWriter, httpRequest *http.R //GetStrategyPluginConfig 获取策略组插件信息 func GetStrategyPluginConfig(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") pluginName := httpRequest.PostFormValue("pluginName") @@ -156,10 +170,6 @@ func GetStrategyPluginConfig(httpResponse http.ResponseWriter, httpRequest *http //CheckPluginIsExistInStrategy 检查策略组是否绑定插件 func CheckPluginIsExistInStrategy(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") pluginName := httpRequest.PostFormValue("pluginName") @@ -190,10 +200,6 @@ func CheckPluginIsExistInStrategy(httpResponse http.ResponseWriter, httpRequest //GetStrategyPluginStatus 检查策略组插件是否开启 func GetStrategyPluginStatus(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationREAD) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") pluginName := httpRequest.PostFormValue("pluginName") @@ -226,10 +232,6 @@ func GetStrategyPluginStatus(httpResponse http.ResponseWriter, httpRequest *http //BatchStartStrategyPlugin 批量开启策略组插件 func BatchStartStrategyPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") connIDList := httpRequest.PostFormValue("connIDList") @@ -256,10 +258,6 @@ func BatchStartStrategyPlugin(httpResponse http.ResponseWriter, httpRequest *htt //BatchStopStrategyPlugin 批量修改策略组插件状态 func BatchStopStrategyPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") connIDList := httpRequest.PostFormValue("connIDList") @@ -285,10 +283,6 @@ func BatchStopStrategyPlugin(httpResponse http.ResponseWriter, httpRequest *http //BatchDeleteStrategyPlugin 批量删除策略组插件 func BatchDeleteStrategyPlugin(httpResponse http.ResponseWriter, httpRequest *http.Request) { - _, e := controller.CheckLogin(httpResponse, httpRequest, controller.OperationStrategy, controller.OperationEDIT) - if e != nil { - return - } strategyID := httpRequest.PostFormValue("strategyID") connIDList := httpRequest.PostFormValue("connIDList") diff --git a/console/controller/utils.go b/console/controller/utils.go index 8f0e5d3c7577f709f07e289dfe8d031af0fe8db8..0a51ef777c6fab259c4459500edd90c23aa362fa 100644 --- a/console/controller/utils.go +++ b/console/controller/utils.go @@ -2,39 +2,9 @@ package controller import ( "encoding/json" - "errors" + log "github.com/eolinker/goku-api-gateway/goku-log" "net/http" "reflect" - "strconv" - - log "github.com/eolinker/goku-api-gateway/goku-log" - - "github.com/eolinker/goku-api-gateway/console/module/account" -) - -const ( - //OperationEDIT 编辑 - OperationEDIT = "edit" - //OperationREAD 读取 - OperationREAD = "read" -) -const ( - //OperationNone 无操作 - OperationNone = "" - //OperationAPI 接口操作 - OperationAPI = "apiManagement" - //OperationADMIN 管理员 - OperationADMIN = "adminManagement" - //OperationLoadBalance 负载操作 - OperationLoadBalance = "loadBalance" - //OperationStrategy 策略操作 - OperationStrategy = "strategyManagement" - //OperationNode 节点操作 - OperationNode = "nodeManagement" - //OperationPlugin 插件操作 - OperationPlugin = "pluginManagement" - //OperationGatewayConfig 网关配置操作 - OperationGatewayConfig = "gatewayConfig" ) //PageInfo 页码信息 @@ -137,28 +107,3 @@ func WriteError(w http.ResponseWriter, statusCode, resultType, resultDesc string log.WithFields(ret).Debug("write error:", err) } - -//CheckLogin 判断是否登录 -func CheckLogin(w http.ResponseWriter, r *http.Request, operationType, operation string) (int, error) { - - userIDCookie, idErr := r.Cookie("userID") - userCookie, userErr := r.Cookie("userToken") - if idErr != nil || userErr != nil { - e := errors.New("user not logged in") - WriteError(w, "100001", "user", e.Error(), e) - return 0, e - } - userID, err := strconv.Atoi(userIDCookie.Value) - if err != nil { - WriteError(w, "100001", "user", "Illegal user id!", err) - return 0, err - } - flag := account.CheckLogin(userCookie.Value, userID) - if !flag { - e := errors.New("illegal users") - WriteError(w, "100001", "user", "Illegal users!", e) - return userID, e - } - - return userID, nil -} diff --git a/console/module/account/guest.go b/console/module/account/guest.go index aaec70262d8f6842f477f2f84997c5d846349b59..9f28f1cfead5f03a310e4aa7b9c76077effde459 100644 --- a/console/module/account/guest.go +++ b/console/module/account/guest.go @@ -1,27 +1,42 @@ package account import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" + +) + +var( + guestDao dao.GuestDao + userDao dao.UserDao ) +func init() { + pdao.Need(&guestDao,&userDao) +} + + //Login 登录 -func Login(loginCall, loginPassword string) (bool, int) { - return console_sqlite3.Login(loginCall, loginPassword) +func Login(loginCall, loginPassword string) (bool, int) { + return guestDao.Login(loginCall, loginPassword) } //CheckLogin 检查用户是否登录 -func CheckLogin(userToken string, userID int) bool { - return console_sqlite3.CheckLogin(userToken, userID) +func CheckLogin(userToken string, userID int) bool { + + return guestDao.CheckLogin(userToken, userID) } //Register 用户注册 -func Register(loginCall, loginPassword string) bool { - return console_sqlite3.Register(loginCall, loginPassword) +func Register(loginCall, loginPassword string) bool { + return guestDao.Register(loginCall, loginPassword) } //CheckSuperAdminCount 获取超级管理员数量 -func CheckSuperAdminCount() (int, error) { - b, err := console_sqlite3.CheckSuperAdminCount() +func CheckSuperAdminCount() (int, error) { + b, err := userDao.CheckSuperAdminCount() return b, err } + + diff --git a/console/module/account/user.go b/console/module/account/user.go index c723957a4b0fec64d5a9a80adf62fd7daa1b619b..25d343e61f384328314d15e6417bef6a5ccaec95 100644 --- a/console/module/account/user.go +++ b/console/module/account/user.go @@ -1,40 +1,26 @@ package account -import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" -) - -//GetUserListWithPermission 获取具有编辑权限的用户列表 -func GetUserListWithPermission(operationType, operation string) (bool, []map[string]interface{}, error) { - return console_sqlite3.GetUserListWithPermission(operationType, operation) -} - //EditPassword 修改账户信息 func EditPassword(oldPassword, newPassword string, userID int) (bool, string, error) { - return console_sqlite3.EditPassword(oldPassword, newPassword, userID) + return userDao.EditPassword(oldPassword, newPassword, userID) } //GetUserInfo 获取账户信息 func GetUserInfo(userID int) (bool, interface{}, error) { - return console_sqlite3.GetUserInfo(userID) + return userDao.GetUserInfo(userID) } //GetUserType 获取用户类型 func GetUserType(userID int) (bool, interface{}, error) { - return console_sqlite3.GetUserType(userID) + return userDao.GetUserType(userID) } //CheckUserIsAdmin 判断是否是管理员 func CheckUserIsAdmin(userID int) (bool, string, error) { - return console_sqlite3.CheckUserIsAdmin(userID) + return userDao.CheckUserIsAdmin(userID) } //CheckUserIsSuperAdmin 判断是否是超级管理员 func CheckUserIsSuperAdmin(userID int) (bool, string, error) { - return console_sqlite3.CheckUserIsSuperAdmin(userID) -} - -//CheckUserPermission 检查用户权限 -func CheckUserPermission(operationType, operation string, userID int) (bool, string, error) { - return console_sqlite3.CheckUserPermission(operationType, operation, userID) + return userDao.CheckUserIsSuperAdmin(userID) } diff --git a/console/module/api/api.go b/console/module/api/api.go index 1d56ec8e62610ec8f481718255351f4b2c9a3759..6e8e270bda870ef29f0a4780380f718007bcf2dd 100644 --- a/console/module/api/api.go +++ b/console/module/api/api.go @@ -1,53 +1,57 @@ package api import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) //AddAPI 新增接口 -func AddAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, managerID, userID, apiType int) (bool, int, error) { +func AddAPI(apiName, alias, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, managerID, userID, apiType int) (bool, int, error) { - flag, result, err := console_sqlite3.AddAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol, projectID, groupID, timeout, retryCount, alertValve, managerID, userID, apiType) + flag, result, err := apiDao.AddAPI(apiName, alias, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol, projectID, groupID, timeout, retryCount, alertValve, managerID, userID, apiType) return flag, result, err } //EditAPI 新增接口 -func EditAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, apiID, managerID, userID int) (bool, error) { - flag, err := console_sqlite3.EditAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol, projectID, groupID, timeout, retryCount, alertValve, apiID, managerID, userID) +func EditAPI(apiName, alias, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, apiID, managerID, userID int) (bool, error) { + flag, err := apiDao.EditAPI(apiName, alias, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkApis, staticResponse, responseDataType, balanceName, protocol, projectID, groupID, timeout, retryCount, alertValve, apiID, managerID, userID) return flag, err } //GetAPIInfo 获取接口信息 func GetAPIInfo(apiID int) (bool, *entity.API, error) { - return console_sqlite3.GetAPIInfo(apiID) + return apiDao.GetAPIInfo(apiID) } // GetAPIIDList 获取接口ID列表 func GetAPIIDList(projectID int, groupID int, keyword string, condition int, ids []int) (bool, []int, error) { - return console_sqlite3.GetAPIIDList(projectID, groupID, keyword, condition, ids) + return apiDao.GetAPIIDList(projectID, groupID, keyword, condition, ids) } // GetAPIList 获取接口列表 func GetAPIList(projectID int, groupID int, keyword string, condition, page, pageSize int, ids []int) (bool, []map[string]interface{}, int, error) { - return console_sqlite3.GetAPIList(projectID, groupID, keyword, condition, page, pageSize, ids) + return apiDao.GetAPIList(projectID, groupID, keyword, condition, page, pageSize, ids) } //CheckURLIsExist 接口路径是否存在 func CheckURLIsExist(requestURL, requestMethod string, projectID, apiID int) bool { - return console_sqlite3.CheckURLIsExist(requestURL, requestMethod, projectID, apiID) + return apiDao.CheckURLIsExist(requestURL, requestMethod, projectID, apiID) } //CheckAPIIsExist 检查接口是否存在 func CheckAPIIsExist(apiID int) (bool, error) { - return console_sqlite3.CheckAPIIsExist(apiID) + return apiDao.CheckAPIIsExist(apiID) +} + +//CheckAliasIsExist 检查接口是否存在 +func CheckAliasIsExist(apiID int, alias string) bool { + return apiDao.CheckAliasIsExist(apiID, alias) } //BatchEditAPIGroup 批量修改接口分组 func BatchEditAPIGroup(apiIDList []string, groupID int) (bool, string, error) { - r, e := console_sqlite3.BatchEditAPIGroup(apiIDList, groupID) + r, e := apiDao.BatchEditAPIGroup(apiIDList, groupID) return e == nil, r, e } @@ -55,7 +59,7 @@ func BatchEditAPIGroup(apiIDList []string, groupID int) (bool, string, error) { //BatchEditAPIBalance 批量修改接口负载 func BatchEditAPIBalance(apiIDList []string, balance string) (string, error) { - r, err := console_sqlite3.BatchEditAPIBalance(apiIDList, balance) + r, err := apiDao.BatchEditAPIBalance(apiIDList, balance) return r, err } @@ -63,7 +67,7 @@ func BatchEditAPIBalance(apiIDList []string, balance string) (string, error) { //BatchDeleteAPI 批量删除接口 func BatchDeleteAPI(apiIDList string) (bool, string, error) { - flag, result, err := console_sqlite3.BatchDeleteAPI(apiIDList) + flag, result, err := apiDao.BatchDeleteAPI(apiIDList) return flag, result, err } diff --git a/console/module/api/apiGroup.go b/console/module/api/apiGroup.go index a7275f9d73775c6da7cb4fabb998155b801d6995..bb1fd0370c4b91c131f784fd020f61edb9493686 100644 --- a/console/module/api/apiGroup.go +++ b/console/module/api/apiGroup.go @@ -1,27 +1,23 @@ package api -import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" -) - //AddAPIGroup 新建接口分组 func AddAPIGroup(groupName string, projectID, parentGroupID int) (bool, interface{}, error) { - return console_sqlite3.AddAPIGroup(groupName, projectID, parentGroupID) + return apiGroupDao.AddAPIGroup(groupName, projectID, parentGroupID) } //EditAPIGroup 修改接口分组 func EditAPIGroup(groupName string, groupID, projectID int) (bool, string, error) { - return console_sqlite3.EditAPIGroup(groupName, groupID, projectID) + return apiGroupDao.EditAPIGroup(groupName, groupID, projectID) } //DeleteAPIGroup 删除接口分组 func DeleteAPIGroup(projectID, groupID int) (bool, string, error) { - flag, result, err := console_sqlite3.DeleteAPIGroup(projectID, groupID) + flag, result, err := apiGroupDao.DeleteAPIGroup(projectID, groupID) return flag, result, err } //GetAPIGroupList 获取接口分组列表 func GetAPIGroupList(projectID int) (bool, []map[string]interface{}, error) { - return console_sqlite3.GetAPIGroupList(projectID) + return apiGroupDao.GetAPIGroupList(projectID) } diff --git a/console/module/api/apiPlugin.go b/console/module/api/apiPlugin.go index 3c594c3075ef9164d3601d52b95ab4139cfe3d66..b42b7673a1326ccd5eeb84ea5952b1b531e0b028 100644 --- a/console/module/api/apiPlugin.go +++ b/console/module/api/apiPlugin.go @@ -1,67 +1,63 @@ package api -import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" -) - //BatchEditAPIPluginStatus BatchEditAPIPluginStatus批量修改接口插件状态 func BatchEditAPIPluginStatus(connIDList, strategyID string, pluginStatus, userID int) (bool, string, error) { - flag, result, err := console_sqlite3.BatchEditAPIPluginStatus(connIDList, strategyID, pluginStatus, userID) + flag, result, err := apiPluginDao.BatchEditAPIPluginStatus(connIDList, strategyID, pluginStatus, userID) return flag, result, err } //BatchDeleteAPIPlugin 批量删除接口插件 func BatchDeleteAPIPlugin(connIDList, strategyID string) (bool, string, error) { - flag, result, err := console_sqlite3.BatchDeleteAPIPlugin(connIDList, strategyID) + flag, result, err := apiPluginDao.BatchDeleteAPIPlugin(connIDList, strategyID) return flag, result, err } //AddPluginToAPI 新增插件到接口 func AddPluginToAPI(pluginName, config, strategyID string, apiID, userID int) (bool, interface{}, error) { - flag, result, err := console_sqlite3.AddPluginToAPI(pluginName, config, strategyID, apiID, userID) + flag, result, err := apiPluginDao.AddPluginToAPI(pluginName, config, strategyID, apiID, userID) return flag, result, err } //EditAPIPluginConfig 修改接口插件配置 func EditAPIPluginConfig(pluginName, config, strategyID string, apiID, userID int) (bool, interface{}, error) { - flag, result, err := console_sqlite3.EditAPIPluginConfig(pluginName, config, strategyID, apiID, userID) + flag, result, err := apiPluginDao.EditAPIPluginConfig(pluginName, config, strategyID, apiID, userID) return flag, result, err } //GetAPIPluginList 获取接口插件列表 func GetAPIPluginList(apiID int, strategyID string) (bool, []map[string]interface{}, error) { - return console_sqlite3.GetAPIPluginList(apiID, strategyID) + return apiPluginDao.GetAPIPluginList(apiID, strategyID) } //GetPluginIndex 获取插件优先级 func GetPluginIndex(pluginName string) (bool, int, error) { - return console_sqlite3.GetPluginIndex(pluginName) + return apiPluginDao.GetPluginIndex(pluginName) } //GetAPIPluginConfig 通过ApiID获取配置信息 func GetAPIPluginConfig(apiID int, strategyID, pluginName string) (bool, map[string]string, error) { - return console_sqlite3.GetAPIPluginConfig(apiID, strategyID, pluginName) + return apiPluginDao.GetAPIPluginConfig(apiID, strategyID, pluginName) } //CheckPluginIsExistInAPI 检查策略组是否绑定插件 func CheckPluginIsExistInAPI(strategyID, pluginName string, apiID int) (bool, error) { - return console_sqlite3.CheckPluginIsExistInAPI(strategyID, pluginName, apiID) + return apiPluginDao.CheckPluginIsExistInAPI(strategyID, pluginName, apiID) } //GetAllAPIPluginInStrategy 获取策略组中所有接口插件列表 func GetAllAPIPluginInStrategy(strategyID string) (bool, []map[string]interface{}, error) { - return console_sqlite3.GetAllAPIPluginInStrategy(strategyID) + return apiPluginDao.GetAllAPIPluginInStrategy(strategyID) } // GetAPIPluginInStrategyByAPIID 获取策略组中所有接口插件列表 func GetAPIPluginInStrategyByAPIID(strategyID string, apiID int, keyword string, condition int) (bool, []map[string]interface{}, map[string]interface{}, error) { - return console_sqlite3.GetAPIPluginInStrategyByAPIID(strategyID, apiID, keyword, condition) + return apiPluginDao.GetAPIPluginInStrategyByAPIID(strategyID, apiID, keyword, condition) } //GetAPIPluginListWithNotAssignAPIList 获取没有绑定插件得接口列表 func GetAPIPluginListWithNotAssignAPIList(strategyID string) (bool, []map[string]interface{}, error) { - return console_sqlite3.GetAPIPluginListWithNotAssignAPIList(strategyID) + return apiPluginDao.GetAPIPluginListWithNotAssignAPIList(strategyID) } diff --git a/console/module/api/apiStrategy.go b/console/module/api/apiStrategy.go index 5bc7ce64a82d3007276b4ec087a77d8cbcb03a7b..5b383bc9d3422a6682678c7ad4b7340c02488ef8 100644 --- a/console/module/api/apiStrategy.go +++ b/console/module/api/apiStrategy.go @@ -1,58 +1,54 @@ package api -import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" -) - //AddAPIToStrategy 将接口加入策略组 func AddAPIToStrategy(apiList []string, strategyID string) (bool, string, error) { - flag, result, err := console_sqlite3.AddAPIToStrategy(apiList, strategyID) + flag, result, err := apiStrategyDao.AddAPIToStrategy(apiList, strategyID) return flag, result, err } //SetTarget 重置目标地址 func SetTarget(apiID int, strategyID string, target string) (bool, string, error) { - flag, result, err := console_sqlite3.SetAPITargetOfStrategy(apiID, strategyID, target) + flag, result, err := apiStrategyDao.SetAPITargetOfStrategy(apiID, strategyID, target) return flag, result, err } // BatchSetTarget 批量重置目标地址 func BatchSetTarget(apiIds []int, strategyID string, target string) (bool, string, error) { - flag, result, err := console_sqlite3.BatchSetAPITargetOfStrategy(apiIds, strategyID, target) + flag, result, err := apiStrategyDao.BatchSetAPITargetOfStrategy(apiIds, strategyID, target) return flag, result, err } // GetAPIIDListFromStrategy 获取策略组接口ID列表 func GetAPIIDListFromStrategy(strategyID, keyword string, condition int, ids []int, balanceNames []string) (bool, []int, error) { - return console_sqlite3.GetAPIIDListFromStrategy(strategyID, keyword, condition, ids, balanceNames) + return apiStrategyDao.GetAPIIDListFromStrategy(strategyID, keyword, condition, ids, balanceNames) } // GetAPIListFromStrategy 获取策略组接口列表 func GetAPIListFromStrategy(strategyID, keyword string, condition, page, pageSize int, ids []int, balanceNames []string) (bool, []map[string]interface{}, int, error) { - return console_sqlite3.GetAPIListFromStrategy(strategyID, keyword, condition, page, pageSize, ids, balanceNames) + return apiStrategyDao.GetAPIListFromStrategy(strategyID, keyword, condition, page, pageSize, ids, balanceNames) } //CheckIsExistAPIInStrategy 检查插件是否添加进策略组 func CheckIsExistAPIInStrategy(apiID int, strategyID string) (bool, string, error) { - return console_sqlite3.CheckIsExistAPIInStrategy(apiID, strategyID) + return apiStrategyDao.CheckIsExistAPIInStrategy(apiID, strategyID) } // GetAPIIDListNotInStrategy 获取未被该策略组绑定的接口ID列表(通过项目) func GetAPIIDListNotInStrategy(strategyID string, projectID, groupID int, keyword string) (bool, []int, error) { - return console_sqlite3.GetAPIIDListNotInStrategy(strategyID, projectID, groupID, keyword) + return apiStrategyDao.GetAPIIDListNotInStrategy(strategyID, projectID, groupID, keyword) } // GetAPIListNotInStrategy 获取未被该策略组绑定的接口列表(通过项目) func GetAPIListNotInStrategy(strategyID string, projectID, groupID, page, pageSize int, keyword string) (bool, []map[string]interface{}, int, error) { - return console_sqlite3.GetAPIListNotInStrategy(strategyID, projectID, groupID, page, pageSize, keyword) + return apiStrategyDao.GetAPIListNotInStrategy(strategyID, projectID, groupID, page, pageSize, keyword) } //BatchDeleteAPIInStrategy 批量删除策略组接口 func BatchDeleteAPIInStrategy(apiIDList, strategyID string) (bool, string, error) { - flag, result, err := console_sqlite3.BatchDeleteAPIInStrategy(apiIDList, strategyID) + flag, result, err := apiStrategyDao.BatchDeleteAPIInStrategy(apiIDList, strategyID) return flag, result, err } diff --git a/console/module/api/dao.go b/console/module/api/dao.go new file mode 100644 index 0000000000000000000000000000000000000000..26dddaef63774d83efc43d8ac68d05001f9521c9 --- /dev/null +++ b/console/module/api/dao.go @@ -0,0 +1,18 @@ +package api + +import ( + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" +) + +var( + apiDao dao.APIDao + apiGroupDao dao.APIGroupDao + apiPluginDao dao.APIPluginDao + apiStrategyDao dao.APIStrategyDao + importDao dao.ImportDao +) + +func init() { + pdao.Need(&apiDao,&apiGroupDao,&apiPluginDao,&apiStrategyDao,&importDao) +} \ No newline at end of file diff --git a/console/module/api/import.go b/console/module/api/import.go index 924848920eb02eda26fa26c12b497c6fc7cf25a4..917b0a9ddbae1a294210d361da2e05ad50c26825 100644 --- a/console/module/api/import.go +++ b/console/module/api/import.go @@ -1,27 +1,26 @@ package api import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) //ImportAPIGroupFromAms 导入接口分组 func ImportAPIGroupFromAms(projectID, userID int, groupInfo entity.AmsGroupInfo) (bool, string, error) { - flag, result, err := console_sqlite3.ImportAPIGroupFromAms(projectID, userID, groupInfo) + flag, result, err := importDao.ImportAPIGroupFromAms(projectID, userID, groupInfo) return flag, result, err } //ImportProjectFromAms 导入项目 func ImportProjectFromAms(userID int, projectInfo entity.AmsProject) (bool, string, error) { - flag, result, err := console_sqlite3.ImportProjectFromAms(userID, projectInfo) + flag, result, err := importDao.ImportProjectFromAms(userID, projectInfo) return flag, result, err } //ImportAPIFromAms 导入接口 func ImportAPIFromAms(projectID, groupID, userID int, apiList []entity.AmsAPIInfo) (bool, string, error) { - flag, result, err := console_sqlite3.ImportAPIFromAms(projectID, groupID, userID, apiList) + flag, result, err := importDao.ImportAPIFromAms(projectID, groupID, userID, apiList) return flag, result, err } diff --git a/console/module/auth/auth.go b/console/module/auth/auth.go index 996c3180194bbc23a8d51173df608d1c7cab1cbd..b4380a8cd9b3741f2eb4e7eb461bd6718186e214 100644 --- a/console/module/auth/auth.go +++ b/console/module/auth/auth.go @@ -1,22 +1,29 @@ package auth import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" +) +var ( + authDao dao.AuthDao ) +func init() { + pdao.Need(&authDao) +} //GetAuthStatus 获取认证状态 func GetAuthStatus(strategyID string) (bool, map[string]interface{}, error) { - return console_sqlite3.GetAuthStatus(strategyID) + return authDao.GetAuthStatus(strategyID) } //GetAuthInfo 获取认证信息 func GetAuthInfo(strategyID string) (bool, map[string]interface{}, error) { - return console_sqlite3.GetAuthInfo(strategyID) + return authDao.GetAuthInfo(strategyID) } //EditAuthInfo 编辑认证信息 func EditAuthInfo(strategyID, strategyName, basicAuthList, apikeyList, jwtCredentialList, oauth2CredentialList string, delClientIDList []string) (bool, error) { - flag, err := console_sqlite3.EditAuthInfo(strategyID, strategyName, basicAuthList, apikeyList, + flag, err := authDao.EditAuthInfo(strategyID, strategyName, basicAuthList, apikeyList, jwtCredentialList, oauth2CredentialList, delClientIDList) return flag, err diff --git a/console/module/balance/balance.go b/console/module/balance/balance.go index 075a88fbd23e96a3032955b6091a6cbbf1ae118c..16937085b64a4736cdb0ecfc77a09d4aeb120438 100644 --- a/console/module/balance/balance.go +++ b/console/module/balance/balance.go @@ -5,14 +5,12 @@ import ( "fmt" "time" - dao_balance "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-balance" - "github.com/eolinker/goku-api-gateway/console/module/service" driver2 "github.com/eolinker/goku-api-gateway/server/driver" entity "github.com/eolinker/goku-api-gateway/server/entity/balance-entity-service" ) -//Add 新增负载 +//RegisterDao 新增负载 func Add(info *Param) (string, error) { serviceInfo, err := service.Get(info.ServiceName) if err != nil { @@ -25,7 +23,7 @@ func Add(info *Param) (string, error) { return "param:static 和 staticCluster 不能同时为空", errors.New("param:static 和 staticCluster 不能同时为空") } now := time.Now().Format("2006-01-02 15:04:05") - result, err := dao_balance.AddStatic(info.Name, info.ServiceName, info.Static, info.StaticCluster, info.Desc, now) + result, err := balanceDao.AddStatic(info.Name, info.ServiceName, info.Static, info.StaticCluster, info.Desc, now) return result, err } @@ -35,7 +33,7 @@ func Add(info *Param) (string, error) { return "param:appName 不能为空", errors.New("param:appName 不能为空") } now := time.Now().Format("2006-01-02 15:04:05") - result, err := dao_balance.AddDiscovery(info.Name, info.ServiceName, info.AppName, info.Desc, now) + result, err := balanceDao.AddDiscovery(info.Name, info.ServiceName, info.AppName, info.Desc, now) return result, err } @@ -58,7 +56,7 @@ func Save(info *Param) (string, error) { return "param:static 和 staticCluster 不能同时为空", errors.New("param:static 和 staticCluster 不能同时为空") } now := time.Now().Format("2006-01-02 15:04:05") - result, err := dao_balance.SaveStatic(info.Name, info.ServiceName, info.Static, info.StaticCluster, info.Desc, now) + result, err := balanceDao.SaveStatic(info.Name, info.ServiceName, info.Static, info.StaticCluster, info.Desc, now) return result, err } @@ -68,7 +66,7 @@ func Save(info *Param) (string, error) { return "param:appName 不能为空", errors.New("param:appName 不能为空") } now := time.Now().Format("2006-01-02 15:04:05") - result, err := dao_balance.SaveDiscover(info.Name, info.ServiceName, info.AppName, info.Desc, now) + result, err := balanceDao.SaveDiscover(info.Name, info.ServiceName, info.AppName, info.Desc, now) return result, err } @@ -80,7 +78,7 @@ func Save(info *Param) (string, error) { //Get 通过负载名称获取负载信息 func Get(name string) (*Info, error) { - b, e := dao_balance.Get(name) + b, e := balanceDao.Get(name) if e != nil { return nil, e } @@ -92,13 +90,13 @@ func Get(name string) (*Info, error) { func Search(keyworkd string) ([]*Info, error) { var entities []*entity.Balance if keyworkd == "" { - es, e := dao_balance.GetAll() + es, e := balanceDao.GetAll() if e != nil { return nil, e } entities = es } else { - es, e := dao_balance.Search(keyworkd) + es, e := balanceDao.Search(keyworkd) if e != nil { return nil, e } @@ -107,7 +105,13 @@ func Search(keyworkd string) ([]*Info, error) { infos := make([]*Info, 0, len(entities)) + useBalances, _ := balanceDao.GetUseBalanceNames() for _, ent := range entities { + if useBalances != nil { + if _, ok := useBalances[ent.Name]; ok { + ent.CanDelete = 0 + } + } infos = append(infos, ReadInfo(ent)) } return infos, nil @@ -116,13 +120,18 @@ func Search(keyworkd string) ([]*Info, error) { //GetAll 获取所有负载列表 func GetAll() ([]*Info, error) { - entities, e := dao_balance.GetAll() + entities, e := balanceDao.GetAll() if e != nil { return nil, e } infos := make([]*Info, 0, len(entities)) - + useBalances, _ := balanceDao.GetUseBalanceNames() for _, ent := range entities { + if useBalances != nil { + if _, ok := useBalances[ent.Name]; ok { + ent.CanDelete = 0 + } + } infos = append(infos, ReadInfo(ent)) } return infos, nil @@ -130,19 +139,19 @@ func GetAll() ([]*Info, error) { //Delete 删除负载 func Delete(name string) (string, error) { - result, err := dao_balance.Delete(name) + result, err := balanceDao.Delete(name) return result, err } //GetBalancNames 获取负载名称列表 func GetBalancNames() (bool, []string, error) { - return dao_balance.GetBalanceNames() + return balanceDao.GetBalanceNames() } //BatchDeleteBalance 批量删除负载 func BatchDeleteBalance(balanceNames []string) (string, error) { - result, err := dao_balance.BatchDelete(balanceNames) + result, err := balanceDao.BatchDelete(balanceNames) return result, err } diff --git a/console/module/balance/param.go b/console/module/balance/param.go index 1de64bce1021865345330210cfaccf6b2035645a..1f740f7339ee85bc4fa08be7d4d33ba383895f7a 100644 --- a/console/module/balance/param.go +++ b/console/module/balance/param.go @@ -28,6 +28,7 @@ type Info struct { Desc string `json:"balanceDesc"` CreateTime string `json:"createTime"` UpdateTime string `json:"updateTime"` + CanDelete int `json:"canDelete"` } //ReadInfo 读取负载信息 @@ -43,6 +44,7 @@ func ReadInfo(balance *entity.Balance) *Info { Desc: balance.Desc, CreateTime: balance.CreateTime, UpdateTime: balance.UpdateTime, + CanDelete: balance.CanDelete, } json.Unmarshal([]byte(balance.StaticCluster), &info.StaticCluster) return info diff --git a/console/module/balance/update.go b/console/module/balance/update.go index 083f61422fd50809ad2a21f6ab02e43a0f49bd7f..51dd380cf001b5661e93eb05b676239332f13e36 100644 --- a/console/module/balance/update.go +++ b/console/module/balance/update.go @@ -2,25 +2,30 @@ package balance import ( "encoding/json" + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" "github.com/eolinker/goku-api-gateway/common/general" - dao_balance_update2 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-balance-update" entity "github.com/eolinker/goku-api-gateway/server/entity/balance-entity" ) - +var ( + balanceDao dao.BalanceDao + balanceUpdateDao dao.BalanceUpdateDao +) func init() { + pdao.Need(&balanceDao,&balanceUpdateDao) general.RegeditLater(Update) } //Update 将旧负载配置更新为新负载配置 func Update() error { - l, e := dao_balance_update2.GetAllOldVerSion() + l, e := balanceUpdateDao.GetAllOldVerSion() if e != nil { return e } - defStaticServiceName := dao_balance_update2.GetDefaultServiceStatic() + defStaticServiceName := balanceUpdateDao.GetDefaultServiceStatic() for _, e := range l { update(e, defStaticServiceName) } diff --git a/console/module/cluster/cluster.go b/console/module/cluster/cluster.go index beab2bd9fa3dce1d69582930de863a239ae3e85d..720fd40700a42e3f8d448c19255b6beb65295594 100644 --- a/console/module/cluster/cluster.go +++ b/console/module/cluster/cluster.go @@ -1,46 +1,53 @@ package cluster import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +var ( + clusterDao dao.ClusterDao +) +func init() { + pdao.Need(&clusterDao) +} //AddCluster 新增集群 func AddCluster(name, title, note string) error { - return console_sqlite3.AddCluster(name, title, note) + return clusterDao.AddCluster(name, title, note) } //EditCluster 修改集群信息 func EditCluster(name, title, note string) error { - return console_sqlite3.EditCluster(name, title, note) + return clusterDao.EditCluster(name, title, note) } //DeleteCluster 删除集群 func DeleteCluster(name string) error { - return console_sqlite3.DeleteCluster(name) + return clusterDao.DeleteCluster(name) } //GetClusters 获取集群列表 func GetClusters() ([]*entity.Cluster, error) { - return console_sqlite3.GetClusters() + return clusterDao.GetClusters() } //GetCluster 获取集群信息 func GetCluster(name string) (*entity.Cluster, error) { - return console_sqlite3.GetCluster(name) + return clusterDao.GetCluster(name) } //GetClusterNodeCount 获取集群节点数量 func GetClusterNodeCount(name string) int { - return console_sqlite3.GetClusterNodeCount(name) + return clusterDao.GetClusterNodeCount(name) } //CheckClusterNameIsExist 判断集群名称是否存在 func CheckClusterNameIsExist(name string) bool { - return console_sqlite3.CheckClusterNameIsExist(name) + return clusterDao.CheckClusterNameIsExist(name) } //GetClusterIDByName 获取集群节点数量 func GetClusterIDByName(name string) int { - return console_sqlite3.GetClusterIDByName(name) + return clusterDao.GetClusterIDByName(name) } diff --git a/console/module/config-log/dao.go b/console/module/config-log/dao.go new file mode 100644 index 0000000000000000000000000000000000000000..4bdab4c1389ccb7e0873e12018a843d5e58e1e89 --- /dev/null +++ b/console/module/config-log/dao.go @@ -0,0 +1,14 @@ +package config_log + +import ( + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" +) + +var ( + configLogDao dao.ConfigLogDao +) + +func init() { + pdao.Need(&configLogDao) +} \ No newline at end of file diff --git a/console/module/config-log/get.go b/console/module/config-log/get.go index 52ed06166004e58cbefa518b0a1e44cdcce93668..700dcb2429daa9817a017510e061149523165b74 100644 --- a/console/module/config-log/get.go +++ b/console/module/config-log/get.go @@ -5,7 +5,6 @@ import ( "github.com/eolinker/goku-api-gateway/common/auto-form" log "github.com/eolinker/goku-api-gateway/goku-log" - config_log "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/config-log" ) //Get 获取普通日志配置 @@ -18,7 +17,7 @@ func Get(name string) (*LogConfig, error) { c.Levels = Levels c.Periods = Periods c.Expires = Expires - config, e := config_log.Get(name) + config, e := configLogDao.Get(name) if e != nil || config == nil { auto.SetDefaults(c) @@ -36,7 +35,7 @@ func Get(name string) (*LogConfig, error) { //GetAccess 获取access配置 func GetAccess() (*AccessConfig, error) { - config, e := config_log.Get(AccessLog) + config, e := configLogDao.Get(AccessLog) c := new(AccessConfig) c.Periods = Periods c.Expires = Expires diff --git a/console/module/config-log/set.go b/console/module/config-log/set.go index 3216f1e0610dd4f714ff8c8abdd704070efc40e4..a4d5f0c9c388c550939face118bed191baa6fcb9 100644 --- a/console/module/config-log/set.go +++ b/console/module/config-log/set.go @@ -4,7 +4,6 @@ import ( "fmt" log "github.com/eolinker/goku-api-gateway/goku-log" - config_log "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/config-log" entity "github.com/eolinker/goku-api-gateway/server/entity/config-log" ) @@ -27,7 +26,7 @@ func Set(name string, param *Param) error { } c.Fields = param.Fields c.Expire = param.Expire - err := config_log.Set(c) + err := configLogDao.Set(c) if err != nil { return err } diff --git a/console/module/gateway/gateway.go b/console/module/gateway/gateway.go index fbe4654983f823fb4b2dd5b5241919f8596654f0..81aa7ee03b6e7003ab2907a91ac8cf9e4ee4e49d 100644 --- a/console/module/gateway/gateway.go +++ b/console/module/gateway/gateway.go @@ -1,10 +1,22 @@ package gateway import ( + "github.com/eolinker/goku-api-gateway/common/pdao" v "github.com/eolinker/goku-api-gateway/common/version" - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" + "github.com/eolinker/goku-api-gateway/server/dao" + entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +var ( + gatewayDao dao.GatewayDao + pluginDao dao.PluginDao + clusterDao dao.ClusterDao +) + +func init() { + pdao.Need(&gatewayDao, &pluginDao, &clusterDao) +} + //BaseGatewayInfo 网关基本配置 type BaseGatewayInfo struct { NodeCount int `json:"nodeCount"` @@ -25,37 +37,36 @@ type SystemInfo struct { //GetGatewayConfig 获取网关配置 func GetGatewayConfig() (map[string]interface{}, error) { - return console_sqlite3.GetGatewayConfig() + return gatewayDao.GetGatewayConfig() } //EditGatewayBaseConfig 编辑网关基本配置 func EditGatewayBaseConfig(successCode string, nodeUpdatePeriod, monitorUpdatePeriod, timeout int) (bool, string, error) { - flag, result, err := console_sqlite3.EditGatewayBaseConfig(successCode, nodeUpdatePeriod, monitorUpdatePeriod, timeout) - return flag, result, err -} - -//EditGatewayAlarmConfig 编辑网关告警配置 -func EditGatewayAlarmConfig(apiAlertInfo, sender, senderPassword, smtpAddress string, alertStatus, smtpPort, smtpProtocol int) (bool, string, error) { - flag, result, err := console_sqlite3.EditGatewayAlarmConfig(apiAlertInfo, sender, senderPassword, smtpAddress, alertStatus, smtpPort, smtpProtocol) - + config := entity.GatewayBasicConfig{ + SuccessCode: successCode, + NodeUpdatePeriod: nodeUpdatePeriod, + MonitorUpdatePeriod: monitorUpdatePeriod, + MonitorTimeout: timeout, + } + flag, result, err := gatewayDao.EditGatewayBaseConfig(config) return flag, result, err } //GetGatewayMonitorSummaryByPeriod 获取监控summary func GetGatewayMonitorSummaryByPeriod() (bool, *SystemInfo, error) { - nodeStartCount, nodeStopCount, projectCount, apiCount, strategyCount, e := console_sqlite3.GetGatewayInfo() + nodeStartCount, nodeStopCount, projectCount, apiCount, strategyCount, e := gatewayDao.GetGatewayInfo() if e != nil { return false, nil, e } info := new(SystemInfo) - info.BaseInfo.PluginCount = console_sqlite3.GetPluginCount() + info.BaseInfo.PluginCount = pluginDao.GetPluginCount() info.BaseInfo.NodeCount = nodeStartCount + nodeStopCount info.BaseInfo.ProjectCount = projectCount info.BaseInfo.APICount = apiCount info.BaseInfo.StrategyCount = strategyCount info.BaseInfo.Version = v.Version - info.BaseInfo.ClusterCount = console_sqlite3.GetClusterCount() + info.BaseInfo.ClusterCount = clusterDao.GetClusterCount() return true, info, nil diff --git a/console/module/monitor/module.go b/console/module/monitor/module.go index 80b2293b26ff60eba620b60ff1e6e13649077885..76f21163dca0b6a61b095f478eeaf74e75065901 100644 --- a/console/module/monitor/module.go +++ b/console/module/monitor/module.go @@ -1,11 +1,20 @@ package monitor import ( + "github.com/eolinker/goku-api-gateway/common/general" + "github.com/eolinker/goku-api-gateway/common/pdao" "github.com/eolinker/goku-api-gateway/ksitigarbha" - - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" + "github.com/eolinker/goku-api-gateway/server/dao" "github.com/pkg/errors" ) +var( + monitorModuleDao dao.MonitorModulesDao +) + +func init() { + pdao.Need(&monitorModuleDao) + general.RegeditLater(InitModuleStatus) +} type MonitorModule struct { Name string `json:"moduleName"` @@ -14,31 +23,54 @@ type MonitorModule struct { Desc string `json:"moduleDesc"` Models interface{} `json:"layer"` } +// 初始化监控模块的配置状态 +func InitModuleStatus() error { + modules, err := monitorModuleDao.GetMonitorModules() + if err != nil { + return err + } + + names := ksitigarbha.GetMonitorModuleNames() + + for _, name := range names { + + if m,has:= modules[name];has{ + if m.ModuleStatus == 1{ + ksitigarbha.Open(name,m.Config) + }else{ + ksitigarbha.Close(name) + } + }else{ + ksitigarbha.Close(name) + } + } + return nil +} //GetMonitorModules 获取监控模块列表 func GetMonitorModules() ([]*MonitorModule, error) { - m, err := console_sqlite3.GetMonitorModules() + m, err := monitorModuleDao.GetMonitorModules() if err != nil { - return make([]*MonitorModule, 0), nil + return nil, err } names := ksitigarbha.GetMonitorModuleNames() modules := make([]*MonitorModule, 0, len(names)) for _, name := range names { - model,_ := ksitigarbha.GetMonitorModuleModel(name) - mod :=&MonitorModule{ - Name: name, - Config: model.GetDefaultConfig(), - ModuleStatus: 0, - Desc: model.GetDesc(), - Models: model.GetModel(), - } + model, _ := ksitigarbha.GetMonitorModuleModel(name) + mod := &MonitorModule{ + Name: name, + Config: model.GetDefaultConfig(), + ModuleStatus: 0, + Desc: model.GetDesc(), + Models: model.GetModel(), + } v, ok := m[name] if ok { mod.ModuleStatus = v.ModuleStatus - c ,err := model.Decode(v.Config) + c, err := model.Decode(v.Config) if err == nil { mod.Config = c } @@ -51,22 +83,21 @@ func GetMonitorModules() ([]*MonitorModule, error) { func SetMonitorModule(moduleName string, config string, moduleStatus int) error { - model,has := ksitigarbha.GetMonitorModuleModel(moduleName) + model, has := ksitigarbha.GetMonitorModuleModel(moduleName) if !has { return errors.New("[error]the module does not exist") } - if moduleStatus == 1 { + if moduleStatus == 1 { - _ ,err:= model.Decode(config) - if err != nil{ + _, err := model.Decode(config) + if err != nil { //errInfo := "[error]invalid config" return err } - } - err := console_sqlite3.SetMonitorModule(moduleName, config, moduleStatus) + err := monitorModuleDao.SetMonitorModule(moduleName, config, moduleStatus) if err != nil { return err } diff --git a/console/module/node/Locker_test.go b/console/module/node/Locker_test.go index c2cce1ca1e9d67c20c4d8605641535bf22eae860..f250801f1a1dc240fd6f8836d19f55521aeff3e1 100644 --- a/console/module/node/Locker_test.go +++ b/console/module/node/Locker_test.go @@ -4,27 +4,27 @@ import "testing" func Test_InstanceLocker_Lock(t *testing.T) { - l:=newInstanceLocker() - instance:="test" - if !l.Lock(instance){ + l := newInstanceLocker() + instance := "test" + if !l.Lock(instance) { t.Error("should lock true") return } - if l.Lock(instance){ + if l.Lock(instance) { t.Error("should lock false") return } l.UnLock(instance) - if !l.Lock(instance){ + if !l.Lock(instance) { t.Error("should lock true") return } - if l.Lock(instance){ + if l.Lock(instance) { t.Error("should lock false") return } -} \ No newline at end of file +} diff --git a/console/module/node/dao.go b/console/module/node/dao.go new file mode 100644 index 0000000000000000000000000000000000000000..364f52df30ea947bf1e5a92dab3f0e3f2604db88 --- /dev/null +++ b/console/module/node/dao.go @@ -0,0 +1,15 @@ +package node + +import ( + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" +) + +var ( + nodeDao dao.NodeDao + nodeGroupDao dao.NodeGroupDao +) + +func init() { + pdao.Need(&nodeDao,&nodeGroupDao) +} \ No newline at end of file diff --git a/console/module/node/node.go b/console/module/node/node.go index 1421f338519583dcda224ec86e22d60fd208c478..024f3c145d7108eabd7b1d6f2de0bf81f9d6a5c0 100644 --- a/console/module/node/node.go +++ b/console/module/node/node.go @@ -3,66 +3,80 @@ package node import ( "time" - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" "github.com/eolinker/goku-api-gateway/utils" ) //AddNode 新增节点信息 -func AddNode(clusterID int, nodeName, listenAddress, adminAddress, gatewayPath string, groupID int) (bool, map[string]interface{}, error) { +func AddNode(clusterID int, nodeName, listenAddress, adminAddress, gatewayPath string, groupID int) (int64, string, string, error) { now := time.Now().Format("20060102150405") nodeKey := utils.Md5(utils.GetRandomString(16) + now) - return console_sqlite3.AddNode(clusterID, nodeName, nodeKey, listenAddress, adminAddress, gatewayPath, groupID) + return nodeDao.AddNode(clusterID, nodeName, nodeKey, listenAddress, adminAddress, gatewayPath, groupID) } //EditNode 修改节点 -func EditNode(nodeName, listenAddress, adminAddress, gatewayPath string, nodeID, groupID int) (bool, string, error) { - return console_sqlite3.EditNode(nodeName, listenAddress, adminAddress, gatewayPath, nodeID, groupID) +func EditNode(nodeName, listenAddress, adminAddress, gatewayPath string, nodeID, groupID int) (string, error) { + return nodeDao.EditNode(nodeName, listenAddress, adminAddress, gatewayPath, nodeID, groupID) } //DeleteNode 删除节点 -func DeleteNode(nodeID int) (bool, string, error) { - return console_sqlite3.DeleteNode(nodeID) +func DeleteNode(nodeID int) (string, error) { + return nodeDao.DeleteNode(nodeID) } //GetNodeInfo 获取节点信息 -func GetNodeInfo(nodeID int) ( *entity.Node, error) { - node, e := console_sqlite3.GetNodeInfo(nodeID) +func GetNodeInfo(nodeID int) (*entity.Node, error) { + node, e := nodeDao.GetNodeInfo(nodeID) + if e != nil { + return nil, e + } ResetNodeStatus(node) - return node, e + return node, e } //GetNodeInfoByKey 获取节点信息 -func GetNodeInfoByKey(nodeKey string) ( *entity.Node, error) { - node, e := console_sqlite3.GetNodeByKey(nodeKey) +func GetNodeInfoByKey(nodeKey string) (*entity.Node, error) { + node, e := nodeDao.GetNodeByKey(nodeKey) + if e != nil { + return nil, e + } ResetNodeStatus(node) - return node, e + return node, e } + // GetNodeList 获取节点列表 -func GetNodeList(clusterID, groupID int, keyword string) (bool, []*entity.Node, error) { - b, nodes, e := console_sqlite3.GetNodeList(clusterID, groupID, keyword) +func GetNodeList(clusterID, groupID int, keyword string) ([]*entity.Node, error) { + nodes, e := nodeDao.GetNodeList(clusterID, groupID, keyword) + if e != nil { + return nil, e + } ResetNodeStatus(nodes...) - return b, nodes, e + return nodes, e } +//GetAllNode 获取所有节点 +func GetAllNode() ([]*entity.Node, error) { + nodes, e := nodeDao.GetNodeInfoAll() + if e != nil { + return nil, e + } + + return nodes, e +} //BatchDeleteNode 批量删除节点 -func BatchDeleteNode(nodeIDList string) (bool, string, error) { - flag, nodeIDList, err := console_sqlite3.GetAvaliableNodeListFromNodeList(nodeIDList, 0) - if !flag { - return false, err.Error(), err - } else if nodeIDList == "" { - return false, "230013", err +func BatchDeleteNode(nodeIDList string) (string, error) { + nodeIDList, err := nodeDao.GetAvaliableNodeListFromNodeList(nodeIDList, 0) + if err != nil { + return err.Error(), err + } + if nodeIDList == "" { + return "230013", err } - return console_sqlite3.BatchDeleteNode(nodeIDList) + return nodeDao.BatchDeleteNode(nodeIDList) } //BatchEditNodeGroup 批量修改节点分组 -func BatchEditNodeGroup(nodeIDList string, groupID int) (bool, string, error) { - return console_sqlite3.BatchEditNodeGroup(nodeIDList, groupID) +func BatchEditNodeGroup(nodeIDList string, groupID int) (string, error) { + return nodeDao.BatchEditNodeGroup(nodeIDList, groupID) } -// -////GetNodeIPList 获取节点IP列表 -//func GetNodeIPList() (bool, []map[string]interface{}, error) { -// return console_sqlite3.GetNodeIPList() -//} diff --git a/console/module/node/nodeGroup.go b/console/module/node/nodeGroup.go index 33de70e9f4a3828e91c719be9ffd06fe410fd1aa..cb60cf419afdd432279da8960cc9e8917de7ba35 100644 --- a/console/module/node/nodeGroup.go +++ b/console/module/node/nodeGroup.go @@ -1,40 +1,36 @@ package node -import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" -) - //AddNodeGroup 新建节点分组 func AddNodeGroup(groupName string, clusterID int) (bool, interface{}, error) { - return console_sqlite3.AddNodeGroup(groupName, clusterID) + return nodeGroupDao.AddNodeGroup(groupName, clusterID) } //EditNodeGroup 修改节点分组信息 func EditNodeGroup(groupName string, groupID int) (bool, string, error) { - return console_sqlite3.EditNodeGroup(groupName, groupID) + return nodeGroupDao.EditNodeGroup(groupName, groupID) } //DeleteNodeGroup 删除节点分组 func DeleteNodeGroup(groupID int) (bool, string, error) { - return console_sqlite3.DeleteNodeGroup(groupID) + return nodeGroupDao.DeleteNodeGroup(groupID) } //GetNodeGroupInfo 获取节点分组信息 func GetNodeGroupInfo(groupID int) (bool, map[string]interface{}, error) { - return console_sqlite3.GetNodeGroupInfo(groupID) + return nodeGroupDao.GetNodeGroupInfo(groupID) } //GetNodeGroupList 获取节点分组列表 func GetNodeGroupList(clusterID int) (bool, []map[string]interface{}, error) { - return console_sqlite3.GetNodeGroupList(clusterID) + return nodeGroupDao.GetNodeGroupList(clusterID) } //CheckNodeGroupIsExist 检查节点分组是否存在 func CheckNodeGroupIsExist(groupID int) (bool, error) { - return console_sqlite3.CheckNodeGroupIsExist(groupID) + return nodeGroupDao.CheckNodeGroupIsExist(groupID) } //GetRunningNodeCount 获取分组内启动节点数量 func GetRunningNodeCount(groupID int) (bool, interface{}, error) { - return console_sqlite3.GetRunningNodeCount(groupID) + return nodeGroupDao.GetRunningNodeCount(groupID) } diff --git a/console/module/node/status.go b/console/module/node/status.go index 6a17e9bb5afe3ed87ac73c9ec1df7ad5022bb740..35c4d4838289d99e97beed5a6c23a39760f7c3bd 100644 --- a/console/module/node/status.go +++ b/console/module/node/status.go @@ -8,7 +8,7 @@ import ( ) //EXPIRE 心跳检测过期时间 -const EXPIRE = time.Second * 5 +const EXPIRE = time.Second * 10 var ( manager = _StatusManager{ @@ -25,11 +25,16 @@ type _StatusManager struct { func (m *_StatusManager) refresh(id string) { t := time.Now() + //heartBeat, err := nodeDao.GetHeartBeatTime(id) + //if err == nil { + // t = heartBeat + //} m.locker.Lock() m.lastHeartBeat[id] = t m.locker.Unlock() + nodeDao.SetHeartBeatTime(id, time.Now()) } func (m *_StatusManager) stop(id string) { @@ -48,7 +53,7 @@ func (m *_StatusManager) get(id string) (time.Time, bool) { } type _InstanceLocker struct { - locker sync.RWMutex + locker sync.RWMutex instances map[string]bool } @@ -58,22 +63,22 @@ func newInstanceLocker() *_InstanceLocker { instances: make(map[string]bool), } } -func (l * _InstanceLocker)IsLock(key string)bool { +func (l *_InstanceLocker) IsLock(key string) bool { l.locker.RLock() - locked :=l.instances[key] + locked := l.instances[key] l.locker.RUnlock() return locked } -func (l * _InstanceLocker)Lock(key string)bool{ +func (l *_InstanceLocker) Lock(key string) bool { - locked :=l.IsLock(key) - if locked{ + locked := l.IsLock(key) + if locked { return false } l.locker.Lock() - locked =l.instances[key] - if locked{ + locked = l.instances[key] + if locked { l.locker.Unlock() return false } @@ -81,7 +86,7 @@ func (l * _InstanceLocker)Lock(key string)bool{ l.locker.Unlock() return true } -func (l * _InstanceLocker)UnLock(key string){ +func (l *_InstanceLocker) UnLock(key string) { l.locker.Lock() l.instances[key] = false @@ -90,21 +95,29 @@ func (l * _InstanceLocker)UnLock(key string){ //Refresh refresh -func Refresh( instance string) { +func Refresh(instance string) { manager.refresh(instance) } +func GetLastHeartTime(instance string) (time.Time, bool) { + return manager.get(instance) +} + //IsLive 通过ip和端口获取当前节点在线状态 -func IsLive( instance string) bool { +func IsLive(instance string) bool { + + if instanceLocker.IsLock(instance) { + return true + } t, has := manager.get(instance) if !has { return false } - - if time.Now().Sub(t) > EXPIRE { + now := time.Now() + if now.Sub(t) > EXPIRE { return false } return true @@ -113,23 +126,23 @@ func IsLive( instance string) bool { //ResetNodeStatus 重置节点状态 func ResetNodeStatus(nodes ...*entity.Node) { for _, node := range nodes { - - if instanceLocker.IsLock(node.NodeKey) || IsLive(node.NodeKey) { + if instanceLocker.IsLock(node.NodeKey) || IsLive(node.NodeKey) { node.NodeStatus = 1 } else { - node.NodeStatus = 0 + if node.NodeStatus == 1 { + node.NodeStatus = 2 + } else { + node.NodeStatus = 0 + } } } } -func Lock(key string)bool{ +func Lock(key string) bool { return instanceLocker.Lock(key) } -func UnLock(key string) { +func UnLock(key string) { instanceLocker.UnLock(key) Refresh(key) -} -func IsLock(key string)bool{ - return instanceLocker.Lock(key) -} \ No newline at end of file +} diff --git a/console/module/plugin/plugin.go b/console/module/plugin/plugin.go index 9172b1950a2ddc30abe35ccb6288444aa2318efb..ac462c183ce3fa26d44b6749dc51ec07a3ef32b8 100644 --- a/console/module/plugin/plugin.go +++ b/console/module/plugin/plugin.go @@ -1,77 +1,84 @@ package plugin import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +var ( + pluginDao dao.PluginDao +) +func init() { + pdao.Need(&pluginDao) +} //GetPluginInfo 获取插件配置信息 func GetPluginInfo(pluginName string) (bool, *entity.Plugin, error) { - return console_sqlite3.GetPluginInfo(pluginName) + return pluginDao.GetPluginInfo(pluginName) } //GetPluginList 获取插件列表 func GetPluginList(keyword string, condition int) (bool, []*entity.Plugin, error) { - return console_sqlite3.GetPluginList(keyword, condition) + return pluginDao.GetPluginList(keyword, condition) } //AddPlugin 新增插件信息 func AddPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPriority, isStop, pluginType int) (bool, string, error) { - return console_sqlite3.AddPlugin(pluginName, pluginConfig, pluginDesc, version, pluginPriority, isStop, pluginType) + return pluginDao.AddPlugin(pluginName, pluginConfig, pluginDesc, version, pluginPriority, isStop, pluginType) } //EditPlugin 修改插件信息 func EditPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPriority, isStop, pluginType int) (bool, string, error) { - return console_sqlite3.EditPlugin(pluginName, pluginConfig, pluginDesc, version, pluginPriority, isStop, pluginType) + return pluginDao.EditPlugin(pluginName, pluginConfig, pluginDesc, version, pluginPriority, isStop, pluginType) } //DeletePlugin 删除插件信息 func DeletePlugin(pluginName string) (bool, string, error) { - return console_sqlite3.DeletePlugin(pluginName) + return pluginDao.DeletePlugin(pluginName) } //CheckIndexIsExist 判断插件ID是否存在 func CheckIndexIsExist(pluginName string, pluginPriority int) (bool, error) { - return console_sqlite3.CheckIndexIsExist(pluginName, pluginPriority) + return pluginDao.CheckIndexIsExist(pluginName, pluginPriority) } //GetPluginConfig 获取插件配置及插件信息 func GetPluginConfig(pluginName string) (bool, string, error) { - return console_sqlite3.GetPluginConfig(pluginName) + return pluginDao.GetPluginConfig(pluginName) } //CheckNameIsExist 检查插件名称是否存在 func CheckNameIsExist(pluginName string) (bool, error) { - return console_sqlite3.CheckNameIsExist(pluginName) + return pluginDao.CheckNameIsExist(pluginName) } //EditPluginStatus 修改插件开启状态 func EditPluginStatus(pluginName string, pluginStatus int) (bool, error) { - flag, err := console_sqlite3.EditPluginStatus(pluginName, pluginStatus) + flag, err := pluginDao.EditPluginStatus(pluginName, pluginStatus) return flag, err } //GetPluginListByPluginType 获取不同类型的插件列表 func GetPluginListByPluginType(pluginType int) (bool, []map[string]interface{}, error) { - return console_sqlite3.GetPluginListByPluginType(pluginType) + return pluginDao.GetPluginListByPluginType(pluginType) } //BatchStopPlugin 批量关闭插件 func BatchStopPlugin(pluginNameList string) (bool, string, error) { - flag, result, err := console_sqlite3.BatchStopPlugin(pluginNameList) + flag, result, err := pluginDao.BatchStopPlugin(pluginNameList) return flag, result, err } //BatchStartPlugin 批量关闭插件 func BatchStartPlugin(pluginNameList string) (bool, string, error) { - flag, result, err := console_sqlite3.BatchStartPlugin(pluginNameList) + flag, result, err := pluginDao.BatchStartPlugin(pluginNameList) return flag, result, err } //EditPluginCheckStatus 更新插件检测状态 func EditPluginCheckStatus(pluginName string, isCheck int) (bool, string, error) { - return console_sqlite3.EditPluginCheckStatus(pluginName, isCheck) + return pluginDao.EditPluginCheckStatus(pluginName, isCheck) } diff --git a/console/module/project/project.go b/console/module/project/project.go index c7363da9b6090058a9cfe000a777eb746e82e82d..ef655610cb5a41c7a9386aedf388118966381432 100644 --- a/console/module/project/project.go +++ b/console/module/project/project.go @@ -1,49 +1,56 @@ package project import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +var ( + projectDao dao.ProjectDao +) +func init() { + pdao.Need(&projectDao) +} //AddProject 新建项目 func AddProject(projectName string) (bool, interface{}, error) { - return console_sqlite3.AddProject(projectName) + return projectDao.AddProject(projectName) } //EditProject 修改项目信息 func EditProject(projectName string, projectID int) (bool, string, error) { - return console_sqlite3.EditProject(projectName, projectID) + return projectDao.EditProject(projectName, projectID) } //DeleteProject 修改项目信息 func DeleteProject(projectID int) (bool, string, error) { - flag, result, err := console_sqlite3.DeleteProject(projectID) + flag, result, err := projectDao.DeleteProject(projectID) return flag, result, err } //BatchDeleteProject 批量删除项目 func BatchDeleteProject(projectIDList string) (bool, string, error) { - flag, result, err := console_sqlite3.BatchDeleteProject(projectIDList) + flag, result, err := projectDao.BatchDeleteProject(projectIDList) return flag, result, err } //GetProjectInfo 获取项目信息 func GetProjectInfo(projectID int) (bool, entity.Project, error) { - return console_sqlite3.GetProjectInfo(projectID) + return projectDao.GetProjectInfo(projectID) } //GetProjectList 获取项目列表 func GetProjectList(keyword string) (bool, []*entity.Project, error) { - return console_sqlite3.GetProjectList(keyword) + return projectDao.GetProjectList(keyword) } //CheckProjectIsExist 检查项目是否存在 func CheckProjectIsExist(projectID int) (bool, error) { - return console_sqlite3.CheckProjectIsExist(projectID) + return projectDao.CheckProjectIsExist(projectID) } //GetAPIListFromProjectNotInStrategy 获取项目列表中没有被策略组绑定的接口 func GetAPIListFromProjectNotInStrategy() (bool, []map[string]interface{}, error) { - return console_sqlite3.GetAPIListFromProjectNotInStrategy() + return projectDao.GetAPIListFromProjectNotInStrategy() } diff --git a/console/module/service/module.go b/console/module/service/module.go index f2c26458e88636a93f0143815cce9116a9d26288..fb00ad879db0d49a48e0acdea98201c3e1ed5cbb 100644 --- a/console/module/service/module.go +++ b/console/module/service/module.go @@ -2,17 +2,24 @@ package service import ( "fmt" + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" - dao_service2 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-service" driver2 "github.com/eolinker/goku-api-gateway/server/driver" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) const _TableName = "goku_service_config" +var ( + serviceDao dao.ServiceDao +) -//Add 新增服务发现 +func init() { + pdao.Need(&serviceDao) +} +//RegisterDao 新增服务发现 func Add(param *AddParam) error { - err := dao_service2.Add(param.Name, param.Driver, param.Desc, param.Config, param.ClusterConfig, false, param.HealthCheck, param.HealthCheckPath, param.HealthCheckCode, param.HealthCheckPeriod, param.HealthCheckTimeOut) + err := serviceDao.Add(param.Name, param.Driver, param.Desc, param.Config, param.ClusterConfig, false, param.HealthCheck, param.HealthCheckPath, param.HealthCheckCode, param.HealthCheckPeriod, param.HealthCheckTimeOut) return err } @@ -20,7 +27,7 @@ func Add(param *AddParam) error { //Save 保存服务发现 func Save(param *AddParam) error { - v, e := dao_service2.Get(param.Name) + v, e := serviceDao.Get(param.Name) if e != nil { return e } @@ -29,14 +36,14 @@ func Save(param *AddParam) error { return fmt.Errorf("not allowed change dirver from %s to %s for service", v.Driver, param.Driver) } - err := dao_service2.Save(param.Name, param.Desc, param.Config, param.ClusterConfig, param.HealthCheck, param.HealthCheckPath, param.HealthCheckCode, param.HealthCheckPeriod, param.HealthCheckTimeOut) + err := serviceDao.Save(param.Name, param.Desc, param.Config, param.ClusterConfig, param.HealthCheck, param.HealthCheckPath, param.HealthCheckCode, param.HealthCheckPeriod, param.HealthCheckTimeOut) return err } //Get 通过名称获取服务发现信息 func Get(name string) (*Info, error) { - v, err := dao_service2.Get(name) + v, err := serviceDao.Get(name) if err != nil { return nil, err } @@ -61,12 +68,12 @@ func Delete(names []string) error { } } - return dao_service2.Delete(names) + return serviceDao.Delete(names) } //SetDefaut 设置默认服务发现 func SetDefaut(name string) error { - return dao_service2.SetDefault(name) + return serviceDao.SetDefault(name) } func tran(v *entity.Service) *Service { s := &Service{ @@ -94,7 +101,7 @@ func tran(v *entity.Service) *Service { //List 获取服务发现列表 func List(keyword string) ([]*Service, error) { - vs, e := dao_service2.List(keyword) + vs, e := serviceDao.List(keyword) if e != nil { return nil, e } @@ -110,7 +117,7 @@ func List(keyword string) ([]*Service, error) { //SimpleList 获取简易服务发现列表 func SimpleList() ([]*Simple, string, error) { - vs, e := dao_service2.List("") + vs, e := serviceDao.List("") if e != nil { return nil, "", e } diff --git a/console/module/service/service.go b/console/module/service/service.go index 7579c515d7aa0d136dc25e4fbfbdbc93c1184308..9cb8b1a1da241476dcc03b0fe9a65d67b9a6df1b 100644 --- a/console/module/service/service.go +++ b/console/module/service/service.go @@ -33,7 +33,7 @@ type Info struct { HealthCheckTimeOut int `json:"healthCheckTimeOut"` } -//Decode 解码 +//Read 解码 func (i *Info) Decode() { json.Unmarshal([]byte(i.ClusterConfig), &i.ClusterConfigObj) } diff --git a/console/module/strategy/dao.go b/console/module/strategy/dao.go new file mode 100644 index 0000000000000000000000000000000000000000..ea0b86109a7c79c4d1a9e70d1b717481859c95ad --- /dev/null +++ b/console/module/strategy/dao.go @@ -0,0 +1,17 @@ +package strategy + +import ( + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" +) + +var( + strategyDao dao.StrategyDao + strategyGroupDao dao.StrategyGroupDao + strategyPluginDao dao.StrategyPluginDao + +) + +func init() { + pdao.Need(&strategyDao,&strategyGroupDao,&strategyPluginDao) +} \ No newline at end of file diff --git a/console/module/strategy/strategy.go b/console/module/strategy/strategy.go index 4c8b99f01449f58da6f03f5ce71bc24717408945..2169c338cf0a34eecbd972e653af7b7d7c60c5b6 100644 --- a/console/module/strategy/strategy.go +++ b/console/module/strategy/strategy.go @@ -3,95 +3,88 @@ package strategy import ( "errors" - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" - entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) //AddStrategy 新增策略组 -func AddStrategy(strategyName string, groupID int) (bool, string, error) { - flag := console_sqlite3.CheckIsOpenGroup(groupID) +func AddStrategy(strategyName string, groupID, userID int) (bool, string, error) { + flag := strategyGroupDao.CheckIsOpenGroup(groupID) if flag { return false, "[ERROR]The group is an open group", errors.New("[ERROR]The group is an open group") } - flag, result, err := console_sqlite3.AddStrategy(strategyName, groupID) + flag, result, err := strategyDao.AddStrategy(strategyName, groupID, userID) return flag, result, err } //EditStrategy 修改策略组信息 -func EditStrategy(strategyID, strategyName string, groupID int) (bool, string, error) { - return console_sqlite3.EditStrategy(strategyID, strategyName, groupID) +func EditStrategy(strategyID, strategyName string, groupID, userID int) (bool, string, error) { + return strategyDao.EditStrategy(strategyID, strategyName, groupID, userID) } // DeleteStrategy 删除策略组 func DeleteStrategy(strategyID string) (bool, string, error) { - flag := console_sqlite3.CheckIsOpenStrategy(strategyID) + flag := strategyDao.CheckIsOpenStrategy(strategyID) if flag { return false, "[ERROR]The strategy is an open strategy", errors.New("[ERROR]The strategy is an open strategy") } - flag, result, err := console_sqlite3.DeleteStrategy(strategyID) + flag, result, err := strategyDao.DeleteStrategy(strategyID) return flag, result, err } // GetOpenStrategy 获取策略组列表 func GetOpenStrategy() (bool, *entity.Strategy, error) { - return console_sqlite3.GetOpenStrategy() + return strategyDao.GetOpenStrategy() } // GetStrategyList 获取策略组列表 -func GetStrategyList(groupID int, keyword string, condition int) (bool, []*entity.Strategy, error) { - return console_sqlite3.GetStrategyList(groupID, keyword, condition) +func GetStrategyList(groupID int, keyword string, condition, page, pageSize int) (bool, []*entity.Strategy, int, error) { + return strategyDao.GetStrategyList(groupID, keyword, condition, page, pageSize) } // GetStrategyInfo 获取策略组信息 func GetStrategyInfo(strategyID string) (bool, *entity.Strategy, error) { - return console_sqlite3.GetStrategyInfo(strategyID) + return strategyDao.GetStrategyInfo(strategyID) } // CheckStrategyIsExist 检查策略组ID是否存在 func CheckStrategyIsExist(strategyID string) (bool, error) { - return console_sqlite3.CheckStrategyIsExist(strategyID) + return strategyDao.CheckStrategyIsExist(strategyID) } // BatchEditStrategyGroup 批量修改策略组分组 func BatchEditStrategyGroup(strategyIDList string, groupID int) (bool, string, error) { - return console_sqlite3.BatchEditStrategyGroup(strategyIDList, groupID) + return strategyDao.BatchEditStrategyGroup(strategyIDList, groupID) } // BatchDeleteStrategy 批量修改策略组分组 func BatchDeleteStrategy(strategyIDList string) (bool, string, error) { - flag, result, err := console_sqlite3.BatchDeleteStrategy(strategyIDList) + flag, result, err := strategyDao.BatchDeleteStrategy(strategyIDList) return flag, result, err } -//CheckIsOpenStrategy 检查是否是开放策略 -func CheckIsOpenStrategy(strategyID string) bool { - return console_sqlite3.CheckIsOpenStrategy(strategyID) -} - //BatchUpdateStrategyEnableStatus 更新策略启用状态 func BatchUpdateStrategyEnableStatus(strategyIDList string, enableStatus int) (bool, string, error) { - flag, result, err := console_sqlite3.BatchUpdateStrategyEnableStatus(strategyIDList, enableStatus) + flag, result, err := strategyDao.BatchUpdateStrategyEnableStatus(strategyIDList, enableStatus) return flag, result, err } // GetBalanceListInStrategy 获取在策略中的负载列表 func GetBalanceListInStrategy(strategyID string, balanceType int) (bool, []string, error) { - return console_sqlite3.GetBalanceListInStrategy(strategyID, balanceType) + return strategyDao.GetBalanceListInStrategy(strategyID, balanceType) } // CopyStrategy 复制策略 func CopyStrategy(strategyID string, newStrategyID string, userID int) (string, error) { - result, err := console_sqlite3.CopyStrategy(strategyID, newStrategyID, userID) + result, err := strategyDao.CopyStrategy(strategyID, newStrategyID, userID) return result, err } //GetStrategyIDList 获取策略ID列表 func GetStrategyIDList(groupID int, keyword string, condition int) (bool, []string, error) { - return console_sqlite3.GetStrategyIDList(groupID, keyword, condition) + return strategyDao.GetStrategyIDList(groupID, keyword, condition) } diff --git a/console/module/strategy/strategyGroup.go b/console/module/strategy/strategyGroup.go index b0be5e3b5a25d8f7097d7211a207e127cb6193c7..d2e04bdcd4b5cc076e3bb76593546d056f454f2f 100644 --- a/console/module/strategy/strategyGroup.go +++ b/console/module/strategy/strategyGroup.go @@ -2,37 +2,35 @@ package strategy import ( "errors" - - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" ) //AddStrategyGroup 新建策略组分组 func AddStrategyGroup(groupName string) (bool, interface{}, error) { - return console_sqlite3.AddStrategyGroup(groupName) + return strategyGroupDao.AddStrategyGroup(groupName) } //EditStrategyGroup 修改策略组分组 func EditStrategyGroup(groupName string, groupID int) (bool, string, error) { - return console_sqlite3.EditStrategyGroup(groupName, groupID) + return strategyGroupDao.EditStrategyGroup(groupName, groupID) } // DeleteStrategyGroup 删除策略组分组 func DeleteStrategyGroup(groupID int) (bool, string, error) { - flag := console_sqlite3.CheckIsOpenGroup(groupID) + flag := strategyGroupDao.CheckIsOpenGroup(groupID) if flag { return false, "[ERROR]The group is an open group", errors.New("[ERROR]The group is an open group") } - flag, result, err := console_sqlite3.DeleteStrategyGroup(groupID) + flag, result, err := strategyGroupDao.DeleteStrategyGroup(groupID) return flag, result, err } //GetStrategyGroupList 获取策略组分组列表 func GetStrategyGroupList() (bool, []map[string]interface{}, error) { - return console_sqlite3.GetStrategyGroupList() + return strategyGroupDao.GetStrategyGroupList() } //CheckIsOpenGroup 判断是否是开放分组 func CheckIsOpenGroup(groupID int) bool { - return console_sqlite3.CheckIsOpenGroup(groupID) + return strategyGroupDao.CheckIsOpenGroup(groupID) } diff --git a/console/module/strategy/strategyPlugin.go b/console/module/strategy/strategyPlugin.go index 3410ece08148e7ede9cf6aa86bd6e1a399e9bb45..8411804689d5b9cfd321bbb8a7efca85e5714ce1 100644 --- a/console/module/strategy/strategyPlugin.go +++ b/console/module/strategy/strategyPlugin.go @@ -1,19 +1,15 @@ package strategy -import ( - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" -) - //AddPluginToStrategy 新增策略组插件 func AddPluginToStrategy(pluginName, config, strategyID string) (bool, interface{}, error) { - flag, result, err := console_sqlite3.AddPluginToStrategy(pluginName, config, strategyID) + flag, result, err := strategyPluginDao.AddPluginToStrategy(pluginName, config, strategyID) return flag, result, err } //EditStrategyPluginConfig 新增策略组插件配置 func EditStrategyPluginConfig(pluginName, config, strategyID string) (bool, string, error) { - flag, result, err := console_sqlite3.EditStrategyPluginConfig(pluginName, config, strategyID) + flag, result, err := strategyPluginDao.EditStrategyPluginConfig(pluginName, config, strategyID) return flag, result, err } @@ -21,39 +17,39 @@ func EditStrategyPluginConfig(pluginName, config, strategyID string) (bool, stri //BatchEditStrategyPluginStatus 批量修改策略组插件状态 func BatchEditStrategyPluginStatus(connIDList, strategyID string, pluginStatus int) (bool, string, error) { - flag, result, err := console_sqlite3.BatchEditStrategyPluginStatus(connIDList, strategyID, pluginStatus) + flag, result, err := strategyPluginDao.BatchEditStrategyPluginStatus(connIDList, strategyID, pluginStatus) return flag, result, err } //BatchDeleteStrategyPlugin 批量删除策略组插件 func BatchDeleteStrategyPlugin(connIDList, strategyID string) (bool, string, error) { - flag, result, err := console_sqlite3.BatchDeleteStrategyPlugin(connIDList, strategyID) + flag, result, err := strategyPluginDao.BatchDeleteStrategyPlugin(connIDList, strategyID) return flag, result, err } // GetStrategyPluginList 获取策略插件列表 func GetStrategyPluginList(strategyID, keyword string, condition int) (bool, []map[string]interface{}, error) { - return console_sqlite3.GetStrategyPluginList(strategyID, keyword, condition) + return strategyPluginDao.GetStrategyPluginList(strategyID, keyword, condition) } //GetStrategyPluginConfig 通过策略组ID获取配置信息 func GetStrategyPluginConfig(strategyID, pluginName string) (bool, string, error) { - return console_sqlite3.GetStrategyPluginConfig(strategyID, pluginName) + return strategyPluginDao.GetStrategyPluginConfig(strategyID, pluginName) } //CheckPluginIsExistInStrategy 检查策略组是否绑定插件 func CheckPluginIsExistInStrategy(strategyID, pluginName string) (bool, error) { - return console_sqlite3.CheckPluginIsExistInStrategy(strategyID, pluginName) + return strategyPluginDao.CheckPluginIsExistInStrategy(strategyID, pluginName) } //GetStrategyPluginStatus 检查策略组插件是否开启 func GetStrategyPluginStatus(strategyID, pluginName string) (bool, error) { - return console_sqlite3.GetStrategyPluginStatus(strategyID, pluginName) + return strategyPluginDao.GetStrategyPluginStatus(strategyID, pluginName) } //GetConnIDFromStrategyPlugin 获取Connid func GetConnIDFromStrategyPlugin(pluginName, strategyID string) (bool, int, error) { - return console_sqlite3.GetConnIDFromStrategyPlugin(pluginName, strategyID) + return strategyPluginDao.GetConnIDFromStrategyPlugin(pluginName, strategyID) } diff --git a/console/module/updater/check.go b/console/module/updater/check.go index 670c0443b85bca7db1e4da39f8c83df3373451e2..dd78702492398bc35817f6cb1b8e9158e3bf80db 100644 --- a/console/module/updater/check.go +++ b/console/module/updater/check.go @@ -1,15 +1,22 @@ package updater import ( - "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/updater" + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" +) +var ( + updaterDao dao.UpdaterDao ) +func init() { + pdao.Need(&updaterDao) +} //IsTableExist 检查table是否存在 func IsTableExist(name string) bool { - return updater.IsTableExist(name) + return updaterDao.IsTableExist(name) } //IsColumnExist 检查列是否存在 func IsColumnExist(name string, column string) bool { - return updater.IsColumnExist(name, column) + return updaterDao.IsColumnExist(name, column) } diff --git a/console/module/versionConfig/load.go b/console/module/versionConfig/load.go index 914904164af21bb9aa84325dfb1b1e16420c74f5..64d18062caa3432c808c1c99833f5eb7801c1181 100644 --- a/console/module/versionConfig/load.go +++ b/console/module/versionConfig/load.go @@ -1,67 +1,88 @@ package versionConfig import ( - "context" "sync" "time" log "github.com/eolinker/goku-api-gateway/goku-log" - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" - - "github.com/eolinker/goku-api-gateway/common/telegraph" - entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" "github.com/eolinker/goku-api-gateway/config" ) -type versionConfig struct { - config map[string]*telegraph.Telegraph - lock sync.RWMutex -} +type ConfigChangeEventFunc func(conf map[string]*config.GokuConfig) var ( - vc *versionConfig + eventCallback []ConfigChangeEventFunc + lock sync.RWMutex + + lastConf = make(map[string]*config.GokuConfig) ) -func init() { - vc = &versionConfig{ - config: make(map[string]*telegraph.Telegraph), - lock: sync.RWMutex{}, +func AddCallback(f ConfigChangeEventFunc) { + lock.Lock() + eventCallback = append(eventCallback, f) + lock.Unlock() +} +func call() { + lock.RLock() + es := eventCallback + conf := lastConf + lock.RUnlock() + + for _, f := range es { + f(conf) } } -//InitVersionConfig 初始化版本配置 +//type versionConfig struct { +// config map[string]*telegraph.Telegraph +// lock sync.RWMutex +//} +// +//var ( +// vc *versionConfig +//) + +//func init() { +// vc = &versionConfig{ +// config: make(map[string]*telegraph.Telegraph), +// lock: sync.RWMutex{}, +// } +//} + +////InitVersionConfig 初始化版本配置 func InitVersionConfig() { load() } -func (c *versionConfig) GetV(cluster string) *telegraph.Telegraph { - c.lock.RLock() - v, ok := c.config[cluster] - c.lock.RUnlock() - if !ok { - c.lock.Lock() - v, ok = c.config[cluster] - if !ok { - v = telegraph.NewTelegraph("", nil) - c.config[cluster] = v - } - c.lock.Unlock() - } - return v -} -func (c *versionConfig) getConfig(ctx context.Context, cluster string, version string) (*config.GokuConfig, error) { - - v := c.GetV(cluster) - r, err := v.GetWidthContext(ctx, version) - if err != nil { - return nil, err - } - return r.(*config.GokuConfig), err - -} +//func (c *versionConfig) GetV(cluster string) *telegraph.Telegraph { +// c.lock.RLock() +// v, ok := c.config[cluster] +// c.lock.RUnlock() +// if !ok { +// c.lock.Lock() +// v, ok = c.config[cluster] +// if !ok { +// v = telegraph.NewTelegraph("", nil) +// c.config[cluster] = v +// } +// c.lock.Unlock() +// } +// return v +//} +//func (c *versionConfig) getConfig(ctx context.Context, cluster string, version string) (*config.GokuConfig, error) { +// +// v := c.GetV(cluster) +// +// r, err := v.GetWidthContext(ctx, version) +// if err != nil { +// return nil, err +// } +// return r.(*config.GokuConfig), err +// +//} //func (c *versionConfig) getVersion() string { // c.lock.RLock() @@ -69,12 +90,25 @@ func (c *versionConfig) getConfig(ctx context.Context, cluster string, version s // return c.version //} -//GetVersionConfig 获取版本配置 -func GetVersionConfig(ctx context.Context, cluster, version string) (*config.GokuConfig, error) { - return vc.getConfig(ctx, cluster, version) +////GetVersionConfig 获取版本配置 +//func GetVersionConfig(ctx context.Context, cluster, version string) (*config.GokuConfig, error) { +// return vc.getConfig(ctx, cluster, version) +//} + +func GetConfig(cluster string) (*config.GokuConfig, error) { + + lock.RLock() + c, has := lastConf[cluster] + lock.RUnlock() + if !has { + return &config.GokuConfig{}, nil + //return nil, errors.New("no pub config") + } + return c, nil + } -func (c *versionConfig) reset(clusters []*entity.Cluster, gokuConfig *config.GokuConfig, balanceConfig map[string]map[string]*config.BalanceConfig, discoverConfig map[string]map[string]*config.DiscoverConfig) { +func reset(clusters []*entity.Cluster, gokuConfig *config.GokuConfig, balanceConfig map[string]map[string]*config.BalanceConfig, discoverConfig map[string]map[string]*config.DiscoverConfig) { newConfig := make(map[string]*config.GokuConfig) now := time.Now().Format("20060102150405") for _, cl := range clusters { @@ -86,6 +120,12 @@ func (c *versionConfig) reset(clusters []*entity.Cluster, gokuConfig *config.Gok if v, ok := discoverConfig[cl.Name]; ok { df = v } + var redisConfig interface{} = nil + if config, ok := gokuConfig.RedisConfig[cl.Name]; ok { + redisConfig = config + } else { + redisConfig = cl.Redis + } configByte := &config.GokuConfig{ Version: now, Cluster: cl.Name, @@ -99,38 +139,31 @@ func (c *versionConfig) reset(clusters []*entity.Cluster, gokuConfig *config.Gok Log: gokuConfig.Log, AccessLog: gokuConfig.AccessLog, MonitorModules: gokuConfig.MonitorModules, + Routers: gokuConfig.Routers, + GatewayBasicInfo: gokuConfig.GatewayBasicInfo, + ExtendsConfig: map[string]interface{}{ + "redis": redisConfig, + }, } newConfig[cl.Name] = configByte } - c.lock.Lock() + lock.Lock() + + lastConf = newConfig + lock.Unlock() + call() - for name, cf := range vc.config { - if _, has := newConfig[name]; !has { - cf.Close() - delete(vc.config, name) - } - } - for name, cs := range newConfig { - cf, has := vc.config[name] - if !has { - cf = telegraph.NewTelegraph(now, cs) - vc.config[name] = cf - } else { - cf.Set(now, cs) - } - } - c.lock.Unlock() } func load() { - clusters, err := console_sqlite3.GetClusters() + clusters, err := clusterDao.GetClusters() if err != nil { return } - cf, bf, df, err := console_sqlite3.GetVersionConfig() + cf, bf, df, err := versionDao.GetVersionConfig() if err != nil { log.Warn("load config error:", err) return } - vc.reset(clusters, cf, bf, df) + reset(clusters, cf, bf, df) } diff --git a/console/module/versionConfig/version.go b/console/module/versionConfig/version.go index 642dc865669cdf90ed0423280f1b948eca5d447d..671fc6fc2354b60f9e7586127650f713d4c3c360 100644 --- a/console/module/versionConfig/version.go +++ b/console/module/versionConfig/version.go @@ -3,41 +3,54 @@ package versionConfig import ( "encoding/json" - "github.com/eolinker/goku-api-gateway/ksitigarbha" + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" + entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" - console_sqlite3 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3" - dao_version_config2 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-version-config" + "github.com/eolinker/goku-api-gateway/ksitigarbha" "github.com/eolinker/goku-api-gateway/config" ) -var authNames = map[string]string{ - "Oauth2": "goku-oauth2_auth", - "Apikey": "goku-apikey_auth", - "Basic": "goku-basic_auth", - "Jwt": "goku-jwt_auth", +var ( + versionDao dao.VersionDao + versionConfigDao dao.VersionConfigDao + clusterDao dao.ClusterDao + authNames = map[string]string{ + "Oauth2": "goku-oauth2_auth", + "Apikey": "goku-apikey_auth", + "Basic": "goku-basic_auth", + "Jwt": "goku-jwt_auth", + } +) + +func init() { + pdao.Need(&versionConfigDao, &versionDao, &clusterDao) } //GetVersionList 获取版本列表 func GetVersionList(keyword string) ([]config.VersionConfig, error) { - return console_sqlite3.GetVersionList(keyword) + return versionDao.GetVersionList(keyword) } //AddVersionConfig 新增版本配置 -func AddVersionConfig(name, version, remark, now string) (int, error) { +func AddVersionConfig(name, version, remark, now string, userID int) (int, error) { config, balanceConfig, discoverConfig := buildVersionConfig(version) - return console_sqlite3.AddVersionConfig(name, version, remark, config, balanceConfig, discoverConfig, now) + return versionDao.AddVersionConfig(name, version, remark, config, balanceConfig, discoverConfig, now, userID) +} +func EditVersionBasicConfig(name, version, remark string, userID, versionID int) error { + return versionDao.EditVersionBasicConfig(name, version, remark, userID, versionID) } //BatchDeleteVersionConfig 批量删除版本配置 func BatchDeleteVersionConfig(ids []int) error { - publishID := console_sqlite3.GetPublishVersionID() - return console_sqlite3.BatchDeleteVersionConfig(ids, publishID) + publishID := versionDao.GetPublishVersionID() + return versionDao.BatchDeleteVersionConfig(ids, publishID) } //PublishVersion 发布版本 -func PublishVersion(id int, now string) error { - err := console_sqlite3.PublishVersion(id, now) +func PublishVersion(id, userID int, now string) error { + err := versionDao.PublishVersion(id, userID, now) if err == nil { load() } @@ -46,44 +59,55 @@ func PublishVersion(id int, now string) error { //GetVersionConfigCount 获取版本配置数量 func GetVersionConfigCount() int { - return console_sqlite3.GetVersionConfigCount() + return versionDao.GetVersionConfigCount() +} + +func getRedisConfig(clusters []*entity.Cluster) map[string]interface{} { + redisConfig := map[string]interface{}{} + for _, c := range clusters { + redisConfig[c.Name] = c.Redis + } + return redisConfig } func buildVersionConfig(v string) (string, string, string) { - clusters, err := console_sqlite3.GetClusters() + clusters, err := clusterDao.GetClusters() if err != nil { return "", "", "" } - discoverMap, err := dao_version_config2.GetDiscoverConfig(clusters) + discoverMap, err := versionConfigDao.GetDiscoverConfig(clusters) if err != nil { return "", "", "" } - balanceMap, err := dao_version_config2.GetBalances(clusters) + balanceMap, err := versionConfigDao.GetBalances(clusters) if err != nil { return "", "", "" } - openStrategy, strategyConfigs, err := dao_version_config2.GetStrategyConfig() + openStrategy, strategyConfigs, err := versionConfigDao.GetStrategyConfig() if err != nil { return "", "", "" } - apiContents, err := dao_version_config2.GetAPIContent() + apiContents, err := versionConfigDao.GetAPIContent() if err != nil { return "", "", "" } - plugins, err := dao_version_config2.GetGlobalPlugin() + plugins, err := versionConfigDao.GetGlobalPlugin() if err != nil { return "", "", "" } - logCf, accessCf, err := dao_version_config2.GetLogInfo() + logCf, accessCf, err := versionConfigDao.GetLogInfo() if err != nil { return "", "", "" } + + g, _ := versionConfigDao.GetGatewayBasicConfig() + routers, _ := versionConfigDao.GetRouterRules(1) ms := make(map[string]string) - modules, _ := dao_version_config2.GetMonitorModules(1, false) + modules, _ := versionConfigDao.GetMonitorModules(1, false) if modules != nil { for key, config := range modules { - module ,has:= ksitigarbha.GetMonitorModuleModel(key) - if has{ + module, has := ksitigarbha.GetMonitorModuleModel(key) + if has { ms[module.GetName()] = config } } @@ -91,7 +115,7 @@ func buildVersionConfig(v string) (string, string, string) { c := config.GokuConfig{ Version: v, - Plugins: plugins, + Plugins: *plugins, APIS: apiContents, Strategy: strategyConfigs, AnonymousStrategyID: openStrategy, @@ -99,6 +123,9 @@ func buildVersionConfig(v string) (string, string, string) { Log: logCf, AccessLog: accessCf, MonitorModules: ms, + Routers: routers, + GatewayBasicInfo: g, + RedisConfig: getRedisConfig(clusters), } cByte, err := json.Marshal(c) diff --git a/diting/diting.go b/diting/diting.go index e94039c7a47b4abbdc2aeeff84239a453474573d..dcef19d0b22c70d5bf9120801f0917d25806740f 100644 --- a/diting/diting.go +++ b/diting/diting.go @@ -6,25 +6,21 @@ type ConfigHandleFunc func() interface{} //Constructor constructor type Constructor interface { Namespace() string - Create(conf string) (Factory,error) + Create(conf string) (Factory, error) Close() - } //Factory factory type Factory interface { - - NewCounter(opt *CounterOpts) (Counter,error) + NewCounter(opt *CounterOpts) (Counter, error) //NewSummary(opt *SummaryOpts) (Summary,error) - NewHistogram(opt *HistogramOpts) (Histogram,error) - NewGauge(opt *GaugeOpts) (Gauge,error) - + NewHistogram(opt *HistogramOpts) (Histogram, error) + NewGauge(opt *GaugeOpts) (Gauge, error) } //Factories factories type Factories []Factory - //NewCounter new counter func (fs Factories) NewCounter(opt *CounterOpts) (Counters, error) { cs := make(Counters, 0, len(fs)) diff --git a/diting/internal/id.go b/diting/internal/id.go index 37cc512a72d5944688f24fcb56b9cf5a2ddd8113..d2c5cb259bb8c54832653ae9f1acd11db8c43c5d 100644 --- a/diting/internal/id.go +++ b/diting/internal/id.go @@ -18,7 +18,7 @@ func NewIDCreate() *IDCreate { //Next next func (c *IDCreate) Next() uint64 { - var id uint64 = 0 + var id uint64 c.locker.Lock() id = uint64(time.Now().UnixNano()) diff --git a/diting/manager.go b/diting/manager.go index a407924aa484568b45ae21d1b436380b7ceb1b4d..122b68dc0dff935115662935d85974c04816c721 100644 --- a/diting/manager.go +++ b/diting/manager.go @@ -30,11 +30,13 @@ func get(namespace string) (Constructor, bool) { func construct(confs map[string]string) Factories { + lives:= make(map[string]int) factories := make(Factories,0,len(confs)) defer func() { // close 关闭不用的模块 - lives := confs + for name,constructor:= range constructorMap{ + if _,has:=lives[name];!has{ constructor.Close() } @@ -44,9 +46,9 @@ func construct(confs map[string]string) Factories { return factories } - for name, conf := range confs { - namespace:=ksitigarbha.GetNameSpaceByName(name) + namespace,_:=ksitigarbha.GetNameSpaceByName(name) + lives[namespace] = 1 constructor, has := get(namespace) if !has { continue diff --git a/diting/opt.go b/diting/opt.go index 6e59e7989d0f5defb713108d0d1c25a4da2c470f..4b582c65861255a09667abd02b905265558dd57e 100644 --- a/diting/opt.go +++ b/diting/opt.go @@ -54,15 +54,15 @@ type HistogramOpts struct { LabelNames []string // Namespace, Subsystem, and Name are components of the fully-qualified - // name of the Histogram (created by joining these components with + // name of the HistogramObserve (created by joining these components with // "_"). Only Name is mandatory, the others merely help structuring the - // name. Note that the fully-qualified name of the Histogram must be a + // name. Note that the fully-qualified name of the HistogramObserve must be a // valid Prometheus metric name. Namespace string Subsystem string Name string - // Help provides information about this Histogram. + // Help provides information about this HistogramObserve. // // Metrics with the same fully-qualified name must have the same Help // string. diff --git a/diting/proxy-summary.go b/diting/proxy-summary.go index 70543161456d564a5edba71faffbe0966063db16..e0a00e2520beb39cf1f1ca03382a004467da11db 100644 --- a/diting/proxy-summary.go +++ b/diting/proxy-summary.go @@ -1,6 +1,5 @@ package diting - // //type SummariesProxy struct { // ConstLabelsProxy @@ -33,4 +32,4 @@ package diting // s.locker.RUnlock() // summaries.Observe(value,labels) //} -// \ No newline at end of file +// diff --git a/diting/utils.go b/diting/utils.go index 9fa8b0f6d85df92cc717c898203d7e3ca1651386..f449bbee144ab46a4853d31377e91d25fc7d2ed2 100644 --- a/diting/utils.go +++ b/diting/utils.go @@ -14,7 +14,7 @@ func NewGauge(opt *GaugeOpts) Gauge { return g } -//NewHistogram new Histogram +//NewHistogram new HistogramObserve func NewHistogram(opt *HistogramOpts) Histogram { h := newHistogramProxy(opt) refresher.Add(h) @@ -23,6 +23,6 @@ func NewHistogram(opt *HistogramOpts) Histogram { //func NewSummary(opt *SummaryOpts) Summary { // s:= newSummariesProxy(opt) -// refresher.Add(s) +// refresher.RegisterDao(s) // return s //} diff --git a/go.mod b/go.mod index 4b677cdb6a880d1275edb0799d40428cfa92522f..2e4419413f0a4f8abeb61be170a908e9ae4f92b0 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,6 @@ require ( github.com/go-sql-driver/mysql v1.4.1 github.com/hashicorp/consul/api v1.1.0 github.com/json-iterator/go v1.1.7 - github.com/julienschmidt/httprouter v1.2.0 github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/marpaia/graphite-golang v0.0.0-20190519024811-caf161d2c2b1 github.com/mattn/go-colorable v0.1.4 // indirect @@ -24,7 +23,9 @@ require ( github.com/onsi/gomega v1.7.0 // indirect github.com/peterh/liner v1.1.0 // indirect github.com/pkg/errors v0.8.1 + github.com/pkg/sftp v1.10.1 github.com/prometheus/client_golang v1.2.1 + github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff github.com/sirupsen/logrus v1.4.2 github.com/spf13/cobra v0.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect @@ -34,7 +35,10 @@ require ( golang.org/x/net v0.0.0-20190923162816-aa69164e4478 // indirect golang.org/x/sys v0.0.0-20191024073052-e66fe6eb8e0c // indirect google.golang.org/appengine v1.6.3 // indirect + gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect + gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df + gopkg.in/sourcemap.v1 v1.0.5 // indirect gopkg.in/yaml.v2 v2.2.4 ) diff --git a/go.sum b/go.sum index 46e210e61f8cd737343da2fd64597a54f2dabb1c..a538225573c8982346d5a0080272c41e6df4b1c4 100644 --- a/go.sum +++ b/go.sum @@ -91,6 +91,8 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGi github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -141,6 +143,8 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v0.0.0-20170413231811-06b906832ed0/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/sftp v1.10.1 h1:VasscCm72135zRysgrJDKsntdmPN+OuU3+nnHYA9wyc= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -158,6 +162,8 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8= github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff h1:+6NUiITWwE5q1KO6SAfUX918c+Tab0+tGAM/mtdlUyA= +github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY= github.com/russross/blackfriday v0.0.0-20180428102519-11635eb403ff/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= @@ -194,6 +200,7 @@ golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392 h1:ACG4HJsFiNMf47Y4PeRoebLNy/2lXT9EtprMuTFWt1M= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -238,6 +245,8 @@ google.golang.org/appengine v1.6.3 h1:hvZejVcIxAKHR8Pq2gXaDggf6CWT1QEqO+JEBeOKCG google.golang.org/appengine v1.6.3/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= +gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -245,6 +254,10 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= +gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE= +gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw= +gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI= +gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= diff --git a/goku-handler/account.go b/goku-handler/account.go new file mode 100644 index 0000000000000000000000000000000000000000..bd9af2a9908de58d6a1ae59bc7d4d9b7ae69e371 --- /dev/null +++ b/goku-handler/account.go @@ -0,0 +1,63 @@ +package goku_handler + +import ( + "net/http" +) + +//Account 账号处理器 +type Account interface { + CheckLogin(r *http.Request) (int, error) + CheckPermission(pre string, isEdit bool, userID int) (bool, error) +} + +//AccountHandler 账号处理器 +type AccountHandler struct { + account Account + handler http.Handler + permission string + isEdit bool +} + +func (h *AccountHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + + // 检查登录操作 + userID, err := h.account.CheckLogin(r) + if err != nil { + WriteError(w, "100001", "user", err.Error(), err) + return + } + + // 检查权限操作 + if _, err := h.account.CheckPermission(h.permission, h.isEdit, userID); err != nil { + WriteError(w, "100002", "user", err.Error(), err) + return + } + + r = SetUserIDToRequest(r, userID) + h.handler.ServeHTTP(w, r) +} + +//AccountHandlerFactory 账号处理工厂 +type AccountHandlerFactory struct { + account Account +} + +//NewAccountHandlerFactory new AccountHandlerFactory +func NewAccountHandlerFactory(account Account) *AccountHandlerFactory { + return &AccountHandlerFactory{account: account} +} + +//NewAccountHandler new accountHandler +func (f *AccountHandlerFactory) NewAccountHandler(permission string, isEdit bool, handler http.Handler) http.Handler { + return &AccountHandler{ + account: f.account, + handler: handler, + permission: permission, + isEdit: isEdit, + } +} + +//NewAccountHandleFunction new accountHandleFunction +func (f *AccountHandlerFactory) NewAccountHandleFunction(permission string, isEdit bool, handleFunc func(w http.ResponseWriter, r *http.Request)) http.Handler { + return f.NewAccountHandler(permission, isEdit, http.HandlerFunc(handleFunc)) +} diff --git a/goku-handler/handler.go b/goku-handler/handler.go new file mode 100644 index 0000000000000000000000000000000000000000..8e5aa68337e214836ffc3dae8ad052ba0737e6b0 --- /dev/null +++ b/goku-handler/handler.go @@ -0,0 +1,47 @@ +package goku_handler + +import ( + "fmt" + "net/http" + "strings" +) + +//GokuHandler gokuHandler +type GokuHandler interface { + Handlers(factory *AccountHandlerFactory) map[string]http.Handler +} + +//GokuServer gokuServer +type GokuServer struct { + factory *AccountHandlerFactory + mux *http.ServeMux +} + +func (s *GokuServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { + s.mux.ServeHTTP(w, r) +} + +//NewGokuServer new gokuServer +func NewGokuServer(factory *AccountHandlerFactory) *GokuServer { + return &GokuServer{ + factory: factory, + mux: http.NewServeMux(), + } +} + +//Add add +func (s *GokuServer) Add(pre string, handler GokuHandler) { + handlers := handler.Handlers(s.factory) + + for sub, h := range handlers { + + path := join(pre, sub) + s.mux.Handle(path, h) + } +} + +func join(pre, sub string) string { + + return fmt.Sprint(strings.TrimSuffix(pre, "/"), "/", strings.TrimPrefix(sub, "/")) + +} diff --git a/goku-handler/user.go b/goku-handler/user.go new file mode 100644 index 0000000000000000000000000000000000000000..294e4140a343b148b75007c8a68326414372f578 --- /dev/null +++ b/goku-handler/user.go @@ -0,0 +1,31 @@ +package goku_handler + +import ( + "context" + "fmt" + "net/http" +) + +//ContextKey contextKey +type userIDKey struct { +} + +var _userIDKey = userIDKey{} + +//UserIDFromRequest 从request中读取用户ID +func UserIDFromRequest(req *http.Request) int { + ctx := req.Context() + p, ok := ctx.Value(_userIDKey).(int) + if !ok { + fmt.Println("error") + } + return p +} + +//SetUserIDToRequest 设置userID到request +func SetUserIDToRequest(req *http.Request, userID int) *http.Request { + rctx := req.Context() + rctx = context.WithValue(rctx, _userIDKey, userID) + req = req.WithContext(rctx) + return req +} diff --git a/goku-handler/utils.go b/goku-handler/utils.go new file mode 100644 index 0000000000000000000000000000000000000000..7f0f10ff87ecc72c786c7e4be722235037bb2504 --- /dev/null +++ b/goku-handler/utils.go @@ -0,0 +1,34 @@ +package goku_handler + +import ( + "encoding/json" + log "github.com/eolinker/goku-api-gateway/goku-log" + "net/http" +) + + + +//WriteError 返回错误 +func WriteError(w http.ResponseWriter, statusCode, resultType, resultDesc string, resuleErr error) { + + ret := map[string]interface{}{ + "type": resultType, + "statusCode": statusCode, + "resultDesc": resultDesc, + } + + if resuleErr != nil { + log.Info(resuleErr) + } + + data, err := json.Marshal(ret) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + log.WithFields(ret).Debug("write error:", err) + } + + w.Write(data) + log.WithFields(ret).Debug("write error:", err) + +} + diff --git a/goku-labels/labels.go b/goku-labels/labels.go index 82c3c11fb7896fc644ebe350c318d819ba21e5d1..3c36c595cc845426b62d37b8462ba8a0c74980c1 100644 --- a/goku-labels/labels.go +++ b/goku-labels/labels.go @@ -1,23 +1,51 @@ -package goku_labels - -// constlabel +package goku_labels // constlabel +// api labels +// proxy const ( - Cluster = "cluster" + Cluster = "cluster" Instance = "instance" -) + //Namespace 命名空间 + Namespace = "goku" + //Subsystem subSystem + Subsystem = "" + //APIName apiName + APIName = "api" + //ProxyName proxyName + ProxyName = "proxy" -// api labels -const ( - API = "api" + API = "api" Strategy = "strategy" - Status ="status" - + Status = "status" + Proto = "proto" + Method = "method" + Host = "host" + Path = "path" ) -// proxy -const ( - Proto = "proto" - Method = "method" - Host ="host" - Path = "path" -) \ No newline at end of file +var ( + //APIBuckets apiBuckets + APIBuckets = []float64{5, 25, 50, 100, 200, 400, 600, 800, 1000, 2500, 5000} + //ProxyBuckets proxyBuckets + ProxyBuckets = []float64{5, 25, 50, 100, 200, 400, 600, 800, 1000, 2500, 5000} + + //APIDelayLabelNames apiDelayLabelNames + APIDelayLabelNames = []string{ + Cluster, + Instance, + API, + Strategy, + Status, + } + //ProxyDelayLabelNames proxyDelayLabelNames + ProxyDelayLabelNames = []string{ + Cluster, + Instance, + API, + Strategy, + Proto, + Host, + Path, + Method, + Status, + } +) diff --git a/goku-node/common/body-request.go b/goku-node/common/body-request.go index 2153fb69b0b4291d704f54f3656e869c52793e5c..5f644c2b6c42692e8d2a8e431ef4eee6321c705d 100644 --- a/goku-node/common/body-request.go +++ b/goku-node/common/body-request.go @@ -51,13 +51,11 @@ func (b *BodyRequestHandler) Files() (map[string]*goku_plugin.FileHeader, error) //Parse 解析 func (b *BodyRequestHandler) Parse() error { - if b.isInit { return nil } contentType, _, _ := mime.ParseMediaType(b.contentType) - switch contentType { case goku_plugin.JSON: { @@ -123,8 +121,7 @@ func (b *BodyRequestHandler) Parse() error { return err } if b.form == nil { - - b.object = form + b.form = form } else { for k, v := range form { b.form[k] = append(b.form[k], v...) diff --git a/goku-node/common/request-reader.go b/goku-node/common/request-reader.go index 7b1d77c50745be9effc48c40d69df69d6840d1e8..8db15538ce018561155f82428b1d9992761998e1 100644 --- a/goku-node/common/request-reader.go +++ b/goku-node/common/request-reader.go @@ -30,9 +30,9 @@ func NewRequestReader(req *http.Request) *RequestReader { func (r *RequestReader) ParseRequest() { r.Header = NewHeader(r.req.Header) - body ,err:= ioutil.ReadAll(r.req.Body) + body, err := ioutil.ReadAll(r.req.Body) _ = r.req.Body.Close() - if err != nil { + if err != nil { r.BodyRequestHandler = NewBodyRequestHandler(r.req.Header.Get("Content-Type"), nil) } else { r.BodyRequestHandler = NewBodyRequestHandler(r.req.Header.Get("Content-Type"), body) diff --git a/goku-node/redis-plugin-proxy/redis.go b/goku-node/redis-plugin-proxy/redis.go index 04787964d522e65081c3e1fceb41e16ff7194a13..3217bc006cb81b53eaeb17f09926543319272d40 100644 --- a/goku-node/redis-plugin-proxy/redis.go +++ b/goku-node/redis-plugin-proxy/redis.go @@ -7,7 +7,9 @@ import ( //Create 创建RedisManager func Create() goku_plugin.RedisManager { - + if redis_manager.GetConnection() == nil { + return nil + } return &RedisManager{ def: &RedisProxy{ redisClient: redis_manager.GetConnection(), diff --git a/goku-observe/histogram.go b/goku-observe/histogram.go index d62bbda77997e99c2d295fd17b6138f65d938dec..3c6c6df9b3e24a0b99c3778360b4617c3563c279 100644 --- a/goku-observe/histogram.go +++ b/goku-observe/histogram.go @@ -10,69 +10,78 @@ import ( // values int64 //} -type _Histogram struct { - size int - buckets []float64 - values []int64 - max float64 - min float64 - sum float64 - count int - locker sync.Mutex +//Histogram histogram +type Histogram struct { + size int + Values []uint64 + Max float64 + Min float64 + Sum float64 + Count uint64 } -func (h *_Histogram) Observe(value float64) { +//HistogramObserver histogramObserver +type HistogramObserver struct { + Histogram + locker sync.Mutex +} + +//Collapse Collapse +func (h *HistogramObserver) Collapse() (values []uint64, sum, max, min float64, count uint64) { + return h.Values, h.Sum, h.Max, h.Min, h.Count +} + +//Observe Observe +func (h *HistogramObserver) Observe(buckets []float64, value float64) { + h.locker.Lock() if value < 0 { value = 0 } - h.locker.Lock() - h.count++ - h.sum += value - if value> h.max{ - h.max = value + h.Count++ + h.Sum += value + if value > h.Max { + h.Max = value } - if value < h.min{ - h.min= value + if value < h.Min { + h.Min = value } - l:= h.size -1 - for i:=l;i>=0;i--{ - if value >= h.buckets[i]{ + l := h.size - 1 + for i := l; i >= 0; i-- { + if value >= buckets[i] { break } - h.values[i]++ + h.Values[i]++ } h.locker.Unlock() } -//func (h*_Histogram) Reset() { -// h.locker.Lock() -// h.values = make([]int64,len(h.values),len(h.values)) -// h.sum ,h.max ,h.min,h.count = 0,0,math.MaxFloat64,0 -// h.locker.Unlock() -//} -func (h *_Histogram) Collapse() (values []int64, sum ,max,min float64,count int){ - h.locker.Lock() - values,sum,max,min,count = h.values,h.sum,h.max,h.min,h.count - h.locker.Unlock() - return + +//NewHistogram new Histogram +func NewHistogram(size int) *Histogram { + return &Histogram{ + size: size, + Values: make([]uint64, size, size), + Max: 0, + Min: math.MaxFloat64, + Sum: 0, + Count: 0, + } } -func NewHistogram(buckets []float64) *_Histogram { - max:= len(buckets) +1 - h:=&_Histogram{ - size: max, - buckets: make([]float64, 0, max), - values: make([]int64, max, max), - max: 0, - min: math.MaxFloat64, - sum: 0, - count: 0, - locker: sync.Mutex{}, + +//NewHistogramObserve new HistogramObserve +func NewHistogramObserve(size int) HistogramObserve { + + h := &HistogramObserver{ + Histogram: Histogram{ + size: size, + Values: make([]uint64, size, size), + Max: 0, + Min: math.MaxFloat64, + Sum: 0, + Count: 0, + }, + locker: sync.Mutex{}, } - h.buckets = append(h.buckets,buckets...) - h.buckets = append(h.buckets,math.MaxFloat64) - //sort.Float64s(h.buckets) return h } - - diff --git a/goku-observe/histogram_test.go b/goku-observe/histogram_test.go index 469144a37d852b31b42287cca7ce9915811eea6e..a1b05236030c24902e0ded64ca561f3af0062ab1 100644 --- a/goku-observe/histogram_test.go +++ b/goku-observe/histogram_test.go @@ -58,7 +58,7 @@ func TestHistogram_Observe(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - h := &Histogram{ + h := &HistogramObserve{ Buckets: tt.fields.Buckets, Count: tt.fields.Count, } @@ -82,23 +82,22 @@ func TestNewHistogram(t *testing.T) { tests := []struct { name string args args - want *Histogram + want *HistogramObserve }{ - // TODO: Add test cases. + // TODO: RegisterDao test cases. { name: "", args: args{ buckets: []float64{0.1,0.5,1.0}, }, - want: &Histogram{ - Buckets: []float64{0.1,0.5,1.0,math.MaxFloat64}, - Count: []int64{0,0,0,0}, + want: &HistogramObserver{ + }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := NewHistogram(tt.args.buckets); !reflect.DeepEqual(got, tt.want) { + if got := NewHistogramObserve(len(tt.args.buckets)); !reflect.DeepEqual(got, tt.want) { t.Errorf("NewHistogram() = %v, want %v", got, tt.want) } }) diff --git a/goku-observe/observe.go b/goku-observe/observe.go index 086855be6e0a4f74f2f8efeed48972f2347b259f..d7062a41e0c703c8dba7bcf7b7594a76fccc7de3 100644 --- a/goku-observe/observe.go +++ b/goku-observe/observe.go @@ -1,10 +1,7 @@ package goku_observe -type Observe interface { - Observe(value float64) -} - -type Histogram interface { - Observe - Collapse() (values []int64, sum ,max,min float64,count int) +//HistogramObserve HistogramObserve +type HistogramObserve interface { + Observe(buckets []float64, value float64) + Collapse() (values []uint64, sum, max, min float64, count uint64) } diff --git a/goku-service/application/application.go b/goku-service/application/application.go index 2f0567a68a218b0e5a6b0e471dda19862a6af434..b06d4e8527b7ade85de0691d9ab7486321782578 100644 --- a/goku-service/application/application.go +++ b/goku-service/application/application.go @@ -1,6 +1,7 @@ package application import ( + goku_plugin "github.com/eolinker/goku-plugin" "net/http" "net/url" "time" @@ -8,5 +9,5 @@ import ( //IHttpApplication iHttpApplication type IHttpApplication interface { - Send(Proto string, method string, path string, querys url.Values, header http.Header, body []byte, timeout time.Duration, retry int) (*http.Response, string, []string, error) + Send(ctx goku_plugin.ContextAccess,Proto string, method string, path string, querys url.Values, header http.Header, body []byte, timeout time.Duration, retry int) (*http.Response, string, []string, error) } diff --git a/goku-service/application/org.go b/goku-service/application/org.go index 469eca1318997bd2aaa17d084451167ab98afc2a..a118a02395761c66c39918b507d4a32a2ff67389 100644 --- a/goku-service/application/org.go +++ b/goku-service/application/org.go @@ -2,6 +2,7 @@ package application import ( "fmt" + goku_plugin "github.com/eolinker/goku-plugin" "net/http" "net/url" "time" @@ -15,7 +16,7 @@ type Org struct { } //Send 请求发送,忽略重试 -func (app *Org) Send(proto string, method string, path string, querys url.Values, header http.Header, body []byte, timeout time.Duration, retry int) (*http.Response, string, []string, error) { +func (app *Org) Send(ctx goku_plugin.ContextAccess,proto string, method string, path string, querys url.Values, header http.Header, body []byte, timeout time.Duration, retry int) (*http.Response, string, []string, error) { var response *http.Response var err error @@ -30,7 +31,7 @@ func (app *Org) Send(proto string, method string, path string, querys url.Values u := fmt.Sprintf("%s://%s/%s", proto, app.server, path) FinalTargetServer = app.server RetryTargetServers = append(RetryTargetServers, FinalTargetServer) - response, err = request(method, u, querys, header, body, timeout) + response, err = request(ctx,method, u, querys, header, body, timeout) if err != nil { continue } else { diff --git a/goku-service/application/r.go b/goku-service/application/r.go index 4b47b28f7525a3eafd2b871ebd6e29501232bd84..65f8c8bd6b0643d64477a3061f84ea01832019f9 100644 --- a/goku-service/application/r.go +++ b/goku-service/application/r.go @@ -2,12 +2,13 @@ package application import ( "fmt" + goku_plugin "github.com/eolinker/goku-plugin" "net/http" "net/url" "time" ) -func request(method string, backendDomain string, query url.Values, header http.Header, body []byte, timeout time.Duration) (*http.Response, error) { +func request(ctx goku_plugin.ContextAccess,method string, backendDomain string, query url.Values, header http.Header, body []byte, timeout time.Duration) (*http.Response, error) { if backendDomain == "" { return nil, fmt.Errorf("invaild url") @@ -24,11 +25,11 @@ func request(method string, backendDomain string, query url.Values, header http. return nil, err } - queryDest:= u.Query() - if query!= nil{ - for k,vs:=range query{ - for _,v:=range vs{ - queryDest.Add(k,v) + queryDest := u.Query() + if query != nil { + for k, vs := range query { + for _, v := range vs { + queryDest.Add(k, v) } } } @@ -41,5 +42,5 @@ func request(method string, backendDomain string, query url.Values, header http. if timeout != 0 { req.SetTimeout(timeout) } - return req.Send() + return req.Send(ctx) } diff --git a/goku-service/application/request.go b/goku-service/application/request.go index 63aeb01ca117f593c78277cbebe28ee60120958d..d4373334ebf3b9a2b87364f883070e4dc4918471 100644 --- a/goku-service/application/request.go +++ b/goku-service/application/request.go @@ -2,10 +2,15 @@ package application import ( "bytes" + "crypto/tls" "errors" "io" + "net" "net/http" "net/url" + "strconv" + + goku_plugin "github.com/eolinker/goku-plugin" "github.com/eolinker/goku-api-gateway/diting" goku_labels "github.com/eolinker/goku-api-gateway/goku-labels" @@ -18,6 +23,13 @@ import ( //Version 版本号 var Version = "2.0" +var skipCertificate = 0 + +//SetSkipCertificate 设置跳过证书 +func SetSkipCertificate(skip int) { + skipCertificate = skip +} + //Request request type Request struct { client *http.Client @@ -40,6 +52,14 @@ func NewRequest(method string, URL *url.URL) (*Request, error) { return newRequest(method, URL) } +//URLPath urlPath +func URLPath(url string, query url.Values) string { + if len(query) < 1 { + return url + } + return url + "?" + query.Encode() +} + func newRequest(method string, URL *url.URL) (*Request, error) { var urlPath string queryParams := make(map[string][]string) @@ -47,8 +67,14 @@ func newRequest(method string, URL *url.URL) (*Request, error) { queryParams[key] = values } urlPath = URL.Scheme + "://" + URL.Host + URL.Path + tp := http.DefaultTransport + if skipCertificate == 1 { + tp = &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + } r := &Request{ - client: &http.Client{}, + client: &http.Client{Transport: tp}, method: method, URL: urlPath, headers: make(map[string][]string), @@ -95,12 +121,13 @@ func (r *Request) SetTimeout(timeout time.Duration) { //} //Send 发送请求 -func (r *Request) Send() (*http.Response, error) { +func (r *Request) Send(ctx goku_plugin.ContextAccess) (*http.Response, error) { // now := time.Now() req, err := r.parseBody() if err != nil { return nil, err } + status := 0 start := time.Now() defer func() { delay := time.Since(start) @@ -110,6 +137,9 @@ func (r *Request) Send() (*http.Response, error) { labels[goku_labels.Host] = req.Host labels[goku_labels.Path] = req.URL.Path labels[goku_labels.Method] = req.Method + labels[goku_labels.API] = strconv.Itoa(ctx.ApiID()) + labels[goku_labels.Strategy] = ctx.StrategyId() + labels[goku_labels.Status] = strconv.Itoa(status) monitor.ProxyMonitor.Observe(float64(delay/time.Millisecond), labels) }() req.Header.Set("Accept-Encoding", "gzip") @@ -120,8 +150,18 @@ func (r *Request) Send() (*http.Response, error) { httpResponse, err := r.client.Do(req) if err != nil { + if netErr, ok := err.(net.Error); ok { + if netErr.Timeout() { + status = 504 + } else { + status = 503 + } + } else { + status = 503 + } return nil, err } + status = httpResponse.StatusCode return httpResponse, nil } diff --git a/goku-service/application/service.go b/goku-service/application/service.go index 80d69145863d0f946d544d553dd87a9aaf6b537d..0053070896dc448ff3f8d6d8cf47f612d249a65a 100644 --- a/goku-service/application/service.go +++ b/goku-service/application/service.go @@ -2,6 +2,7 @@ package application import ( "fmt" + goku_plugin "github.com/eolinker/goku-plugin" "net/http" "net/url" "time" @@ -27,7 +28,7 @@ func NewApplication(service *common.Service, healthCheckHandler health.CheckHand } //Send send -func (app *Application) Send(proto string, method string, path string, querys url.Values, header http.Header, body []byte, timeout time.Duration, retry int) (*http.Response, string, []string, error) { +func (app *Application) Send(ctx goku_plugin.ContextAccess,proto string, method string, path string, querys url.Values, header http.Header, body []byte, timeout time.Duration, retry int) (*http.Response, string, []string, error) { var response *http.Response var err error @@ -51,7 +52,7 @@ func (app *Application) Send(proto string, method string, path string, querys ur RetryTargetServers = append(RetryTargetServers, FinalTargetServer) u := fmt.Sprintf("%s://%s/%s", proto, FinalTargetServer, path) - response, err = request(method, u, querys, header, body, timeout) + response, err = request(ctx,method, u, querys, header, body, timeout) if err != nil { if app.healthCheckHandler.IsNeedCheck() { diff --git a/goku-service/discovery/config.go b/goku-service/discovery/config.go index acf42edc50a39c9dad245b77a717290583833c73..5844159aebcf707c976dbe63bf673e810a3ca856 100644 --- a/goku-service/discovery/config.go +++ b/goku-service/discovery/config.go @@ -1,2 +1 @@ package discovery - diff --git a/goku-service/driver/static/static-node.go b/goku-service/driver/static/static-node.go index 5856d0ae0e7efe3cd80659b077d628e18e02de1e..7bb01c20d38c2819b1c987693e53741caddf82ed 100644 --- a/goku-service/driver/static/static-node.go +++ b/goku-service/driver/static/static-node.go @@ -16,35 +16,35 @@ func (d *Driver) Open(name string, config string) (discovery.ISource, error) { } //StaticDiscovery staticDiscovery -type StaticDiscovery struct { +type Discovery struct { } //SetConfig setConfig -func (d *StaticDiscovery) SetConfig(config string) error { +func (d *Discovery) SetConfig(config string) error { return nil } //Driver driver -func (d *StaticDiscovery) Driver() string { +func (d *Discovery) Driver() string { return DriverName } //SetCallback setCallBack -func (d *StaticDiscovery) SetCallback(callback func(services []*common.Service)) { +func (d *Discovery) SetCallback(callback func(services []*common.Service)) { return } //GetServers getServers -func (d *StaticDiscovery) GetServers() ([]*common.Service, error) { +func (d *Discovery) GetServers() ([]*common.Service, error) { return nil, nil } //Close close -func (d *StaticDiscovery) Close() error { +func (d *Discovery) Close() error { return nil } //Open open -func (d *StaticDiscovery) Open() error { +func (d *Discovery) Open() error { return nil } diff --git a/goku-service/driver/static/staticSources.go b/goku-service/driver/static/staticSources.go index 7df29b8d2c2e1c3a0a864eba839507dbf462b4e6..23950e14da3e9da979da7166c3f6090ee28cfa6a 100644 --- a/goku-service/driver/static/staticSources.go +++ b/goku-service/driver/static/staticSources.go @@ -22,7 +22,7 @@ var ErrorNoInstance = errors.New("no instance") type Sources struct { name string - discovery *StaticDiscovery + discovery *Discovery healthCheckHandler health.CheckHandler instanceFactory *common.InstanceFactory } @@ -74,7 +74,7 @@ func NewStaticSources(name string) *Sources { return &Sources{ name: name, - discovery: new(StaticDiscovery), + discovery: new(Discovery), healthCheckHandler: &health.CheckBox{}, instanceFactory: common.NewInstanceFactory(), } diff --git a/ksitigarbha/export.go b/ksitigarbha/export.go new file mode 100644 index 0000000000000000000000000000000000000000..cfe4b93caaa34b54bc4bc84419c1e312da21d5a1 --- /dev/null +++ b/ksitigarbha/export.go @@ -0,0 +1,46 @@ +package ksitigarbha + +import ( + log "github.com/eolinker/goku-api-gateway/goku-log" +) + +var mManager = newModelManager() + +//GetMonitorModuleNames 获取监控模块名称列表 +func GetMonitorModuleNames() []string { + return mManager.getModuleNames() +} + +//GetMonitorModuleModel 获取 +func GetMonitorModuleModel(name string) (IModule, bool) { + return mManager.getModuleModel(name) +} + +//GetNameSpaceByName 获取namespace +func GetNameSpaceByName(name string) (namespace string, has bool) { + return mManager.getNameSpace(name) + +} + +//Register 注册 +func Register(name string, f IModule) { + if f == nil { + log.Panic("register ksitigarbha nil") + } + mManager.add(name, f) +} + +//Close close +func Close(name string) { + mManager.Close(name) +} + +//Open open +func Open(name string, config string) { + mManager.Open(name, config) +} + +//HandlerConfig HandlerConfig +func HandlerConfig(name string, handler ConfigHandler) { + mManager.Handler(name, handler) +} diff --git a/ksitigarbha/factory.go b/ksitigarbha/factory.go index 67f91a1d03009de00eecd6833957d80db27747ce..3194bb8b45438210fe5d2a4ebdb98bbe053b5607 100644 --- a/ksitigarbha/factory.go +++ b/ksitigarbha/factory.go @@ -1,13 +1,13 @@ package ksitigarbha +//IModule IModule type IModule interface { GetModel() []Model GetDesc() string GetName() string - GetNameSpace()string + GetNameSpace() string GetDefaultConfig() interface{} //CheckConfig(interface{}) bool - Decode(config string) (interface{},error) - Encoder(v interface{}) (string,error) - + Decode(config string) (interface{}, error) + Encode(v interface{}) (string, error) } diff --git a/ksitigarbha/module.go b/ksitigarbha/module.go index ba034012c7923063723645696b7d53f32ca880fd..301d51525e655829edc60634997ef4f45943d403 100644 --- a/ksitigarbha/module.go +++ b/ksitigarbha/module.go @@ -11,41 +11,46 @@ type modelManager struct { modules map[string]IModule names []string namespaceNames map[string]string + handlers map[string][]ConfigHandler } -func newModelManager() *modelManager { - return &modelManager{ - modules: make(map[string]IModule), - names: make([]string,0,5), - namespaceNames: make(map[string]string), - } +func (m *modelManager) Handler(name string, handler ConfigHandler) { + m.handlers[name] = append(m.handlers[name],handler) } -var mManager = newModelManager() - -//GetMonitorModuleNames 获取监控模块名称列表 -func GetMonitorModuleNames() []string { - return mManager.getModuleNames() +func (m *modelManager) Close(name string) { + namespace,has:= m.getNameSpace(name) + if !has{ + return + } + hs:=m.handlers[name] + for _,handler:=range hs{ + handler.OnClose(namespace,name) + } } -//GetMonitorModuleModel 获取 -func GetMonitorModuleModel(name string) (IModule ,bool){ - return mManager.getModuleModel(name) -} +func (m *modelManager) Open(name string, config string) { + namespace,has:= m.getNameSpace(name) + if !has{ + return + } + hs:=m.handlers[name] -//GetNameSpaceByName 获取namespace -func GetNameSpaceByName(name string) string { - return mManager.getNameSpace(name) -} -//Register 注册 -func Register(name string,f IModule) { - if f==nil { - log.Panic("register ksitigarbha nil") + for _,handler:=range hs{ + handler.OnOpen(namespace,name,config) } - mManager.add(name,f) +} +func newModelManager() *modelManager { + return &modelManager{ + modules: make(map[string]IModule), + names: make([]string,0,5), + namespaceNames: make(map[string]string), + handlers: make(map[string][]ConfigHandler), + } } + func (m *modelManager) add(name string,f IModule) { _,has:=m.modules[name] @@ -73,8 +78,9 @@ func (m *modelManager) isExisted(name string) bool { return ok } -func (m *modelManager) getNameSpace(name string) string { - return m.namespaceNames[name] +func (m *modelManager) getNameSpace(name string) (namespace string,has bool) { + namespace,has = m.namespaceNames[name] + return } func (m *modelManager) getModuleCount() int { count := len(m.modules) diff --git a/ksitigarbha/register.go b/ksitigarbha/register.go new file mode 100644 index 0000000000000000000000000000000000000000..e31ac384a01c3cc78d8d45e0a0196b81a3f4cc0b --- /dev/null +++ b/ksitigarbha/register.go @@ -0,0 +1,13 @@ +package ksitigarbha + +//ConfigHandler configHandler +type ConfigHandler interface { + OnOpen(namespace, name, config string) + OnClose(namespace, name string) +} + +type _H interface { + Handler(namespace string, handler ConfigHandler) + Close(namespace string) + Open(namespace string, config string) +} diff --git a/module/graphite/config/config.go b/module/graphite/config/config.go index c6dafe1eeebdd572d8b2c3ab4dda3d91ca464285..e9206ef2d20d6b1f78e3cf18e35636dbf9010d6d 100644 --- a/module/graphite/config/config.go +++ b/module/graphite/config/config.go @@ -11,8 +11,8 @@ import ( //ModuleNameSpace 模块空间名称 const ModuleNameSpace = "diting.graphite" const moduleName = "Graphite" -const desc = "API监控模块对接Graphite(udp by minute)" -const addressPattern = `^[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]$` +const desc = "对接Graphite(数据每分钟更新)" +const addressPattern = `^[-A-Za-z0-9\.]+(:\d+)$` const content = `[ { "type": "line", @@ -24,7 +24,7 @@ const content = `[ "name":"accessAddress", "placeholder":"", "required":true, - "pattern":"` + addressPattern + `" + "pattern":"" } ] } @@ -36,13 +36,17 @@ var ( ) func init() { - json.Unmarshal([]byte(content), &mode) + err := json.Unmarshal([]byte(content), &mode) + if err != nil { + panic(err) + } r, err := regexp.Compile(addressPattern) if err != nil { panic("init graphite module error:" + err.Error()) } addressMatcher = r + mode[0].Items[0]["pattern"] = addressPattern } //GraphiteModule 配置 @@ -81,8 +85,8 @@ func (c *GraphiteModule) GetDefaultConfig() interface{} { } } -//Encoder encoder -func (c *GraphiteModule) Encoder(v interface{}) (string, error) { +//Write encoder +func (c *GraphiteModule) Encode(v interface{}) (string, error) { if v == nil { return "", nil } @@ -94,7 +98,7 @@ func (c *GraphiteModule) Encoder(v interface{}) (string, error) { return "", errors.New("illegal config") } -//Decode decode +//Read decode func Decode(config string) (*GraphiteConfig, error) { mc := new(GraphiteConfig) err := json.Unmarshal([]byte(config), &mc) @@ -110,7 +114,7 @@ func Decode(config string) (*GraphiteConfig, error) { return mc, nil } -//Decode decode +//Read decode func (c *GraphiteModule) Decode(config string) (interface{}, error) { return Decode(config) } diff --git a/module/graphite/count.go b/module/graphite/count.go index 95907d2ee87a9a6159b6788fcd7d6d66e209470b..a4be6c8584e2e686a6737223adbfce3d370dc52e 100644 --- a/module/graphite/count.go +++ b/module/graphite/count.go @@ -15,7 +15,7 @@ type Count struct { metricsValuesCount *MetricsValuesCount } -//Add add +//RegisterDao add func (c *Count) Add(value float64, labels diting.Labels) { key := c.metricKey.Key(labels, "count") @@ -61,7 +61,7 @@ func NewMetricsValuesCount() *MetricsValuesCount { } } -//Add add +//RegisterDao add func (m *MetricsValuesCount) Add(key string, value float64) { m.locker.Lock() v := int64(value) diff --git a/module/graphite/histogram.go b/module/graphite/histogram.go index 9d3c8530120d7d846bff7db48330347b6197ccb0..63abec03432ece5985896ddb3f12a781c7f0265e 100644 --- a/module/graphite/histogram.go +++ b/module/graphite/histogram.go @@ -12,59 +12,72 @@ import ( "github.com/marpaia/graphite-golang" ) -//Histogram histogram +//HistogramObserve histogram type Histogram struct { metricKey MetricKey - keyHistogram *_KeyHistogram + buckets []float64 + histograms map[string]observe.HistogramObserve + locker sync.Mutex } //NewHistogram new histogram func NewHistogram(metricKey MetricKey, buckets []float64) *Histogram { return &Histogram{ metricKey: metricKey, - keyHistogram: newKeyHistogram(buckets), + buckets: buckets, + histograms: make(map[string]observe.HistogramObserve), + locker: sync.Mutex{}, } } //Observe observe func (h *Histogram) Observe(value float64, labels diting.Labels) { key := h.metricKey.Key(labels, "") - h.keyHistogram.Observe(key, value) + h.locker.Lock() + + hv, has := h.histograms[key] + if !has { + hv = observe.NewHistogramObserve(len(h.buckets)) + h.histograms[key] = hv + } + + h.locker.Unlock() + hv.Observe(h.buckets,value) } //Metrics metrics func (h *Histogram) Metrics() []graphite.Metric { - all := h.keyHistogram.Collapse() + all := h.Collapse() if len(all) == 0 { return nil } keySize := len(all) - size := keySize * (len(h.keyHistogram.buckets) + 5) + size := keySize * (len(h.buckets) + 5) ms := make([]graphite.Metric, 0, size) t := time.Now().Unix() tmpName := make([]string, 2) tmpBucketName := make([]string, 3) tmpBucketName[0] = "bucket_le" - overIndex := len(h.keyHistogram.buckets) + //overIndex := len(h.keyHistogram.buckets) for k, v := range all { tmpName[0] = k - + values, sum, max, min, count := v.Collapse() tmpName[1] = "count" - ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.Itoa(v.count), t)) + ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatUint(count, 10), t)) tmpName[1] = "max" - ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatFloat(v.max, 'f', 2, 64), t)) + ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatFloat(max, 'f', 2, 64), t)) tmpName[1] = "min" - ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatFloat(v.min, 'f', 2, 64), t)) + ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatFloat(min, 'f', 2, 64), t)) tmpName[1] = "sum" - ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatFloat(v.sum, 'f', 2, 64), t)) + ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatFloat(sum, 'f', 2, 64), t)) tmpName[1] = "bucket_le_inf" - ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatInt(v.list[overIndex], 10), t)) + ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatUint(count, 10), t)) - for i, b := range h.keyHistogram.buckets { + for i, b := range h.buckets { floor := math.Floor(b) tmpBucketName[1] = strconv.FormatInt(int64(floor), 10) if floor-b < 0 { @@ -74,73 +87,22 @@ func (h *Histogram) Metrics() []graphite.Metric { tmpName[1] = strings.Join(tmpBucketName[:2], "_") } - ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatInt(v.list[i], 10), t)) + ms = append(ms, graphite.NewMetric(strings.Join(tmpName, "."), strconv.FormatUint(values[i], 10), t)) } } return ms } -type _KeyHistogram struct { - buckets []float64 - histograms map[string]observe.Histogram - locker sync.Mutex -} - -func newKeyHistogram(buckets []float64) *_KeyHistogram { - return &_KeyHistogram{ - buckets: buckets, - histograms: make(map[string]observe.Histogram), - locker: sync.Mutex{}, - } -} - -//HistogramValue histogramValue -type HistogramValue struct { - list []int64 - max float64 - min float64 - count int - sum float64 -} - //Collapse collapse -func (k *_KeyHistogram) Collapse() map[string]HistogramValue { - - new := make(map[string]observe.Histogram) - k.locker.Lock() - histograms := k.histograms - k.histograms = new - k.locker.Unlock() - - values := make(map[string]HistogramValue) - for k, hm := range histograms { - col, sum, max, min, count := hm.Collapse() - values[k] = HistogramValue{ - list: col, - max: max, - min: min, - count: count, - sum: sum, - } - } +func (h *Histogram) Collapse() map[string]observe.HistogramObserve { - return values -} -func (k *_KeyHistogram) get(key string) observe.Histogram { - k.locker.Lock() + n := make(map[string]observe.HistogramObserve) + h.locker.Lock() + histograms := h.histograms + h.histograms = n + h.locker.Unlock() - h, has := k.histograms[key] - if !has { - h = observe.NewHistogram(k.buckets) - k.histograms[key] = h - } - - k.locker.Unlock() - return h + return histograms } -//Observe observe -func (k *_KeyHistogram) Observe(key string, value float64) { - k.get(key).Observe(value) -} diff --git a/module/graphite/metrics.go b/module/graphite/metrics.go index e7af50c63e4f30af71c7b33c8e25b52c56895ee7..1d22a41846c9baf41adb9314cf0101582df7b9c4 100644 --- a/module/graphite/metrics.go +++ b/module/graphite/metrics.go @@ -28,14 +28,13 @@ func NewMetricKey(name string, labelNames []string) MetricKey { return &_MetricKey{name: name, labelNames: labelNames} } - //Key key func (m *_MetricKey) Key(labels diting.Labels, valueType string) string { tmp := make([]string, 0, len(m.labelNames)+2) tmp = append(tmp, m.name) for _, name := range m.labelNames { - labelValue:= labels[name] + labelValue := labels[name] tmp = append(tmp, formatLabelValue(labelValue)) } @@ -45,14 +44,15 @@ func (m *_MetricKey) Key(labels diting.Labels, valueType string) string { return strings.Join(tmp, ".") } -const rep = '_' +const rep = '_' + //formatLabelValue 将label value的所有字母、数字转换成 _ -func formatLabelValue(value string)string { - s:=[]rune(value) +func formatLabelValue(value string) string { + s := []rune(value) for i, r := range s { if !unicode.IsLetter(r) && !unicode.IsNumber(r) { s[i] = rep } } return string(s) -} \ No newline at end of file +} diff --git a/module/httprouter/.travis.yml b/module/httprouter/.travis.yml new file mode 100644 index 0000000000000000000000000000000000000000..477807dd423e549ae12b4ca4cac0684a6d5e7dd9 --- /dev/null +++ b/module/httprouter/.travis.yml @@ -0,0 +1,18 @@ +sudo: false +language: go +go: + - 1.7 + - 1.8 + - 1.9 + - "1.10" + - tip +before_install: + - go get golang.org/x/tools/cmd/cover + - go get github.com/mattn/goveralls + - go get github.com/golang/lint/golint +script: + - go test -v -covermode=count -coverprofile=coverage.out + - go vet ./... + - test -z "$(gofmt -d -s . | tee /dev/stderr)" + - test -z "$(golint ./... | tee /dev/stderr)" + - $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci diff --git a/module/httprouter/LICENSE b/module/httprouter/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..b829abc8a17fe98be0d64dc5ee01c2979598b377 --- /dev/null +++ b/module/httprouter/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2013 Julien Schmidt. All rights reserved. + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * The names of the contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL JULIEN SCHMIDT BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/module/httprouter/README.md b/module/httprouter/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c5903103c2291adb47467810b597c0b2914d4dfb --- /dev/null +++ b/module/httprouter/README.md @@ -0,0 +1,269 @@ +# HttpRouter [![Build Status](https://travis-ci.org/julienschmidt/httprouter.svg?branch=master)](https://travis-ci.org/julienschmidt/httprouter) [![Coverage Status](https://coveralls.io/repos/github/julienschmidt/httprouter/badge.svg?branch=master)](https://coveralls.io/github/julienschmidt/httprouter?branch=master) [![GoDoc](https://godoc.org/github.com/julienschmidt/httprouter?status.svg)](http://godoc.org/github.com/julienschmidt/httprouter) + +HttpRouter is a lightweight high performance HTTP request router (also called *multiplexer* or just *mux* for short) for [Go](https://golang.org/). + +In contrast to the [default mux](https://golang.org/pkg/net/http/#ServeMux) of Go's `net/http` package, this router supports variables in the routing pattern and matches against the request method. It also scales better. + +The router is optimized for high performance and a small memory footprint. It scales well even with very long paths and a large number of routes. A compressing dynamic trie (radix tree) structure is used for efficient matching. + +## Features + +**Only explicit matches:** With other routers, like [`http.ServeMux`](https://golang.org/pkg/net/http/#ServeMux), a requested URL path could match multiple patterns. Therefore they have some awkward pattern priority rules, like *longest match* or *first registered, first matched*. By design of this router, a request can only match exactly one or no route. As a result, there are also no unintended matches, which makes it great for SEO and improves the user experience. + +**Stop caring about trailing slashes:** Choose the URL style you like, the router automatically redirects the client if a trailing slash is missing or if there is one extra. Of course it only does so, if the new path has a handler. If you don't like it, you can [turn off this behavior](https://godoc.org/github.com/julienschmidt/httprouter#Router.RedirectTrailingSlash). + +**Path auto-correction:** Besides detecting the missing or additional trailing slash at no extra cost, the router can also fix wrong cases and remove superfluous path elements (like `../` or `//`). Is [CAPTAIN CAPS LOCK](http://www.urbandictionary.com/define.php?term=Captain+Caps+Lock) one of your users? HttpRouter can help him by making a case-insensitive look-up and redirecting him to the correct URL. + +**Parameters in your routing pattern:** Stop parsing the requested URL path, just give the path segment a name and the router delivers the dynamic value to you. Because of the design of the router, path parameters are very cheap. + +**Zero Garbage:** The matching and dispatching process generates zero bytes of garbage. The only heap allocations that are made are building the slice of the key-value pairs for path parameters, and building new context and request objects (the latter only in the standard `Handler`/`HandlerFunc` api). In the 3-argument API, if the request path contains no parameters not a single heap allocation is necessary. + +**Best Performance:** [Benchmarks speak for themselves](https://github.com/julienschmidt/go-http-routing-benchmark). See below for technical details of the implementation. + +**No more server crashes:** You can set a [Panic handler](https://godoc.org/github.com/julienschmidt/httprouter#Router.PanicHandler) to deal with panics occurring during handling a HTTP request. The router then recovers and lets the `PanicHandler` log what happened and deliver a nice error page. + +**Perfect for APIs:** The router design encourages to build sensible, hierarchical RESTful APIs. Moreover it has builtin native support for [OPTIONS requests](http://zacstewart.com/2012/04/14/http-options-method.html) and `405 Method Not Allowed` replies. + +Of course you can also set **custom [`NotFound`](https://godoc.org/github.com/julienschmidt/httprouter#Router.NotFound) and [`MethodNotAllowed`](https://godoc.org/github.com/julienschmidt/httprouter#Router.MethodNotAllowed) handlers** and [**serve static files**](https://godoc.org/github.com/julienschmidt/httprouter#Router.ServeFiles). + +## Usage + +This is just a quick introduction, view the [GoDoc](http://godoc.org/github.com/julienschmidt/httprouter) for details. + +Let's start with a trivial example: + +```go +package main + +import ( + "fmt" + "github.com/julienschmidt/httprouter" + "net/http" + "log" +) + +func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + fmt.Fprint(w, "Welcome!\n") +} + +func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { + fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name")) +} + +func main() { + router := httprouter.New() + router.GET("/", Index) + router.GET("/hello/:name", Hello) + + log.Fatal(http.ListenAndServe(":8080", router)) +} +``` + +### Named parameters + +As you can see, `:name` is a *named parameter*. The values are accessible via `httprouter.Params`, which is just a slice of `httprouter.Param`s. You can get the value of a parameter either by its index in the slice, or by using the `ByName(name)` method: `:name` can be retrived by `ByName("name")`. + +Named parameters only match a single path segment: + +``` +Pattern: /user/:user + + /user/gordon match + /user/you match + /user/gordon/profile no match + /user/ no match +``` + +**Note:** Since this router has only explicit matches, you can not register static routes and parameters for the same path segment. For example you can not register the patterns `/user/new` and `/user/:user` for the same request method at the same time. The routing of different request methods is independent from each other. + +### Catch-All parameters + +The second type are *catch-all* parameters and have the form `*name`. Like the name suggests, they match everything. Therefore they must always be at the **end** of the pattern: + +``` +Pattern: /src/*filepath + + /src/ match + /src/somefile.go match + /src/subdir/somefile.go match +``` + +## How does it work? + +The router relies on a tree structure which makes heavy use of *common prefixes*, it is basically a *compact* [*prefix tree*](https://en.wikipedia.org/wiki/Trie) (or just [*Radix tree*](https://en.wikipedia.org/wiki/Radix_tree)). Nodes with a common prefix also share a common parent. Here is a short example what the routing tree for the `GET` request method could look like: + +``` +Priority Path Handle +9 \ *<1> +3 ├s nil +2 |├earch\ *<2> +1 |└upport\ *<3> +2 ├blog\ *<4> +1 | └:post nil +1 | └\ *<5> +2 ├about-us\ *<6> +1 | └team\ *<7> +1 └contact\ *<8> +``` + +Every `*` represents the memory address of a handler function (a pointer). If you follow a path trough the tree from the root to the leaf, you get the complete route path, e.g `\blog\:post\`, where `:post` is just a placeholder ([*parameter*](#named-parameters)) for an actual post name. Unlike hash-maps, a tree structure also allows us to use dynamic parts like the `:post` parameter, since we actually match against the routing patterns instead of just comparing hashes. [As benchmarks show](https://github.com/julienschmidt/go-http-routing-benchmark), this works very well and efficient. + +Since URL paths have a hierarchical structure and make use only of a limited set of characters (byte values), it is very likely that there are a lot of common prefixes. This allows us to easily reduce the routing into ever smaller problems. Moreover the router manages a separate tree for every request method. For one thing it is more space efficient than holding a method->handle map in every single node, it also allows us to greatly reduce the routing problem before even starting the look-up in the prefix-tree. + +For even better scalability, the child nodes on each tree level are ordered by priority, where the priority is just the number of handles registered in sub nodes (children, grandchildren, and so on..). This helps in two ways: + +1. Nodes which are part of the most routing paths are evaluated first. This helps to make as much routes as possible to be reachable as fast as possible. +2. It is some sort of cost compensation. The longest reachable path (highest cost) can always be evaluated first. The following scheme visualizes the tree structure. Nodes are evaluated from top to bottom and from left to right. + +``` +├------------ +├--------- +├----- +├---- +├-- +├-- +└- +``` + +## Why doesn't this work with `http.Handler`? + +**It does!** The router itself implements the `http.Handler` interface. Moreover the router provides convenient [adapters for `http.Handler`](https://godoc.org/github.com/julienschmidt/httprouter#Router.Handler)s and [`http.HandlerFunc`](https://godoc.org/github.com/julienschmidt/httprouter#Router.HandlerFunc)s which allows them to be used as a [`httprouter.Handle`](https://godoc.org/github.com/julienschmidt/httprouter#Router.Handle) when registering a route. The only disadvantage is, that no parameter values can be retrieved when a `http.Handler` or `http.HandlerFunc` is used, since there is no efficient way to pass the values with the existing function parameters. Therefore [`httprouter.Handle`](https://godoc.org/github.com/julienschmidt/httprouter#Router.Handle) has a third function parameter. + +Just try it out for yourself, the usage of HttpRouter is very straightforward. The package is compact and minimalistic, but also probably one of the easiest routers to set up. + +## Where can I find Middleware *X*? + +This package just provides a very efficient request router with a few extra features. The router is just a [`http.Handler`](https://golang.org/pkg/net/http/#Handler), you can chain any http.Handler compatible middleware before the router, for example the [Gorilla handlers](http://www.gorillatoolkit.org/pkg/handlers). Or you could [just write your own](https://justinas.org/writing-http-middleware-in-go/), it's very easy! + +Alternatively, you could try [a web framework based on HttpRouter](#web-frameworks-based-on-httprouter). + +### Multi-domain / Sub-domains + +Here is a quick example: Does your server serve multiple domains / hosts? +You want to use sub-domains? +Define a router per host! + +```go +// We need an object that implements the http.Handler interface. +// Therefore we need a type for which we implement the ServeHTTP method. +// We just use a map here, in which we map host names (with port) to http.Handlers +type HostSwitch map[string]http.Handler + +// Implement the ServeHTTP method on our new type +func (hs HostSwitch) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // Check if a http.Handler is registered for the given host. + // If yes, use it to handle the request. + if handler := hs[r.Host]; handler != nil { + handler.ServeHTTP(w, r) + } else { + // Handle host names for which no handler is registered + http.Error(w, "Forbidden", 403) // Or Redirect? + } +} + +func main() { + // Initialize a router as usual + router := httprouter.New() + router.GET("/", Index) + router.GET("/hello/:name", Hello) + + // Make a new HostSwitch and insert the router (our http handler) + // for example.com and port 12345 + hs := make(HostSwitch) + hs["example.com:12345"] = router + + // Use the HostSwitch to listen and serve on port 12345 + log.Fatal(http.ListenAndServe(":12345", hs)) +} +``` + +### Basic Authentication + +Another quick example: Basic Authentication (RFC 2617) for handles: + +```go +package main + +import ( + "fmt" + "log" + "net/http" + + "github.com/julienschmidt/httprouter" +) + +func BasicAuth(h httprouter.Handle, requiredUser, requiredPassword string) httprouter.Handle { + return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { + // Get the Basic Authentication credentials + user, password, hasAuth := r.BasicAuth() + + if hasAuth && user == requiredUser && password == requiredPassword { + // Delegate request to the given handle + h(w, r, ps) + } else { + // Request Basic Authentication otherwise + w.Header().Set("WWW-Authenticate", "Basic realm=Restricted") + http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) + } + } +} + +func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + fmt.Fprint(w, "Not protected!\n") +} + +func Protected(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + fmt.Fprint(w, "Protected!\n") +} + +func main() { + user := "gordon" + pass := "secret!" + + router := httprouter.New() + router.GET("/", Index) + router.GET("/protected/", BasicAuth(Protected, user, pass)) + + log.Fatal(http.ListenAndServe(":8080", router)) +} +``` + +## Chaining with the NotFound handler + +**NOTE: It might be required to set [`Router.HandleMethodNotAllowed`](https://godoc.org/github.com/julienschmidt/httprouter#Router.HandleMethodNotAllowed) to `false` to avoid problems.** + +You can use another [`http.Handler`](https://golang.org/pkg/net/http/#Handler), for example another router, to handle requests which could not be matched by this router by using the [`Router.NotFound`](https://godoc.org/github.com/julienschmidt/httprouter#Router.NotFound) handler. This allows chaining. + +### Static files + +The `NotFound` handler can for example be used to serve static files from the root path `/` (like an `index.html` file along with other assets): + +```go +// Serve static files from the ./public directory +router.NotFound = http.FileServer(http.Dir("public")) +``` + +But this approach sidesteps the strict core rules of this router to avoid routing problems. A cleaner approach is to use a distinct sub-path for serving files, like `/static/*filepath` or `/files/*filepath`. + +## Web Frameworks based on HttpRouter + +If the HttpRouter is a bit too minimalistic for you, you might try one of the following more high-level 3rd-party web frameworks building upon the HttpRouter package: + +* [Ace](https://github.com/plimble/ace): Blazing fast Go Web Framework +* [api2go](https://github.com/manyminds/api2go): A JSON API Implementation for Go +* [Gin](https://github.com/gin-gonic/gin): Features a martini-like API with much better performance +* [Goat](https://github.com/bahlo/goat): A minimalistic REST API server in Go +* [goMiddlewareChain](https://github.com/TobiEiss/goMiddlewareChain): An express.js-like-middleware-chain +* [Hikaru](https://github.com/najeira/hikaru): Supports standalone and Google AppEngine +* [Hitch](https://github.com/nbio/hitch): Hitch ties httprouter, [httpcontext](https://github.com/nbio/httpcontext), and middleware up in a bow +* [httpway](https://github.com/corneldamian/httpway): Simple middleware extension with context for httprouter and a server with gracefully shutdown support +* [kami](https://github.com/guregu/kami): A tiny web framework using x/net/context +* [Medeina](https://github.com/imdario/medeina): Inspired by Ruby's Roda and Cuba +* [Neko](https://github.com/rocwong/neko): A lightweight web application framework for Golang +* [River](https://github.com/abiosoft/river): River is a simple and lightweight REST server +* [Roxanna](https://github.com/iamthemuffinman/Roxanna): An amalgamation of httprouter, better logging, and hot reload +* [siesta](https://github.com/VividCortex/siesta): Composable HTTP handlers with contexts +* [xmux](https://github.com/rs/xmux): xmux is a httprouter fork on top of xhandler (net/context aware) + +---- +此处对tree.go方法getValue方法进行修改,以适应匹配前缀的需求 \ No newline at end of file diff --git a/module/httprouter/params_go17.go b/module/httprouter/params_go17.go new file mode 100644 index 0000000000000000000000000000000000000000..abb4209d4df0e9e64b310b3265d551b54463abc0 --- /dev/null +++ b/module/httprouter/params_go17.go @@ -0,0 +1,38 @@ +// +build go1.7 + +package httprouter + +import ( + "context" + "net/http" +) + +type paramsKey struct{} + +// ParamsKey is the request context key under which URL params are stored. +// +// This is only present from go 1.7. +var ParamsKey = paramsKey{} + +// Handler is an adapter which allows the usage of an http.Handler as a +// request handle. With go 1.7+, the Params will be available in the +// request context under ParamsKey. +func (r *Router) Handler(method, path string, handler http.Handler) { + r.Handle(method, path, + func(w http.ResponseWriter, req *http.Request, p Params) { + ctx := req.Context() + ctx = context.WithValue(ctx, ParamsKey, p) + req = req.WithContext(ctx) + handler.ServeHTTP(w, req) + }, + ) +} + +// ParamsFromContext pulls the URL parameters from a request context, +// or returns nil if none are present. +// +// This is only present from go 1.7. +func ParamsFromContext(ctx context.Context) Params { + p, _ := ctx.Value(ParamsKey).(Params) + return p +} diff --git a/module/httprouter/params_legacy.go b/module/httprouter/params_legacy.go new file mode 100644 index 0000000000000000000000000000000000000000..0278a44164c09cde22d85897092ea4ad3faeeb73 --- /dev/null +++ b/module/httprouter/params_legacy.go @@ -0,0 +1,16 @@ +// +build !go1.7 + +package httprouter + +import "net/http" + +// Handler is an adapter which allows the usage of an http.Handler as a +// request handle. With go 1.7+, the Params will be available in the +// request context under ParamsKey. +func (r *Router) Handler(method, path string, handler http.Handler) { + r.Handle(method, path, + func(w http.ResponseWriter, req *http.Request, _ Params) { + handler.ServeHTTP(w, req) + }, + ) +} diff --git a/module/httprouter/path.go b/module/httprouter/path.go new file mode 100644 index 0000000000000000000000000000000000000000..0331c7ec6d210190b959ec1f06f00e926f8c3953 --- /dev/null +++ b/module/httprouter/path.go @@ -0,0 +1,123 @@ +// Copyright 2013 Julien Schmidt. All rights reserved. +// Based on the path package, Copyright 2009 The Go Authors. +// Use of this source code is governed by a BSD-style license that can be found +// in the LICENSE file. + +package httprouter + +// CleanPath is the URL version of path.Clean, it returns a canonical URL path +// for p, eliminating . and .. elements. +// +// The following rules are applied iteratively until no further processing can +// be done: +// 1. Replace multiple slashes with a single slash. +// 2. Eliminate each . path name element (the current directory). +// 3. Eliminate each inner .. path name element (the parent directory) +// along with the non-.. element that precedes it. +// 4. Eliminate .. elements that begin a rooted path: +// that is, replace "/.." by "/" at the beginning of a path. +// +// If the result of this process is an empty string, "/" is returned +func CleanPath(p string) string { + // Turn empty string into "/" + if p == "" { + return "/" + } + + n := len(p) + var buf []byte + + // Invariants: + // reading from path; r is index of next byte to process. + // writing to buf; w is index of next byte to write. + + // path must start with '/' + r := 1 + w := 1 + + if p[0] != '/' { + r = 0 + buf = make([]byte, n+1) + buf[0] = '/' + } + + trailing := n > 1 && p[n-1] == '/' + + // A bit more clunky without a 'lazybuf' like the path package, but the loop + // gets completely inlined (bufApp). So in contrast to the path package this + // loop has no expensive function calls (except 1x make) + + for r < n { + switch { + case p[r] == '/': + // empty path element, trailing slash is added after the end + r++ + + case p[r] == '.' && r+1 == n: + trailing = true + r++ + + case p[r] == '.' && p[r+1] == '/': + // . element + r += 2 + + case p[r] == '.' && p[r+1] == '.' && (r+2 == n || p[r+2] == '/'): + // .. element: remove to last / + r += 3 + + if w > 1 { + // can backtrack + w-- + + if buf == nil { + for w > 1 && p[w] != '/' { + w-- + } + } else { + for w > 1 && buf[w] != '/' { + w-- + } + } + } + + default: + // real path element. + // add slash if needed + if w > 1 { + bufApp(&buf, p, w, '/') + w++ + } + + // copy element + for r < n && p[r] != '/' { + bufApp(&buf, p, w, p[r]) + w++ + r++ + } + } + } + + // re-append trailing slash + if trailing && w > 1 { + bufApp(&buf, p, w, '/') + w++ + } + + if buf == nil { + return p[:w] + } + return string(buf[:w]) +} + +// internal helper to lazily create a buffer if necessary +func bufApp(buf *[]byte, s string, w int, c byte) { + if *buf == nil { + if s[w] == c { + return + } + + *buf = make([]byte, len(s)) + copy(*buf, s[:w]) + } + (*buf)[w] = c +} diff --git a/module/httprouter/router.go b/module/httprouter/router.go new file mode 100644 index 0000000000000000000000000000000000000000..558e139226924cbd1ea197f57ca57bd66255d378 --- /dev/null +++ b/module/httprouter/router.go @@ -0,0 +1,399 @@ +// Copyright 2013 Julien Schmidt. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be found +// in the LICENSE file. + +// Package httprouter is a trie based high performance HTTP request router. +// +// A trivial example is: +// +// package main +// +// import ( +// "fmt" +// "github.com/julienschmidt/httprouter" +// "net/http" +// "log" +// ) +// +// func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { +// fmt.Fprint(w, "Welcome!\n") +// } +// +// func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { +// fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name")) +// } +// +// func main() { +// router := httprouter.New() +// router.GET("/", Index) +// router.GET("/hello/:name", Hello) +// +// log.Fatal(http.ListenAndServe(":8080", router)) +// } +// +// The router matches incoming requests by the request method and the path. +// If a handle is registered for this path and method, the router delegates the +// request to that function. +// For the methods GET, POST, PUT, PATCH and DELETE shortcut functions exist to +// register handles, for all other methods router.Handle can be used. +// +// The registered path, against which the router matches incoming requests, can +// contain two types of parameters: +// Syntax Type +// :name named parameter +// *name catch-all parameter +// +// Named parameters are dynamic path segments. They match anything until the +// next '/' or the path end: +// Path: /blog/:category/:post +// +// Requests: +// /blog/go/request-routers match: category="go", post="request-routers" +// /blog/go/request-routers/ no match, but the router would redirect +// /blog/go/ no match +// /blog/go/request-routers/comments no match +// +// Catch-all parameters match anything until the path end, including the +// directory index (the '/' before the catch-all). Since they match anything +// until the end, catch-all parameters must always be the final path element. +// Path: /files/*filepath +// +// Requests: +// /files/ match: filepath="/" +// /files/LICENSE match: filepath="/LICENSE" +// /files/templates/article.html match: filepath="/templates/article.html" +// /files no match, but the router would redirect +// +// The value of parameters is saved as a slice of the Param struct, consisting +// each of a key and a value. The slice is passed to the Handle func as a third +// parameter. +// There are two ways to retrieve the value of a parameter: +// // by the name of the parameter +// user := ps.ByName("user") // defined by :user or *user +// +// // by the index of the parameter. This way you can also get the name (key) +// thirdKey := ps[2].Key // the name of the 3rd parameter +// thirdValue := ps[2].Value // the value of the 3rd parameter +package httprouter + +import ( + "net/http" +) + +// Handle is a function that can be registered to a route to handle HTTP +// requests. Like http.HandlerFunc, but has a third parameter for the values of +// wildcards (variables). +type Handle func(http.ResponseWriter, *http.Request, Params) + +// Param is a single URL parameter, consisting of a key and a value. +type Param struct { + Key string + Value string +} + +// Params is a Param-slice, as returned by the router. +// The slice is ordered, the first URL parameter is also the first slice value. +// It is therefore safe to read values by the index. +type Params []Param + +// ByName returns the value of the first Param which key matches the given name. +// If no matching Param is found, an empty string is returned. +func (ps Params) ByName(name string) string { + for i := range ps { + if ps[i].Key == name { + return ps[i].Value + } + } + return "" +} + +// Router is a http.Handler which can be used to dispatch requests to different +// handler functions via configurable routes +type Router struct { + trees map[string]*node + + // Enables automatic redirection if the current route can't be matched but a + // handler for the path with (without) the trailing slash exists. + // For example if /foo/ is requested but a route only exists for /foo, the + // client is redirected to /foo with http status code 301 for GET requests + // and 307 for all other request methods. + RedirectTrailingSlash bool + + // If enabled, the router tries to fix the current request path, if no + // handle is registered for it. + // First superfluous path elements like ../ or // are removed. + // Afterwards the router does a case-insensitive lookup of the cleaned path. + // If a handle can be found for this route, the router makes a redirection + // to the corrected path with status code 301 for GET requests and 307 for + // all other request methods. + // For example /FOO and /..//Foo could be redirected to /foo. + // RedirectTrailingSlash is independent of this option. + RedirectFixedPath bool + + // If enabled, the router checks if another method is allowed for the + // current route, if the current request can not be routed. + // If this is the case, the request is answered with 'Method Not Allowed' + // and HTTP status code 405. + // If no other Method is allowed, the request is delegated to the NotFound + // handler. + HandleMethodNotAllowed bool + + // If enabled, the router automatically replies to OPTIONS requests. + // Custom OPTIONS handlers take priority over automatic replies. + HandleOPTIONS bool + + // Configurable http.Handler which is called when no matching route is + // found. If it is not set, http.NotFound is used. + NotFound http.Handler + + // Configurable http.Handler which is called when a request + // cannot be routed and HandleMethodNotAllowed is true. + // If it is not set, http.Error with http.StatusMethodNotAllowed is used. + // The "Allow" header with allowed request methods is set before the handler + // is called. + MethodNotAllowed http.Handler + + // Function to handle panics recovered from http handlers. + // It should be used to generate a error page and return the http error code + // 500 (Internal Server Error). + // The handler can be used to keep your server from crashing because of + // unrecovered panics. + PanicHandler func(http.ResponseWriter, *http.Request, interface{}) +} + +// Make sure the Router conforms with the http.Handler interface +var _ http.Handler = New() + +// New returns a new initialized Router. +// Path auto-correction, including trailing slashes, is enabled by default. +func New() *Router { + return &Router{ + RedirectTrailingSlash: true, + RedirectFixedPath: true, + HandleMethodNotAllowed: true, + HandleOPTIONS: true, + } +} + +// GET is a shortcut for router.Handle("GET", path, handle) +func (r *Router) GET(path string, handle Handle) { + r.Handle("GET", path, handle) +} + +// HEAD is a shortcut for router.Handle("HEAD", path, handle) +func (r *Router) HEAD(path string, handle Handle) { + r.Handle("HEAD", path, handle) +} + +// OPTIONS is a shortcut for router.Handle("OPTIONS", path, handle) +func (r *Router) OPTIONS(path string, handle Handle) { + r.Handle("OPTIONS", path, handle) +} + +// POST is a shortcut for router.Handle("POST", path, handle) +func (r *Router) POST(path string, handle Handle) { + r.Handle("POST", path, handle) +} + +// PUT is a shortcut for router.Handle("PUT", path, handle) +func (r *Router) PUT(path string, handle Handle) { + r.Handle("PUT", path, handle) +} + +// PATCH is a shortcut for router.Handle("PATCH", path, handle) +func (r *Router) PATCH(path string, handle Handle) { + r.Handle("PATCH", path, handle) +} + +// DELETE is a shortcut for router.Handle("DELETE", path, handle) +func (r *Router) DELETE(path string, handle Handle) { + r.Handle("DELETE", path, handle) +} + +// Handle registers a new request handle with the given path and method. +// +// For GET, POST, PUT, PATCH and DELETE requests the respective shortcut +// functions can be used. +// +// This function is intended for bulk loading and to allow the usage of less +// frequently used, non-standardized or custom methods (e.g. for internal +// communication with a proxy). +func (r *Router) Handle(method, path string, handle Handle) { + if path[0] != '/' { + panic("path must begin with '/' in path '" + path + "'") + } + + if r.trees == nil { + r.trees = make(map[string]*node) + } + + root := r.trees[method] + if root == nil { + root = new(node) + r.trees[method] = root + } + + root.addRoute(path, handle) +} + +// HandlerFunc is an adapter which allows the usage of an http.HandlerFunc as a +// request handle. +func (r *Router) HandlerFunc(method, path string, handler http.HandlerFunc) { + r.Handler(method, path, handler) +} + +// ServeFiles serves files from the given file system root. +// The path must end with "/*filepath", files are then served from the local +// path /defined/root/dir/*filepath. +// For example if root is "/etc" and *filepath is "passwd", the local file +// "/etc/passwd" would be served. +// Internally a http.FileServer is used, therefore http.NotFound is used instead +// of the Router's NotFound handler. +// To use the operating system's file system implementation, +// use http.Dir: +// router.ServeFiles("/src/*filepath", http.Dir("/var/www")) +func (r *Router) ServeFiles(path string, root http.FileSystem) { + if len(path) < 10 || path[len(path)-10:] != "/*filepath" { + panic("path must end with /*filepath in path '" + path + "'") + } + + fileServer := http.FileServer(root) + + r.GET(path, func(w http.ResponseWriter, req *http.Request, ps Params) { + req.URL.Path = ps.ByName("filepath") + fileServer.ServeHTTP(w, req) + }) +} + +func (r *Router) recv(w http.ResponseWriter, req *http.Request) { + if rcv := recover(); rcv != nil { + r.PanicHandler(w, req, rcv) + } +} + +// Lookup allows the manual lookup of a method + path combo. +// This is e.g. useful to build a framework around this router. +// If the path was found, it returns the handle function and the path parameter +// values. Otherwise the third return value indicates whether a redirection to +// the same path with an extra / without the trailing slash should be performed. +func (r *Router) Lookup(method, path string) (Handle, Params, bool) { + if root := r.trees[method]; root != nil { + return root.getValue(path) + } + return nil, nil, false +} + +func (r *Router) allowed(path, reqMethod string) (allow string) { + if path == "*" { // server-wide + for method := range r.trees { + if method == "OPTIONS" { + continue + } + + // add request method to list of allowed methods + if len(allow) == 0 { + allow = method + } else { + allow += ", " + method + } + } + } else { // specific path + for method := range r.trees { + // Skip the requested method - we already tried this one + if method == reqMethod || method == "OPTIONS" { + continue + } + + handle, _, _ := r.trees[method].getValue(path) + if handle != nil { + // add request method to list of allowed methods + if len(allow) == 0 { + allow = method + } else { + allow += ", " + method + } + } + } + } + if len(allow) > 0 { + allow += ", OPTIONS" + } + return +} + +// ServeHTTP makes the router implement the http.Handler interface. +func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { + if r.PanicHandler != nil { + defer r.recv(w, req) + } + + path := req.URL.Path + + if root := r.trees[req.Method]; root != nil { + if handle, ps, tsr := root.getValue(path); handle != nil { + handle(w, req, ps) + return + } else if req.Method != "CONNECT" && path != "/" { + code := 301 // Permanent redirect, request with GET method + if req.Method != "GET" { + // Temporary redirect, request with same method + // As of Go 1.3, Go does not support status code 308. + code = 307 + } + + if tsr && r.RedirectTrailingSlash { + if len(path) > 1 && path[len(path)-1] == '/' { + req.URL.Path = path[:len(path)-1] + } else { + req.URL.Path = path + "/" + } + http.Redirect(w, req, req.URL.String(), code) + return + } + + // Try to fix the request path + if r.RedirectFixedPath { + fixedPath, found := root.findCaseInsensitivePath( + CleanPath(path), + r.RedirectTrailingSlash, + ) + if found { + req.URL.Path = string(fixedPath) + http.Redirect(w, req, req.URL.String(), code) + return + } + } + } + } + + if req.Method == "OPTIONS" && r.HandleOPTIONS { + // Handle OPTIONS requests + if allow := r.allowed(path, req.Method); len(allow) > 0 { + w.Header().Set("Allow", allow) + return + } + } else { + // Handle 405 + if r.HandleMethodNotAllowed { + if allow := r.allowed(path, req.Method); len(allow) > 0 { + w.Header().Set("Allow", allow) + if r.MethodNotAllowed != nil { + r.MethodNotAllowed.ServeHTTP(w, req) + } else { + http.Error(w, + http.StatusText(http.StatusMethodNotAllowed), + http.StatusMethodNotAllowed, + ) + } + return + } + } + } + + // Handle 404 + if r.NotFound != nil { + r.NotFound.ServeHTTP(w, req) + } else { + http.NotFound(w, req) + } +} diff --git a/module/httprouter/tree.go b/module/httprouter/tree.go new file mode 100644 index 0000000000000000000000000000000000000000..89676c3ef310da1ba00b4600c6b01cf36d8a5f81 --- /dev/null +++ b/module/httprouter/tree.go @@ -0,0 +1,661 @@ +// Copyright 2013 Julien Schmidt. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be found +// in the LICENSE file. +// 此处对getValue方法进行部分修改,以适应匹配前缀的需求 + +package httprouter + +import ( + "strings" + "unicode" + "unicode/utf8" +) + +func min(a, b int) int { + if a <= b { + return a + } + return b +} + +func countParams(path string) uint8 { + var n uint + for i := 0; i < len(path); i++ { + if path[i] != ':' && path[i] != '*' { + continue + } + n++ + } + if n >= 255 { + return 255 + } + return uint8(n) +} + +type nodeType uint8 + +const ( + static nodeType = iota // default + root + param + catchAll +) + +type node struct { + path string + wildChild bool + nType nodeType + maxParams uint8 + indices string + children []*node + handle Handle + priority uint32 +} + +// increments priority of the given child and reorders if necessary +func (n *node) incrementChildPrio(pos int) int { + n.children[pos].priority++ + prio := n.children[pos].priority + + // adjust position (move to front) + newPos := pos + for newPos > 0 && n.children[newPos-1].priority < prio { + // swap node positions + n.children[newPos-1], n.children[newPos] = n.children[newPos], n.children[newPos-1] + + newPos-- + } + + // build new index char string + if newPos != pos { + n.indices = n.indices[:newPos] + // unchanged prefix, might be empty + n.indices[pos:pos+1] + // the index char we move + n.indices[newPos:pos] + n.indices[pos+1:] // rest without char at 'pos' + } + + return newPos +} + +// addRoute adds a node with the given handle to the path. +// Not concurrency-safe! +func (n *node) addRoute(path string, handle Handle) { + fullPath := path + n.priority++ + numParams := countParams(path) + + // non-empty tree + if len(n.path) > 0 || len(n.children) > 0 { + walk: + for { + // Update maxParams of the current node + if numParams > n.maxParams { + n.maxParams = numParams + } + + // Find the longest common prefix. + // This also implies that the common prefix contains no ':' or '*' + // since the existing key can't contain those chars. + i := 0 + max := min(len(path), len(n.path)) + for i < max && path[i] == n.path[i] { + i++ + } + + // Split edge + if i < len(n.path) { + child := node{ + path: n.path[i:], + wildChild: n.wildChild, + nType: static, + indices: n.indices, + children: n.children, + handle: n.handle, + priority: n.priority - 1, + } + + // Update maxParams (max of all children) + for i := range child.children { + if child.children[i].maxParams > child.maxParams { + child.maxParams = child.children[i].maxParams + } + } + + n.children = []*node{&child} + // []byte for proper unicode char conversion, see #65 + n.indices = string([]byte{n.path[i]}) + n.path = path[:i] + n.handle = nil + n.wildChild = false + } + + // Make new node a child of this node + if i < len(path) { + path = path[i:] + + if n.wildChild { + n = n.children[0] + n.priority++ + + // Update maxParams of the child node + if numParams > n.maxParams { + n.maxParams = numParams + } + numParams-- + + // Check if the wildcard matches + if len(path) >= len(n.path) && n.path == path[:len(n.path)] && + // Check for longer wildcard, e.g. :name and :names + (len(n.path) >= len(path) || path[len(n.path)] == '/') { + continue walk + } else { + // Wildcard conflict + var pathSeg string + if n.nType == catchAll { + pathSeg = path + } else { + pathSeg = strings.SplitN(path, "/", 2)[0] + } + prefix := fullPath[:strings.Index(fullPath, pathSeg)] + n.path + panic("'" + pathSeg + + "' in new path '" + fullPath + + "' conflicts with existing wildcard '" + n.path + + "' in existing prefix '" + prefix + + "'") + } + } + + c := path[0] + + // slash after param + if n.nType == param && c == '/' && len(n.children) == 1 { + n = n.children[0] + n.priority++ + continue walk + } + + // Check if a child with the next path byte exists + for i := 0; i < len(n.indices); i++ { + if c == n.indices[i] { + i = n.incrementChildPrio(i) + n = n.children[i] + continue walk + } + } + + // Otherwise insert it + if c != ':' && c != '*' { + // []byte for proper unicode char conversion, see #65 + n.indices += string([]byte{c}) + child := &node{ + maxParams: numParams, + } + n.children = append(n.children, child) + n.incrementChildPrio(len(n.indices) - 1) + n = child + } + n.insertChild(numParams, path, fullPath, handle) + return + + } else if i == len(path) { // Make node a (in-path) leaf + if n.handle != nil { + panic("a handle is already registered for path '" + fullPath + "'") + } + n.handle = handle + } + return + } + } else { // Empty tree + n.insertChild(numParams, path, fullPath, handle) + n.nType = root + } +} + +func (n *node) insertChild(numParams uint8, path, fullPath string, handle Handle) { + var offset int // already handled bytes of the path + + // find prefix until first wildcard (beginning with ':'' or '*'') + for i, max := 0, len(path); numParams > 0; i++ { + c := path[i] + if c != ':' && c != '*' { + continue + } + + // find wildcard end (either '/' or path end) + end := i + 1 + for end < max && path[end] != '/' { + switch path[end] { + // the wildcard name must not contain ':' and '*' + case ':', '*': + panic("only one wildcard per path segment is allowed, has: '" + + path[i:] + "' in path '" + fullPath + "'") + default: + end++ + } + } + + // check if this Node existing children which would be + // unreachable if we insert the wildcard here + if len(n.children) > 0 { + panic("wildcard route '" + path[i:end] + + "' conflicts with existing children in path '" + fullPath + "'") + } + + // check if the wildcard has a name + if end-i < 2 { + panic("wildcards must be named with a non-empty name in path '" + fullPath + "'") + } + + if c == ':' { // param + // split path at the beginning of the wildcard + if i > 0 { + n.path = path[offset:i] + offset = i + } + + child := &node{ + nType: param, + maxParams: numParams, + } + n.children = []*node{child} + n.wildChild = true + n = child + n.priority++ + numParams-- + + // if the path doesn't end with the wildcard, then there + // will be another non-wildcard subpath starting with '/' + if end < max { + n.path = path[offset:end] + offset = end + + child := &node{ + maxParams: numParams, + priority: 1, + } + n.children = []*node{child} + n = child + } + + } else { // catchAll + if end != max || numParams > 1 { + panic("catch-all routes are only allowed at the end of the path in path '" + fullPath + "'") + } + + if len(n.path) > 0 && n.path[len(n.path)-1] == '/' { + panic("catch-all conflicts with existing handle for the path segment root in path '" + fullPath + "'") + } + + // currently fixed width 1 for '/' + i-- + if path[i] != '/' { + panic("no / before catch-all in path '" + fullPath + "'") + } + + n.path = path[offset:i] + + // first node: catchAll node with empty path + child := &node{ + wildChild: true, + nType: catchAll, + maxParams: 1, + } + n.children = []*node{child} + n.indices = string(path[i]) + n = child + n.priority++ + + // second node: node holding the variable + child = &node{ + path: path[i:], + nType: catchAll, + maxParams: 1, + handle: handle, + priority: 1, + } + n.children = []*node{child} + + return + } + } + + // insert remaining path part and handle to the leaf + n.path = path[offset:] + n.handle = handle +} + +// Returns the handle registered with the given path (key). The values of +// wildcards are saved to a map. +// If no handle can be found, a TSR (trailing slash redirect) recommendation is +// made if a handle exists with an extra (without the) trailing slash for the +// given path. +func (n *node) getValue(path string) (handle Handle, p Params, tsr bool) { +walk: // outer loop for walking the tree + for { + if len(path) > len(n.path) { + if path[:len(n.path)] == n.path { + path = path[len(n.path):] + // If this node does not have a wildcard (param or catchAll) + // child, we can just look up the next child node and continue + // to walk down the tree + if !n.wildChild { + c := path[0] + for i := 0; i < len(n.indices); i++ { + if c == n.indices[i] { + n = n.children[i] + continue walk + } + } + // 此处对getValue方法进行部分修改,以适应匹配前缀的需求 + handle = n.handle + pathLen := len(path) + tsr = string(path[pathLen-1]) == "/" && n.handle != nil + // Nothing found. + // We can recommend to redirect to the same URL without a + // trailing slash if a leaf exists for that path. + + //tsr = (path == "/" && n.handle != nil) + return + + } + + // handle wildcard child + n = n.children[0] + switch n.nType { + case param: + // find param end (either '/' or path end) + end := 0 + for end < len(path) && path[end] != '/' { + end++ + } + + // save param value + if p == nil { + // lazy allocation + p = make(Params, 0, n.maxParams) + } + i := len(p) + p = p[:i+1] // expand slice within preallocated capacity + p[i].Key = n.path[1:] + p[i].Value = path[:end] + + // we need to go deeper! + if end < len(path) { + if len(n.children) > 0 { + path = path[end:] + n = n.children[0] + continue walk + } + + // ... but we can't + tsr = (len(path) == end+1) + return + } + + if handle = n.handle; handle != nil { + return + } else if len(n.children) == 1 { + // No handle found. Check if a handle for this path + a + // trailing slash exists for TSR recommendation + n = n.children[0] + tsr = (n.path == "/" && n.handle != nil) + } + + return + + case catchAll: + // save param value + if p == nil { + // lazy allocation + p = make(Params, 0, n.maxParams) + } + i := len(p) + p = p[:i+1] // expand slice within preallocated capacity + p[i].Key = n.path[2:] + p[i].Value = path + + handle = n.handle + return + + default: + panic("invalid node type") + } + } + } else if path == n.path { + // We should have reached the node containing the handle. + // Check if this node has a handle registered. + if handle = n.handle; handle != nil { + return + } + + if path == "/" && n.wildChild && n.nType != root { + tsr = true + return + } + + // No handle found. Check if a handle for this path + a + // trailing slash exists for trailing slash recommendation + for i := 0; i < len(n.indices); i++ { + if n.indices[i] == '/' { + n = n.children[i] + tsr = (len(n.path) == 1 && n.handle != nil) || + (n.nType == catchAll && n.children[0].handle != nil) + return + } + } + + return + } + + // Nothing found. We can recommend to redirect to the same URL with an + // extra trailing slash if a leaf exists for that path + tsr = (path == "/") || + (len(n.path) == len(path)+1 && n.path[len(path)] == '/' && + path == n.path[:len(n.path)-1] && n.handle != nil) + return + } +} + +// Makes a case-insensitive lookup of the given path and tries to find a handler. +// It can optionally also fix trailing slashes. +// It returns the case-corrected path and a bool indicating whether the lookup +// was successful. +func (n *node) findCaseInsensitivePath(path string, fixTrailingSlash bool) (ciPath []byte, found bool) { + return n.findCaseInsensitivePathRec( + path, + strings.ToLower(path), + make([]byte, 0, len(path)+1), // preallocate enough memory for new path + [4]byte{}, // empty rune buffer + fixTrailingSlash, + ) +} + +// shift bytes in array by n bytes left +func shiftNRuneBytes(rb [4]byte, n int) [4]byte { + switch n { + case 0: + return rb + case 1: + return [4]byte{rb[1], rb[2], rb[3], 0} + case 2: + return [4]byte{rb[2], rb[3]} + case 3: + return [4]byte{rb[3]} + default: + return [4]byte{} + } +} + +// recursive case-insensitive lookup function used by n.findCaseInsensitivePath +func (n *node) findCaseInsensitivePathRec(path, loPath string, ciPath []byte, rb [4]byte, fixTrailingSlash bool) ([]byte, bool) { + loNPath := strings.ToLower(n.path) + +walk: // outer loop for walking the tree + for len(loPath) >= len(loNPath) && (len(loNPath) == 0 || loPath[1:len(loNPath)] == loNPath[1:]) { + // add common path to result + ciPath = append(ciPath, n.path...) + + if path = path[len(n.path):]; len(path) > 0 { + loOld := loPath + loPath = loPath[len(loNPath):] + + // If this node does not have a wildcard (param or catchAll) child, + // we can just look up the next child node and continue to walk down + // the tree + if !n.wildChild { + // skip rune bytes already processed + rb = shiftNRuneBytes(rb, len(loNPath)) + + if rb[0] != 0 { + // old rune not finished + for i := 0; i < len(n.indices); i++ { + if n.indices[i] == rb[0] { + // continue with child node + n = n.children[i] + loNPath = strings.ToLower(n.path) + continue walk + } + } + } else { + // process a new rune + var rv rune + + // find rune start + // runes are up to 4 byte long, + // -4 would definitely be another rune + var off int + for max := min(len(loNPath), 3); off < max; off++ { + if i := len(loNPath) - off; utf8.RuneStart(loOld[i]) { + // read rune from cached lowercase path + rv, _ = utf8.DecodeRuneInString(loOld[i:]) + break + } + } + + // calculate lowercase bytes of current rune + utf8.EncodeRune(rb[:], rv) + // skipp already processed bytes + rb = shiftNRuneBytes(rb, off) + + for i := 0; i < len(n.indices); i++ { + // lowercase matches + if n.indices[i] == rb[0] { + // must use a recursive approach since both the + // uppercase byte and the lowercase byte might exist + // as an index + if out, found := n.children[i].findCaseInsensitivePathRec( + path, loPath, ciPath, rb, fixTrailingSlash, + ); found { + return out, true + } + break + } + } + + // same for uppercase rune, if it differs + if up := unicode.ToUpper(rv); up != rv { + utf8.EncodeRune(rb[:], up) + rb = shiftNRuneBytes(rb, off) + + for i := 0; i < len(n.indices); i++ { + // uppercase matches + if n.indices[i] == rb[0] { + // continue with child node + n = n.children[i] + loNPath = strings.ToLower(n.path) + continue walk + } + } + } + } + + // Nothing found. We can recommend to redirect to the same URL + // without a trailing slash if a leaf exists for that path + return ciPath, (fixTrailingSlash && path == "/" && n.handle != nil) + } + + n = n.children[0] + switch n.nType { + case param: + // find param end (either '/' or path end) + k := 0 + for k < len(path) && path[k] != '/' { + k++ + } + + // add param value to case insensitive path + ciPath = append(ciPath, path[:k]...) + + // we need to go deeper! + if k < len(path) { + if len(n.children) > 0 { + // continue with child node + n = n.children[0] + loNPath = strings.ToLower(n.path) + loPath = loPath[k:] + path = path[k:] + continue + } + + // ... but we can't + if fixTrailingSlash && len(path) == k+1 { + return ciPath, true + } + return ciPath, false + } + + if n.handle != nil { + return ciPath, true + } else if fixTrailingSlash && len(n.children) == 1 { + // No handle found. Check if a handle for this path + a + // trailing slash exists + n = n.children[0] + if n.path == "/" && n.handle != nil { + return append(ciPath, '/'), true + } + } + return ciPath, false + + case catchAll: + return append(ciPath, path...), true + + default: + panic("invalid node type") + } + } else { + // We should have reached the node containing the handle. + // Check if this node has a handle registered. + if n.handle != nil { + return ciPath, true + } + + // No handle found. + // Try to fix the path by adding a trailing slash + if fixTrailingSlash { + for i := 0; i < len(n.indices); i++ { + if n.indices[i] == '/' { + n = n.children[i] + if (len(n.path) == 1 && n.handle != nil) || + (n.nType == catchAll && n.children[0].handle != nil) { + return append(ciPath, '/'), true + } + return ciPath, false + } + } + } + return ciPath, false + } + } + + // Nothing found. + // Try to fix the path by adding / removing a trailing slash + if fixTrailingSlash { + if path == "/" { + return ciPath, true + } + if len(loPath)+1 == len(loNPath) && loNPath[len(loPath)] == '/' && + loPath[1:] == loNPath[1:len(loPath)] && n.handle != nil { + return append(ciPath, n.path...), true + } + } + return ciPath, false +} diff --git a/module/manager.go b/module/manager.go new file mode 100644 index 0000000000000000000000000000000000000000..4b6d790c6373b32bdf81d7cddcc07a45c9dea3f3 --- /dev/null +++ b/module/manager.go @@ -0,0 +1,2 @@ +package module + diff --git a/module/prometheus/config/config.go b/module/prometheus/config/config.go index fbe24efb919abceb1f4e9004642256f920bfb8b3..984fa41d0074281009aba3bd17d177009afd8376 100644 --- a/module/prometheus/config/config.go +++ b/module/prometheus/config/config.go @@ -12,7 +12,7 @@ const moduleName = "Prometheus" //Pattern 请求路径 const Pattern = "/prometheus/metrics" -const desc = "API监控模块对接Prometheus" +const desc = "对接Prometheus" const content = `[ { "type": "line", @@ -43,8 +43,8 @@ func (c *PrometheusModule) GetNameSpace() string { return ModuleNameSpace } -//Encoder encode -func (c *PrometheusModule) Encoder(v interface{}) (string, error) { +//Encode encode +func (c *PrometheusModule) Encode(v interface{}) (string, error) { return "", nil } diff --git a/module/prometheus/prometheus.go b/module/prometheus/prometheus.go index 3582f4ff0ca21401d623df0d47d4c409ea10bd6f..b2dc19aa25a4bc56d6965a71cc7baa0d8049d2ba 100644 --- a/module/prometheus/prometheus.go +++ b/module/prometheus/prometheus.go @@ -92,7 +92,7 @@ func (p *Prometheus) NewCounter(opts *diting.CounterOpts) (diting.Counter, error return newCounter(c), nil } -//NewHistogram new Histogram +//NewHistogram new HistogramObserve func (p *Prometheus) NewHistogram(opts *diting.HistogramOpts) (diting.Histogram, error) { h := prometheus.NewHistogramVec(ReadHistogramOpts(opts), opts.LabelNames) err := p.registry.Register(h) diff --git a/module/status.go b/module/status.go index cbb7fa88787843be761931b759adfe0a1c57910e..5cd591298cd7f28b8b32a389fa341be7f47fb793 100644 --- a/module/status.go +++ b/module/status.go @@ -47,7 +47,6 @@ func Open(name string) { m.locker.Lock() m.modules[name] = true m.locker.Unlock() - } //Refresh refresh @@ -59,5 +58,5 @@ func Refresh(States []State) { m.modules[s.name] = s.isOpen } m.locker.Unlock() - } + diff --git a/node/admin/handler.go b/node/admin/handler.go index 1eee722414d2521e6f182405a694ef7c8dc21be5..47b61b46bd263a4ca1416c25565c1ef10a985eb0 100644 --- a/node/admin/handler.go +++ b/node/admin/handler.go @@ -71,7 +71,7 @@ func Handler() http.Handler { return handler } -//Add add +//Add( add func Add(name string, pattern string, h http.Handler) { handler.Add(name, pattern, h) } diff --git a/node/console/console.go b/node/console/console.go index 616cc6335d1ecb73359327ba48d3775eabd5207b..2822054c1f90383101c3f5cf0198f30240147ead 100644 --- a/node/console/console.go +++ b/node/console/console.go @@ -1,32 +1,17 @@ package console import ( - "context" - "sync" + "github.com/eolinker/goku-api-gateway/config" ) -//Console console -type Console struct { - adminHost string - instance string - ctx context.Context - cancel context.CancelFunc - lastVersion int - once sync.Once +//ConfigConsole configConsole +type ConfigConsole interface { + Close() + AddListen(callback ConfigCallbackFunc) + GetConfig() (*config.GokuConfig, error) + RegisterToConsole() (*config.GokuConfig, error) + Listen() } -//Close close -func (c *Console) Close() { - c.once.Do(c.cancel) -} - -//NewConsole newConsole -func NewConsole(instance string, adminHost string) *Console { - ctx, cancel := context.WithCancel(context.Background()) - return &Console{ - instance: instance, - adminHost: adminHost, - ctx: ctx, - cancel: cancel, - } -} +//ConfigCallbackFunc configCallbackFunc +type ConfigCallbackFunc func(conf *config.GokuConfig) diff --git a/node/gateway/api.go b/node/gateway/api.go index 91740dc1b9dd1a7820fc3d944031f1c65760d817..6880001b34e63863ddbed5500da390e039111432 100644 --- a/node/gateway/api.go +++ b/node/gateway/api.go @@ -50,9 +50,10 @@ func (h *API) Router(ctx *common.Context) { func (h *API) accessFlow(ctx *common.Context) bool { for _, handler := range h.pluginAccess { - - flag, _ := handler.Execute(ctx) - + flag, err := handler.Execute(ctx) + if err != nil { + fmt.Println(err) + } if flag == false && handler.IsStop() { return false @@ -70,7 +71,6 @@ func (h *API) accessGlobalFlow(ctx *common.Context) { func (h *API) proxyFlow(ctx *common.Context) bool { for _, handler := range h.pluginProxies { - flag, _ := handler.Execute(ctx) if flag == false && handler.IsStop() { diff --git a/node/gateway/application/backend/backend.go b/node/gateway/application/backend/backend.go index 73b3b18d3840bc05fa281b3d2b4b9ff7a6a491ff..2480943654edad98ac6e14cd8f9007d25eaa8ed5 100644 --- a/node/gateway/application/backend/backend.go +++ b/node/gateway/application/backend/backend.go @@ -1,3 +1 @@ package backend - - diff --git a/node/gateway/application/backend/filter.go b/node/gateway/application/backend/filter.go index 2eb1785932749c73e062c909cd3443b1679233a5..b6ab383cc00cda3300babf978248f202d611ff35 100644 --- a/node/gateway/application/backend/filter.go +++ b/node/gateway/application/backend/filter.go @@ -6,23 +6,23 @@ import ( ) func genFilter(blackList, whiteList []string, acs []*config.ActionConfig) action.Filter { - size:=len(blackList)+1 + len(acs) + size := len(blackList) + 1 + len(acs) - filters:= make(action.Filters,0,size) + filters := make(action.Filters, 0, size) - for _,b:=range blackList{ - filters = append(filters,action.Blacklist(b)) + for _, b := range blackList { + filters = append(filters, action.Blacklist(b)) } - if len(whiteList)>0{ - filters = append(filters,action.GenWhite(whiteList)) + if len(whiteList) > 0 { + filters = append(filters, action.GenWhite(whiteList)) } - for _,ac:=range acs{ + for _, ac := range acs { - f:=action.GenByconfig(ac) - if f!= nil{ - filters = append(filters,f) + f := action.GenByconfig(ac) + if f != nil { + filters = append(filters, f) } } return filters -} \ No newline at end of file +} diff --git a/node/gateway/application/backend/layer.go b/node/gateway/application/backend/layer.go index fac80c20e5cd49f99fe6dd9ca70f99fb1303219c..3c5faeb9bc60d2cdb3a5dc9903fe7aa134a2c534 100644 --- a/node/gateway/application/backend/layer.go +++ b/node/gateway/application/backend/layer.go @@ -1,6 +1,7 @@ package backend import ( + "compress/gzip" "context" "io/ioutil" "strings" @@ -41,7 +42,7 @@ func (b *Layer) Send(deadline context.Context, ctx *common.Context, variables *i body := b.Body.Execution(variables) method := b.Method - r, finalTargetServer, retryTargetServers, err := b.Balance.Send(b.Protocol, method, path, ctx.ProxyRequest.Querys(), ctx.ProxyRequest.Headers(), []byte(body), b.TimeOut, b.Retry) + r, finalTargetServer, retryTargetServers, err := b.Balance.Send(ctx, b.Protocol, method, path, ctx.ProxyRequest.Querys(), ctx.ProxyRequest.Headers(), []byte(body), b.TimeOut, b.Retry) if err != nil { return nil, err @@ -57,7 +58,13 @@ func (b *Layer) Send(deadline context.Context, ctx *common.Context, variables *i } defer r.Body.Close() - backendResponse.BodyOrg, err = ioutil.ReadAll(r.Body) + bd := r.Body + if r.Header.Get("Content-Encoding") == "gzip" { + bd, _ = gzip.NewReader(r.Body) + r.Header.Del("Content-Encoding") + } + + backendResponse.BodyOrg, err = ioutil.ReadAll(bd) if err != nil { return backendResponse, nil } @@ -76,6 +83,7 @@ func (b *Layer) Send(deadline context.Context, ctx *common.Context, variables *i if len(b.Group) > 0 { rp.Group(b.Group) } + backendResponse.Body = rp.Data return backendResponse, nil } @@ -95,7 +103,7 @@ func NewLayer(step *config.APIStepConfig) *Layer { Target: step.Target, Group: nil, TimeOut: time.Duration(step.TimeOut) * time.Millisecond, - Body: interpreter.Gen(step.Body), + Body: interpreter.Gen(step.Body, step.Encode), Retry: step.Retry, } if step.Group != "" { diff --git a/node/gateway/application/backend/proxy.go b/node/gateway/application/backend/proxy.go index d58bbd8ad4973f08f0a2ac7a91bc1683d702d901..a18185ceee8e7d78340f01b62d8ccdfc6d5804ef 100644 --- a/node/gateway/application/backend/proxy.go +++ b/node/gateway/application/backend/proxy.go @@ -1,6 +1,7 @@ package backend import ( + "compress/gzip" "fmt" "io/ioutil" "strings" @@ -67,18 +68,20 @@ func (b *Proxy) Send(ctx *common.Context, variables *interpreter.Variables) (*Ba // 不是restful时,将匹配路由之后对url拼接到path之后 if len(variables.Restful) == 0 { - orgRequestURL := ctx.RequestOrg.URL().RawPath + orgRequestURL := ctx.RequestOrg.URL().Path lessPath := strings.TrimPrefix(orgRequestURL, b.RequestPath) lessPath = strings.TrimPrefix(lessPath, "/") - path = strings.TrimSuffix(path, "/") - path = fmt.Sprint(path, "/", lessPath) + if lessPath != "" { + path = strings.TrimSuffix(path, "/") + path = fmt.Sprint(path, "/", lessPath) + } } method := b.Method if method == "FOLLOW" { method = ctx.ProxyRequest.Method } - r, finalTargetServer, retryTargetServers, err := b.Balance.Send(b.Protocol, method, path, ctx.ProxyRequest.Querys(), ctx.ProxyRequest.Headers(), variables.Org, b.TimeOut, b.Retry) + r, finalTargetServer, retryTargetServers, err := b.Balance.Send(ctx, b.Protocol, method, path, ctx.ProxyRequest.Querys(), ctx.ProxyRequest.Headers(), variables.Org, b.TimeOut, b.Retry) backendResponse := &BackendResponse{ Method: method, @@ -89,15 +92,21 @@ func (b *Proxy) Send(ctx *common.Context, variables *interpreter.Variables) (*Ba TargetURL: path, FinalTargetServer: finalTargetServer, RetryTargetServers: retryTargetServers, - Header: r.Header, + //Cookies:r.Cookies(), } if err != nil { backendResponse.StatusCode, backendResponse.Status = 503, "503" return backendResponse, err } + backendResponse.Header = r.Header defer r.Body.Close() - backendResponse.BodyOrg, err = ioutil.ReadAll(r.Body) + bd := r.Body + if r.Header.Get("Content-Encoding") == "gzip" { + bd, _ = gzip.NewReader(r.Body) + r.Header.Del("Content-Encoding") + } + backendResponse.BodyOrg, err = ioutil.ReadAll(bd) if err != nil { return backendResponse, nil } diff --git a/node/gateway/application/interpreter/analysis.go b/node/gateway/application/interpreter/analysis.go index cf8b7fb0b1bda7f95e9d074f80433dfc1d11ddfe..8d2ac828d0e390f4602fc11808547980a56155a1 100644 --- a/node/gateway/application/interpreter/analysis.go +++ b/node/gateway/application/interpreter/analysis.go @@ -17,7 +17,12 @@ var ( ) //Gen gen -func Gen(tpl string) Interpreter { +func Gen(tpl string, encode string) Interpreter { + if encode == "origin" { + exe := make(_Executor, 1, 1) + exe[0] = new(_OrgReader) + return exe + } tpl = strings.TrimSpace(tpl) i, err := Parse(tpl) if err != nil { diff --git a/node/gateway/application/layer.go b/node/gateway/application/layer.go index 7c6abf15c3eeca971290e649f95f9e52961bb756..46e37ce3dc8cc59c5496702982fd90275e6734c2 100644 --- a/node/gateway/application/layer.go +++ b/node/gateway/application/layer.go @@ -2,6 +2,7 @@ package application import ( "context" + "fmt" "time" "github.com/eolinker/goku-api-gateway/config" @@ -54,8 +55,8 @@ func (app *LayerApplication) Execute(ctx *common.Context) { ctx.SetBody([]byte("[ERROR]timeout!")) // 超时 return - case <-errC: - + case e := <-errC: + fmt.Println(e) cancelFunc() ctx.SetStatus(504, "504") ctx.SetBody([]byte("[ERROR]Fail to get response after proxy!")) @@ -74,7 +75,13 @@ func (app *LayerApplication) Execute(ctx *common.Context) { log.Warn("encode response error:", e) return } - + //if headers.Get("Content-Encoding") == "gzip" { + // var b bytes.Buffer + // wb := gzip.NewWriter(&b) + // wb.Write(body) + // wb.Flush() + // body, _ = ioutil.ReadAll(&b) + //} ctx.SetProxyResponseHandler(common.NewResponseReader(headers, 200, "200", body)) } diff --git a/node/gateway/application/proxy.go b/node/gateway/application/proxy.go index f19605c0cd22176a0662134643193166ec116cc6..271d304577daeca73d4da5059e43dbddb8074d6b 100644 --- a/node/gateway/application/proxy.go +++ b/node/gateway/application/proxy.go @@ -4,6 +4,8 @@ import ( "fmt" "strings" + "github.com/eolinker/goku-api-gateway/goku-service/application" + "github.com/eolinker/goku-api-gateway/config" log "github.com/eolinker/goku-api-gateway/goku-log" "github.com/eolinker/goku-api-gateway/goku-node/common" @@ -64,11 +66,12 @@ func (app *DefaultApplication) Execute(ctx *common.Context) { ctx.LogFields[access_field.FinallyServer] = ctx.FinalTargetServer() ctx.LogFields[access_field.Retry] = ctx.RetryTargetServers() - ctx.LogFields[access_field.Proxy] = fmt.Sprintf("\"%s %s %s\"", r.Method, r.TargetURL, r.Protocol) + ctx.LogFields[access_field.Proxy] = fmt.Sprintf("\"%s %s %s\"", r.Method, application.URLPath(r.TargetURL, ctx.ProxyRequest.Querys()), r.Protocol) } if err != nil { - + ctx.SetStatus(504, "504") + ctx.SetBody([]byte("[ERROR]Fail to get response after proxy!")) log.Warn(err) return } diff --git a/node/gateway/application/static-response.go b/node/gateway/application/static-response.go index a5b7d04e740ab0787751cbcfec2abed47fea3732..4a9fc124582432d30c0ace232d96452ad9be2e9f 100644 --- a/node/gateway/application/static-response.go +++ b/node/gateway/application/static-response.go @@ -6,7 +6,7 @@ import ( ) type staticeResponse struct { - body []byte + body []byte strategy config.StaticResponseStrategy } @@ -16,5 +16,5 @@ func newStaticeResponse(body string, strategy config.StaticResponseStrategy) *st func (sp *staticeResponse) Do(ctx *common.Context) { ctx.SetBody(sp.body) - ctx.SetStatus(200,"200") -} \ No newline at end of file + ctx.SetStatus(200, "200") +} diff --git a/node/gateway/befor.go b/node/gateway/befor.go index 69d255add127e2754ca91f848eedb22c3d26fe80..f21653fb012d66807211178bc574aaa3929f9a28 100644 --- a/node/gateway/befor.go +++ b/node/gateway/befor.go @@ -61,6 +61,7 @@ func (r *Before) BeforeMatch(ctx *common.Context) bool { func (r *Before) rout(w http.ResponseWriter, req *http.Request, ctx *common.Context) { strategyID := utils.GetStrateyID(ctx) + if strategyID == "" { // 没有策略id if r.anonymousStrategy == "" { diff --git a/node/gateway/const.go b/node/gateway/const.go index 6c6a23466e269fd1b35235f09a76a4f51594c047..d9283aa0444b9b1817184e022af827c17d62e818 100644 --- a/node/gateway/const.go +++ b/node/gateway/const.go @@ -1,10 +1,10 @@ package gateway -var( +var ( authNames = map[string]string{ "Oauth2": "goku-oauth2_auth", "Apikey": "goku-apikey_auth", "Basic": "goku-basic_auth", "Jwt": "goku-jwt_auth", } -) \ No newline at end of file +) diff --git a/node/gateway/http.go b/node/gateway/http.go index 119c50f3898902331174feb1e1ade3476d9eb314..b9043e96cdd4a851c9b49921b9e20ab9ccab7a66 100644 --- a/node/gateway/http.go +++ b/node/gateway/http.go @@ -17,7 +17,7 @@ import ( fields "github.com/eolinker/goku-api-gateway/server/access-field" ) -var systemRequestPath = []string{"/oauth2/token", "/oauth2/authorize", "/oauth2/verify"} +var systemRequestPath = map[string]bool{"/oauth2/token": true, "/oauth2/authorize": true, "/oauth2/verify": true} //HTTPHandler httpHandler type HTTPHandler struct { @@ -61,12 +61,16 @@ func (h *HTTPHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { ctx.LogFields[fields.HTTPUserAgent] = fmt.Sprint("\"", req.UserAgent(), "\"") ctx.LogFields[fields.HTTPReferer] = req.Referer() ctx.LogFields[fields.RequestTime] = delay - ctx.LogFields[fields.Request] = fmt.Sprint("\"", req.Method, " ", req.URL.Path, " ", req.Proto, "\"") + ctx.LogFields[fields.Request] = fmt.Sprint("\"", req.Method, " ", req.URL.String(), " ", req.Proto, "\"") ctx.LogFields[fields.BodyBytesSent] = n ctx.LogFields[fields.Host] = req.Host access_log.Log(ctx.LogFields) log.WithFields(ctx.LogFields).Info() + // /oauth2的path不参与统计 + if systemRequestPath[req.URL.Path] { + return + } // 监控计数 labels := make(diting.Labels) diff --git a/node/gateway/plugin-executor/executor.go b/node/gateway/plugin-executor/executor.go index bb75ca1399dca80390741fb0b6e4c2a20bf49e2d..7094c9f5816fbbc5dc0d8fcc0b2bba67afde57f4 100644 --- a/node/gateway/plugin-executor/executor.go +++ b/node/gateway/plugin-executor/executor.go @@ -1,82 +1,93 @@ package plugin_executor import ( - goku_plugin "github.com/eolinker/goku-plugin" + "time" + "github.com/eolinker/goku-api-gateway/config" log "github.com/eolinker/goku-api-gateway/goku-log" "github.com/eolinker/goku-api-gateway/goku-node/common" - "time" + goku_plugin "github.com/eolinker/goku-plugin" ) +//Executor executor type Executor interface { - Execute(ctx *common.Context)(isContinue bool, e error) - IsStop()bool + Execute(ctx *common.Context) (isContinue bool, e error) + IsStop() bool + IsAuth() bool } type executorInfo struct { - Name string + Name string isStop bool + isAuth bool } +func (ex *executorInfo) IsStop() bool { + return ex.isStop +} - -func (ex*executorInfo) IsStop() bool { - return ex.isStop +func (ex *executorInfo) IsAuth() bool { + return ex.isAuth } func genExecutor(cfg *config.PluginConfig) executorInfo { return executorInfo{ - Name:cfg.Name, - isStop:cfg.IsStop, + Name: cfg.Name, + isStop: cfg.IsStop, + isAuth: cfg.IsAuth, } } + type beforeExecutor struct { executorInfo plugin goku_plugin.PluginBeforeMatch - } -func (ex*beforeExecutor) Execute(ctx *common.Context) (isContinue bool, e error) { - requestId:=ctx.RequestId() +//Execute execute +func (ex *beforeExecutor) Execute(ctx *common.Context) (isContinue bool, e error) { + requestID := ctx.RequestId() ctx.SetPlugin(ex.Name) - log.Debug(requestId, " before plugin :", ex.Name, " start") + log.Debug(requestID, " before plugin :", ex.Name, " start") now := time.Now() isContinue, err := ex.plugin.BeforeMatch(ctx) - log.Debug(requestId, " before plugin :", ex.Name, " Duration:", time.Since(now)) - log.Debug(requestId, " before plugin :", ex.Name, " end") + log.Debug(requestID, " before plugin :", ex.Name, " Duration:", time.Since(now)) + log.Debug(requestID, " before plugin :", ex.Name, " end") if err != nil { - log.Warn(requestId, " before plugin:", ex.Name, " error:", err) + log.Warn(requestID, " before plugin:", ex.Name, " error:", err) } - return isContinue,err + return isContinue, err } -func NewBeforeExecutor(cfg *config.PluginConfig,p goku_plugin.PluginBeforeMatch ) *beforeExecutor { +//NewBeforeExecutor 创建before阶段执行器 +func NewBeforeExecutor(cfg *config.PluginConfig, p goku_plugin.PluginBeforeMatch) *beforeExecutor { return &beforeExecutor{ executorInfo: genExecutor(cfg), plugin: p, } } + type accessExecutor struct { executorInfo plugin goku_plugin.PluginAccess } func (ex *accessExecutor) Execute(ctx *common.Context) (isContinue bool, e error) { - requestId:=ctx.RequestId() + requestID := ctx.RequestId() ctx.SetPlugin(ex.Name) - log.Debug(requestId, " access plugin :", ex.Name, " start") + log.Debug(requestID, " access plugin :", ex.Name, " start") now := time.Now() isContinue, err := ex.plugin.Access(ctx) - log.Debug(requestId, " access plugin :", ex.Name, " Duration:", time.Since(now)) - log.Debug(requestId, " access plugin :", ex.Name, " end") + log.Debug(requestID, " access plugin :", ex.Name, " Duration:", time.Since(now)) + log.Debug(requestID, " access plugin :", ex.Name, " end") if err != nil { - log.Warn(requestId, " access plugin:", ex.Name, " error:", err) + log.Warn(requestID, " access plugin:", ex.Name, " error:", err) } - return isContinue,err + return isContinue, err } -func NewAccessExecutor(cfg *config.PluginConfig,p goku_plugin.PluginAccess ) *accessExecutor { +//NewAccessExecutor 创建access阶段执行器 +func NewAccessExecutor(cfg *config.PluginConfig, p goku_plugin.PluginAccess) *accessExecutor { return &accessExecutor{ executorInfo: genExecutor(cfg), plugin: p, @@ -88,24 +99,26 @@ type proxyExecutor struct { plugin goku_plugin.PluginProxy } -func (ex*proxyExecutor) Execute(ctx *common.Context) (isContinue bool, e error) { - requestId:=ctx.RequestId() +//Execute execute +func (ex *proxyExecutor) Execute(ctx *common.Context) (isContinue bool, e error) { + requestID := ctx.RequestId() ctx.SetPlugin(ex.Name) - log.Debug(requestId, " proxy plugin :", ex.Name, " start") + log.Debug(requestID, " proxy plugin :", ex.Name, " start") now := time.Now() isContinue, err := ex.plugin.Proxy(ctx) - log.Debug(requestId, " proxy plugin :", ex.Name, " Duration:", time.Since(now)) - log.Debug(requestId, " proxy plugin :", ex.Name, " end") + log.Debug(requestID, " proxy plugin :", ex.Name, " Duration:", time.Since(now)) + log.Debug(requestID, " proxy plugin :", ex.Name, " end") if err != nil { - log.Warn(requestId, " proxy plugin:", ex.Name, " error:", err) + log.Warn(requestID, " proxy plugin:", ex.Name, " error:", err) } - return isContinue,err + return isContinue, err } -func NewProxyExecutor(cfg *config.PluginConfig,p goku_plugin.PluginProxy ) *proxyExecutor { +//NewProxyExecutor 创建proxy阶段执行器 +func NewProxyExecutor(cfg *config.PluginConfig, p goku_plugin.PluginProxy) *proxyExecutor { return &proxyExecutor{ executorInfo: genExecutor(cfg), plugin: p, } -} \ No newline at end of file +} diff --git a/node/gateway/plugin.go b/node/gateway/plugin.go index 4427e80279c7772dab517c1e102e51023202dec4..946933db86478217413c173a58da3616bc7c2086 100644 --- a/node/gateway/plugin.go +++ b/node/gateway/plugin.go @@ -2,6 +2,7 @@ package gateway import ( "reflect" + "strings" "github.com/eolinker/goku-api-gateway/config" plugin_executor "github.com/eolinker/goku-api-gateway/node/gateway/plugin-executor" @@ -32,7 +33,6 @@ func genPlugins(cfgs []*config.PluginConfig, cluster string, strategyID string, psBefor := make([]plugin_executor.Executor, 0, len(cfgs)) psAccess := make([]plugin_executor.Executor, 0, len(cfgs)) psProxy := make([]plugin_executor.Executor, 0, len(cfgs)) - for _, cfg := range cfgs { factory, e := plugin.LoadPlugin(cfg.Name) @@ -48,6 +48,9 @@ func genPlugins(cfgs []*config.PluginConfig, cluster string, strategyID string, psBefor = append(psBefor, plugin_executor.NewBeforeExecutor(cfg, obj.BeforeMatch)) } if obj.Access != nil && !reflect.ValueOf(obj.Access).IsNil() { + if strings.Contains(cfg.Name, "_auth") { + cfg.IsAuth = true + } psAccess = append(psAccess, plugin_executor.NewAccessExecutor(cfg, obj.Access)) } if obj.Proxy != nil && !reflect.ValueOf(obj.Proxy).IsNil() { diff --git a/node/gateway/response/decode.go b/node/gateway/response/decode.go index b96844fd4e452f58e8662de24c62f22316ccb37d..70d36168180a199b9c8648ce2f1efc60bc76a60c 100644 --- a/node/gateway/response/decode.go +++ b/node/gateway/response/decode.go @@ -3,26 +3,45 @@ package response import ( "encoding/json" "strings" + + "github.com/eolinker/goku-api-gateway/utils" ) -const( - JSON ="json" + +const ( + //JSON json + JSON = "json" + //XML xml XML = "xml" + //String string String = "string" + //JSONNoQuote 非标准json(key不带双引号) + JSONNoQuote = "json-noquote" ) + var ( - jsonDecoder = func(data []byte, v interface{}) error { - err:=json.Unmarshal(data,v) + jsonDecoder = func(data []byte, v interface{}) error { + err := json.Unmarshal(data, v) + return err + } + jsonNoQuoteDecoder = func(data []byte, v interface{}) error { + d, err := utils.JSObjectToJSON(string(data)) + if err != nil { + return err + } + err = json.Unmarshal(d, v) return err } - ) + +//GetDecoder getDecoder func GetDecoder(decoder string) DecodeHandle { switch strings.ToLower(decoder) { case JSON: return jsonDecoder + case JSONNoQuote: + return jsonNoQuoteDecoder } return nil } - diff --git a/node/gateway/response/decoder.go b/node/gateway/response/decoder.go index f4e1ef4de881c00c882fb5a8d63baa7806d8ec8d..fafab2072b5035f911ea29b5616dc3b2a9550dd8 100644 --- a/node/gateway/response/decoder.go +++ b/node/gateway/response/decoder.go @@ -3,29 +3,36 @@ package response import "errors" var ( + //ErrorInvalidDecoder 非法Decoder ErrorInvalidDecoder = errors.New("invalid decoder") ) + +//DecodeHandle 解码器 type DecodeHandle func(data []byte, v interface{}) error -type EncodeHandle func (v interface{},org []byte)([]byte,error) +//EncodeHandle 解码处理器 +type EncodeHandle func(v interface{}, org []byte) ([]byte, error) + +//Encoder 解码器 type Encoder interface { - Encode(v interface{},org []byte)([]byte,error) - ContentType()string + Encode(v interface{}, org []byte) ([]byte, error) + ContentType() string } -func Decode(data []byte,handle DecodeHandle) (*Response,error) { +//Decode 解码 +func Decode(data []byte, handle DecodeHandle) (*Response, error) { - if handle == nil{ - return nil,ErrorInvalidDecoder + if handle == nil { + return nil, ErrorInvalidDecoder } var v interface{} - err:=handle(data,&v) - if err!=nil{ - return nil,err + err := handle(data, &v) + if err != nil { + return nil, err } return &Response{ Data: v, - },nil + }, nil } diff --git a/node/gateway/response/encode.go b/node/gateway/response/encode.go index b452fadf2fda8e37dbd76a2b65becea62a2b8101..65020ddb2a00e2bb5d427ed3bca72535d6abb2fc 100644 --- a/node/gateway/response/encode.go +++ b/node/gateway/response/encode.go @@ -8,47 +8,50 @@ import ( ) var ( - - jsonEncoder =& EncoderH{ - contentType:"application/json", - handleFunc:func(v interface{},org []byte)([]byte,error){ + jsonEncoder = &EncoderH{ + contentType: "application/json", + handleFunc: func(v interface{}, org []byte) ([]byte, error) { return json.Marshal(v) }, } - xmlEncoder =&EncoderH{ - contentType:"text/xml; charset=utf-8", - handleFunc:func(v interface{},org []byte) ([]byte,error){ + xmlEncoder = &EncoderH{ + contentType: "text/xml; charset=utf-8", + handleFunc: func(v interface{}, org []byte) ([]byte, error) { return xml.Marshal(v) }, } - stringEncoder =&EncoderH{ - contentType:"text/plain", - handleFunc: func(v interface{},org []byte)([]byte,error) { + stringEncoder = &EncoderH{ + contentType: "text/plain", + handleFunc: func(v interface{}, org []byte) ([]byte, error) { - return org,nil + return org, nil }, } notEncoder = &EncoderH{ contentType: "", handleFunc: func(v interface{}, org []byte) (bytes []byte, e error) { - return org,nil + return org, nil }, } ) +//EncoderH encodeH type EncoderH struct { contentType string - handleFunc EncodeHandle + handleFunc EncodeHandle } -func (e *EncoderH) Encode(v interface{},org []byte) ([]byte, error) { - return e.handleFunc(v,org) +//Encode encode +func (e *EncoderH) Encode(v interface{}, org []byte) ([]byte, error) { + return e.handleFunc(v, org) } +//ContentType contentType func (e *EncoderH) ContentType() string { return e.contentType } +//GetEncoder 获取编码器 func GetEncoder(encoder string) Encoder { switch strings.ToLower(encoder) { @@ -60,4 +63,4 @@ func GetEncoder(encoder string) Encoder { return stringEncoder } return notEncoder -} \ No newline at end of file +} diff --git a/node/gateway/response/node.go b/node/gateway/response/node.go index 1b412345ed9b4d1ce8917e9cffa2cc1efee06b1a..defbcb3312ad4457ae27b6b9947a75a71871b382 100644 --- a/node/gateway/response/node.go +++ b/node/gateway/response/node.go @@ -6,44 +6,42 @@ import ( ) type _Node struct { - data interface{} + data interface{} parent *_Node - index int - key string + index int + key string } -func (node *_Node)Set(v interface{}) { - if node.parent == nil{ +func (node *_Node) Set(v interface{}) { + if node.parent == nil { return } } - - -func (node*_Node)child(key string,callback func(*_Node))bool { +func (node *_Node) child(key string, callback func(*_Node)) bool { return false } -func (node *_Node)get(key string)*_Node{ +func (node *_Node) get(key string) *_Node { - if key == ""{ + if key == "" { return nil } - if key == "*"{ + if key == "*" { return node } switch node.data.(type) { case []interface{}: { - sl:=node.data.([]interface{}) - if i,e:= strconv.Atoi(key);e==nil{ - if i< len(sl){ - n:=&_Node{ - data:sl[i], - parent:node, - index:i, + sl := node.data.([]interface{}) + if i, e := strconv.Atoi(key); e == nil { + if i < len(sl) { + n := &_Node{ + data: sl[i], + parent: node, + index: i, } return n } @@ -52,9 +50,9 @@ func (node *_Node)get(key string)*_Node{ } case map[string]interface{}: { - sm :=node.data.(map[string]interface{}) - if v,has:=sm[key];has{ - n:=&_Node{ + sm := node.data.(map[string]interface{}) + if v, has := sm[key]; has { + n := &_Node{ data: v, parent: node, key: key, @@ -68,89 +66,89 @@ func (node *_Node)get(key string)*_Node{ return nil } -func (node*_Node)Make(path []string) { +func (node *_Node) Make(path []string) { - if node.data == nil{ + if node.data == nil { node.data = make(map[string]interface{}) } - makePath(node.data,path) + makePath(node.data, path) } -func makePath(data interface{},path[]string) { - if len(path) == 0{ +func makePath(data interface{}, path []string) { + if len(path) == 0 { return } - k:=path[0] - next:=path[1:] - switch data.(type){ + k := path[0] + next := path[1:] + switch data.(type) { case []interface{}: - dl:=data.([]interface{}) + dl := data.([]interface{}) if k == "*" { - for _,d:=range dl{ - makePath(d,next) + for _, d := range dl { + makePath(d, next) } - }else if i,err:=strconv.Atoi(k);err!=nil{ - if i0 ; key = spiltKey(key){ + for key := pattern; len(key) > 0; key = spiltKey(key) { - next:=next(pattern,key) - if key == "*" { - data:= node.data + next := next(pattern, key) + if key == "*" { + data := node.data switch data.(type) { case []interface{}: { sl := data.([]interface{}) - - for i, s := range sl { - n := &_Node{ - data: s, - parent: node, - index: i, - } - match, isBreak := n.Pattern(next, callback) - if isBreak { - return true,true - } - isMatch = isMatch || match + for i, s := range sl { + n := &_Node{ + data: s, + parent: node, + index: i, } + match, isBreak := n.Pattern(next, callback) + if isBreak { + return true, true + } + isMatch = isMatch || match + } } case map[string]interface{}: { - sm :=data.(map[string]interface{}) + sm := data.(map[string]interface{}) - if len(sm) > 0{ - for k,s:=range sm { + if len(sm) > 0 { + for k, s := range sm { n := &_Node{ data: s, parent: node, @@ -162,7 +160,7 @@ func (node *_Node) Pattern(pattern string,callback func(*_Node)bool)( match bool } isMatch = isMatch || match } - }else{ + } else { n := &_Node{ data: nil, parent: node, @@ -178,36 +176,36 @@ func (node *_Node) Pattern(pattern string,callback func(*_Node)bool)( match bool } } - }else{ + } else { - child:= node.get(key) + child := node.get(key) if child != nil { - match, isBreak :=child.Pattern(next,callback) + match, isBreak := child.Pattern(next, callback) if isBreak { return true, true } isMatch = match } } - if isMatch{ - return true,false + if isMatch { + return true, false } } - return false,false + return false, false } -func next(pattern ,key string) string{ +func next(pattern, key string) string { - l:=len(key) + l := len(key) - if len(pattern)>l{ + if len(pattern) > l { return pattern[l+1:] } return "" } func spiltKey(key string) string { - if index:=strings.LastIndex(key,".");index!= -1{ + if index := strings.LastIndex(key, "."); index != -1 { return key[:index] } return "" -} \ No newline at end of file +} diff --git a/node/gateway/response/response.go b/node/gateway/response/response.go index 3bb3929557b353594684ef78758ae4b67a4dbbc7..ffae19b9d07f68e69183a5df1c15f0357ac39a34 100644 --- a/node/gateway/response/response.go +++ b/node/gateway/response/response.go @@ -8,63 +8,65 @@ type Response struct { Data interface{} } +//Delete delete func (r *Response) Delete(pattern string) *Response { - if pattern == ""{ + if pattern == "" { return r } - root:=_Node{ - data:r.Data, + root := _Node{ + data: r.Data, } - root.Pattern(pattern, func(node *_Node)bool { - if node.parent ==nil { + root.Pattern(pattern, func(node *_Node) bool { + if node.parent == nil { return false } - parent:= node.parent + parent := node.parent switch parent.data.(type) { case []interface{}: - index:= node.index - sl:= parent.data.([]interface{}) + index := node.index + sl := parent.data.([]interface{}) - nl:=sl[:index] - sl=append(nl,sl[index+1]) + nl := sl[:index] + sl = append(nl, sl[index+1]) parent.data = sl case map[string]interface{}: - mp:=parent.data.(map[string]interface{}) - delete(mp,node.key) + mp := parent.data.(map[string]interface{}) + delete(mp, node.key) } return false }) return r } + //SetValue 设置目标值,如果目标不存在,会对路径进行创建 -func (r *Response) SetValue(pattern string,value interface{}) { - if pattern == ""{ +func (r *Response) SetValue(pattern string, value interface{}) { + if pattern == "" { r.Data = value return } - root:=_Node{ - data:r.Data, + root := _Node{ + data: r.Data, } - root.Make(strings.Split(pattern,".")) + root.Make(strings.Split(pattern, ".")) - root.Pattern(pattern, func(node *_Node)bool { + root.Pattern(pattern, func(node *_Node) bool { - if node.parent ==nil { + if node.parent == nil { return false } - parent:= node.parent + parent := node.parent switch parent.data.(type) { case []interface{}: - sl:= parent.data.([]interface{}) - index:= node.index + sl := parent.data.([]interface{}) + index := node.index sl[index] = value parent.data = sl case map[string]interface{}: - mp:=parent.data.(map[string]interface{}) - mp[node.key]=value + mp := parent.data.(map[string]interface{}) + mp[node.key] = value } return false }) @@ -73,11 +75,11 @@ func (r *Response) SetValue(pattern string,value interface{}) { //ReTarget 选择目标重新设置为root func (r *Response) ReTarget(pattern string) { - if pattern == ""{ + if pattern == "" { return } - root:=_Node{ - data:r.Data, + root := _Node{ + data: r.Data, } match, _ := root.Pattern(pattern, func(node *_Node) bool { @@ -85,25 +87,26 @@ func (r *Response) ReTarget(pattern string) { return true }) - if !match{ + if !match { r.Data = make(map[string]interface{}) } return } -//Group + +//Group group func (r *Response) Group(path []string) { - l:=len(path) - if l==0{ + l := len(path) + if l == 0 { return } root := make(map[string]interface{}) - node:=root + node := root lastKey := path[l-1] - if l>1{ - for _,key:=range path[:l-1]{ + if l > 1 { + for _, key := range path[:l-1] { v := make(map[string]interface{}) - node[key]=v + node[key] = v node = v } } @@ -111,72 +114,74 @@ func (r *Response) Group(path []string) { node[lastKey] = r.Data r.Data = root } + //ReName 重命名 -func (r *Response)ReName(pattern string,newName string) { - if pattern == ""{ +func (r *Response) ReName(pattern string, newName string) { + if pattern == "" { return } - root:=_Node{ - data:r.Data, + root := _Node{ + data: r.Data, } root.Pattern(pattern, func(node *_Node) bool { - if node.parent ==nil { + if node.parent == nil { return false } - parent:= node.parent + parent := node.parent switch parent.data.(type) { case []interface{}: return false case map[string]interface{}: - mp:=parent.data.(map[string]interface{}) - delete(mp,node.key) - mp[newName]=node.data + mp := parent.data.(map[string]interface{}) + delete(mp, node.key) + mp[newName] = node.data return false } return false }) } -func (r *Response)Move(source ,target string) { +//Move move +func (r *Response) Move(source, target string) { - if strings.Index(source,"*") != -1{ + if strings.Index(source, "*") != -1 { return } - if strings.Index(target,"*") != -1{ + if strings.Index(target, "*") != -1 { return } - root:=_Node{ - data:r.Data, + root := _Node{ + data: r.Data, } var oldValues *_Node - match,_:=root.Pattern(source, func(node *_Node) bool { + match, _ := root.Pattern(source, func(node *_Node) bool { oldValues = node - if node.parent ==nil { + if node.parent == nil { return false } - parent:= node.parent + parent := node.parent switch parent.data.(type) { case []interface{}: - index:= node.index - sl:= parent.data.([]interface{}) + index := node.index + sl := parent.data.([]interface{}) - nl:=sl[:index] - sl=append(nl,sl[index+1]) + nl := sl[:index] + sl = append(nl, sl[index+1]) parent.data = sl case map[string]interface{}: - mp:=parent.data.(map[string]interface{}) - delete(mp,node.key) + mp := parent.data.(map[string]interface{}) + delete(mp, node.key) } return false }) - if match{ - r.SetValue(target,oldValues.data) - }else{ - r.SetValue(target,nil) + if match { + r.SetValue(target, oldValues.data) + } else { + r.SetValue(target, nil) } -} \ No newline at end of file +} diff --git a/node/gateway/router.go b/node/gateway/router.go index d05527ac16c1ecff8ac60c19cc0472179fe1ac2f..cef0e2c2b34eb301d27a361470a1e96d1381b508 100644 --- a/node/gateway/router.go +++ b/node/gateway/router.go @@ -2,6 +2,7 @@ package gateway import ( "errors" + "fmt" "net/http" "reflect" "strings" @@ -69,7 +70,7 @@ func (f *_RootFactory) createStrategy() map[string]*Strategy { // 构造策略 func (f *_RootFactory) genStrategy(cfg *config.StrategyConfig) *Strategy { - _, accesses, _ := genPlugins(cfg.Plugins, f.cluster, cfg.ID, 0) + _, accesses, proxies := genPlugins(cfg.Plugins, f.cluster, cfg.ID, 0) s := &Strategy{ ID: cfg.ID, @@ -100,20 +101,23 @@ func (f *_RootFactory) genStrategy(cfg *config.StrategyConfig) *Strategy { } if pluginObj.Access != nil && !reflect.ValueOf(pluginObj.Access).IsNil() { + if cfg.ID == "68YAY7" { + fmt.Println(authKey, pluginName) + } s.authPlugin[authKey] = plugin_executor.NewAccessExecutor(&config.PluginConfig{ Name: pluginName, IsStop: true, Config: authCfg, + IsAuth: true, }, pluginObj.Access) } } } factory := newAPIFactory(f, s.ID) - for _, apiCfg := range cfg.APIS { - iRouter, apiContent := factory.genAPIRouter(apiCfg) + iRouter, apiContent := factory.genAPIRouter(apiCfg, proxies) if iRouter == nil { continue } @@ -137,7 +141,7 @@ func newAPIFactory(root *_RootFactory, strategyID string) *_ApiFactory { strategyID: strategyID, } } -func (f *_ApiFactory) genAPIRouter(cfg *config.APIOfStrategy) (router.IRouter, *config.APIContent) { +func (f *_ApiFactory) genAPIRouter(cfg *config.APIOfStrategy, proxies []plugin_executor.Executor) (router.IRouter, *config.APIContent) { apiContend, has := f.root.apis[cfg.ID] if !has { @@ -149,13 +153,16 @@ func (f *_ApiFactory) genAPIRouter(cfg *config.APIOfStrategy) (router.IRouter, * return nil, nil } _, pluginAccesses, pluginProxies := genPlugins(cfg.Plugins, f.root.cluster, f.strategyID, cfg.ID) + pro := make([]plugin_executor.Executor, 0, len(proxies)+len(pluginProxies)) + pro = append(pro, proxies...) + pro = append(pro, pluginProxies...) return &API{ strategyID: f.strategyID, - apiID: cfg.ID, + apiID: cfg.ID, app: app, pluginAccess: pluginAccesses, - pluginProxies: pluginProxies, + pluginProxies: pro, pluginAccessGlobal: f.root.gAccesses, pluginProxiesGlobal: f.root.gProxies, }, apiContend @@ -169,7 +176,6 @@ func genFactory(cfg *config.GokuConfig, factory router.Factory) *_RootFactory { beforePlugin := genBeforPlugin(cfg.Plugins.BeforePlugins, cfg.Cluster) gBefores, gAccesses, gProxies := genPlugins(cfg.Plugins.GlobalPlugins, cfg.Cluster, "", 0) - apis := toMap(cfg.APIS) return &_RootFactory{ beforePlugin: beforePlugin, @@ -188,6 +194,9 @@ func genFactory(cfg *config.GokuConfig, factory router.Factory) *_RootFactory { func toMap(cfgs []*config.APIContent) map[int]*config.APIContent { m := make(map[int]*config.APIContent) for _, cfg := range cfgs { + //if cfg.ID == 1880 { + // fmt.Println(cfg) + //} m[cfg.ID] = cfg } return m diff --git a/node/gateway/strategy.go b/node/gateway/strategy.go index a08a23e80b19585f1de4b57b4c96015d16cefe54..a86d5a6cb9709b73ab84efdcfaeebb86b26db62b 100644 --- a/node/gateway/strategy.go +++ b/node/gateway/strategy.go @@ -4,6 +4,8 @@ import ( "fmt" "net/http" + "github.com/pkg/errors" + log "github.com/eolinker/goku-api-gateway/goku-log" "github.com/eolinker/goku-api-gateway/goku-node/common" plugin_executor "github.com/eolinker/goku-api-gateway/node/gateway/plugin-executor" @@ -45,50 +47,75 @@ func (r *Strategy) Router(w http.ResponseWriter, req *http.Request, ctx *common. if r.isNeedAuth { // 需要校验 - if !r.auth(ctx) { + ok, err := r.auth(ctx) + if err != nil { // 校验失败 ctx.SetStatus(403, "403") - ctx.SetBody([]byte("[ERROR]Illegal authorization type!")) + //ctx.SetBody([]byte("[ERROR]Illegal authorization type!")) + ctx.SetBody([]byte(err.Error())) + return + } + if !ok { + return + } + } + for _, strategyAccess := range r.accessPlugin { + if strategyAccess.IsAuth() { + continue + } + fmt.Println(strategyAccess.IsAuth()) + isContinued, err := strategyAccess.Execute(ctx) + if isContinued { + continue + } + if err != nil { + ctx.SetStatus(403, "403") + ctx.SetBody([]byte(err.Error())) return } } - r.apiRouter.ServeHTTP(w, req, ctx) } -func (r *Strategy) auth(ctx *common.Context) bool { +func (r *Strategy) auth(ctx *common.Context) (bool, error) { requestID := ctx.RequestId() authType := ctx.Request().GetHeader("Authorization-Type") authPlugin, has := r.authPlugin[authType] if !has { - log.Warn(requestID, " Illegal authorization type:", authType) - return false + errInfo := errors.New(" Illegal authorization type:" + authType) + log.Warn(requestID, errInfo.Error()) + return false, errInfo } isContinue, err := authPlugin.Execute(ctx) if isContinue == false { pluginName := authNames[authType] + + var errInfo error // 校验失败 if err != nil { - log.Warn(requestID, " access auth:[", pluginName, "] error:", err) + errInfo = errors.New(" access auth:[" + pluginName + "] error:" + err.Error()) + log.Warn(requestID, errInfo.Error()) + return false, errInfo } log.Info(requestID, " auth [", pluginName, "] refuse") - return false + return false, nil } log.Debug(requestID, " auth [", authType, "] pass") - return true + return true, nil } -func (r *Strategy) accessFlow(ctx *common.Context) { +func (r *Strategy) accessFlow(ctx *common.Context) bool { for _, handler := range r.accessPlugin { flag, _ := handler.Execute(ctx) if flag == false && handler.IsStop() { - return + return false } } + return true } func (r *Strategy) accessGlobalFlow(ctx *common.Context) { @@ -103,11 +130,18 @@ func (r *Strategy) accessGlobalFlow(ctx *common.Context) { func (r *Strategy) HandlerAPINotFound(ctx *common.Context) { // 未匹配到api // 执行策略access 插件 - r.accessFlow(ctx) + if !r.accessFlow(ctx) { + r.accessGlobalFlow(ctx) + return + } // 执行全局access 插件 r.accessGlobalFlow(ctx) - log.Info(ctx.RequestId(), " URL dose not exist!") - ctx.SetStatus(404, "404") - ctx.SetBody([]byte("[ERROR]URL dose not exist!")) + if ctx.StatusCode() == 0 { + // 插件可能会设置状态码 + log.Info(ctx.RequestId(), " URL dose not exist!") + ctx.SetStatus(404, "404") + ctx.SetBody([]byte("[ERROR]URL dose not exist!")) + } + } diff --git a/node/monitor/collector.go b/node/monitor/collector.go index 244414e0065f2fc4a10b4f317c9e5a20a800ad90..12873eef6024af288ab069b52eae86b1230b2e07 100644 --- a/node/monitor/collector.go +++ b/node/monitor/collector.go @@ -6,12 +6,13 @@ import ( ) var ( - //APICount diting.Counter + //APIMonitor diting.APIMonitor APIMonitor diting.Histogram + //ProxyMonitor diting.Histogram ProxyMonitor diting.Histogram ) -func initCollector(constLabels diting.Labels) { +func initCollector(constLabels diting.Labels) { //apiLabelNames := []string{ // goku_labels.Cluster, // goku_labels.Instance, @@ -22,29 +23,10 @@ func initCollector(constLabels diting.Labels) { //apiCounterOpt:= diting.NewCounterOpts("goku","api","count","api 请求计数",constLabels,apiLabelNames) //APICount = diting.NewCounter(apiCounterOpt) - buckets:=[]float64{5, 25, 50, 100, 200,400, 600,800,1000, 2500,5000} - //buckets:=[]float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10} - apiDelayLabelNames := []string{ - goku_labels.Cluster, - goku_labels.Instance, - goku_labels.API, - goku_labels.Strategy, - goku_labels.Status, - } - apiHistogramOpt := diting.NewHistogramOpts("goku","","api","api整体请求统计",constLabels,apiDelayLabelNames,buckets) + apiHistogramOpt := diting.NewHistogramOpts(goku_labels.Namespace, goku_labels.Subsystem, goku_labels.APIName, "api整体请求统计", constLabels, goku_labels.APIDelayLabelNames, goku_labels.APIBuckets) APIMonitor = diting.NewHistogram(apiHistogramOpt) - - proxyDelayLabelNames := []string{ - goku_labels.Cluster, - goku_labels.Instance, - goku_labels.Proto, - goku_labels.Host, - goku_labels.Path, - goku_labels.Method, - } - - proxyMonitorOpt := diting.NewHistogramOpts("goku","","proxy","转发统计",constLabels,proxyDelayLabelNames,buckets) + proxyMonitorOpt := diting.NewHistogramOpts(goku_labels.Namespace, goku_labels.Subsystem, goku_labels.ProxyName, "转发统计", constLabels, goku_labels.ProxyDelayLabelNames, goku_labels.ProxyBuckets) ProxyMonitor = diting.NewHistogram(proxyMonitorOpt) -} \ No newline at end of file +} diff --git a/node/monitor/monitor.go b/node/monitor/monitor.go index 153aaf0318b725617e49285e210ce49b16f781ee..ca2a11f3bfdc187054588cde6d796d848f6057db 100644 --- a/node/monitor/monitor.go +++ b/node/monitor/monitor.go @@ -1,26 +1,25 @@ package monitor import ( - "github.com/eolinker/goku-api-gateway/diting" - "github.com/eolinker/goku-api-gateway/goku-labels" "strings" "sync" -) + "github.com/eolinker/goku-api-gateway/diting" + goku_labels "github.com/eolinker/goku-api-gateway/goku-labels" +) var ( - once =sync.Once{} - + once = sync.Once{} ) -func Init(cluster string,instance string) { +//Init init +func Init(cluster string, instance string) { once.Do(func() { constLabels := make(diting.Labels) constLabels[goku_labels.Cluster] = cluster - constLabels[goku_labels.Instance] = strings.ReplaceAll(instance,".","_") + constLabels[goku_labels.Instance] = strings.ReplaceAll(instance, ".", "_") initCollector(constLabels) }) } - diff --git a/node/plugin-loader/pluginload.go b/node/plugin-loader/pluginload.go index 27c63cc39f92c587e9d764e4d793a4c1accd1ba4..7260bf0996676fc6d1c749b8ed1119f9f99b9b64 100644 --- a/node/plugin-loader/pluginload.go +++ b/node/plugin-loader/pluginload.go @@ -33,7 +33,7 @@ func (m *_GlodPluginManager) check(name string) (int, error) { return code, err } - _, e, errorCode := m.loadPlugin(name) + _, errorCode, e := m.loadPlugin(name) return errorCode, e } @@ -56,34 +56,31 @@ func (m *_GlodPluginManager) getPluginHandle(name string) (goku_plugin.PluginFac return p, has } -func LoadPlugin(name string)(goku_plugin.PluginFactory ,error) { - factory, err, _ := globalPluginManager.loadPlugin(name) +//LoadPlugin 加载插件 +func LoadPlugin(name string) (goku_plugin.PluginFactory, error) { + factory, _, err := globalPluginManager.loadPlugin(name) - return factory,err + return factory, err } // 加载动态库 -func (m *_GlodPluginManager) loadPlugin(name string) (goku_plugin.PluginFactory, error, int) { +func (m *_GlodPluginManager) loadPlugin(name string) (goku_plugin.PluginFactory, int, error) { handle, has := m.getPluginHandle(name) if has { - return handle, nil, LoadOk + return handle, LoadOk, nil } m.gloadPluginLocker.Lock() defer m.gloadPluginLocker.Unlock() - handle, has = m.gloadPlugin[name] - if has { - return handle, nil, LoadOk - } - path, _ := filepath.Abs(fmt.Sprintf("plugin/%s.so", name)) + pdll, err := plugin.Open(path) if err != nil { - e := fmt.Errorf("The plugin file named '%s.so' can not be found in plugin:%s ", name, err.Error()) + e := fmt.Errorf("plugin:%s ", name, err.Error()) m.errors[name] = e m.errorCodes[name] = LoadFileError - return nil, e, LoadFileError + return nil, LoadFileError, e } //structName := strings.Replace(name, "-", "_", -1) @@ -93,11 +90,10 @@ func (m *_GlodPluginManager) loadPlugin(name string) (goku_plugin.PluginFactory, v, err := pdll.Lookup("Builder") if err != nil { - e := fmt.Errorf("The Builder can not be found in plugin/%s.so ", name) + e := fmt.Errorf("The Builder can not be found in plugin/%s.so ", name) m.errors[name] = e m.errorCodes[name] = LoadLookupError - - return nil, e, LoadLookupError + return nil, LoadLookupError, e } vp, ok := v.(func() goku_plugin.PluginFactory) @@ -105,18 +101,19 @@ func (m *_GlodPluginManager) loadPlugin(name string) (goku_plugin.PluginFactory, e := fmt.Errorf("The builder func can not implemented interface named goku_plugin.PluginFactory:%s ", name) m.errors[name] = e m.errorCodes[name] = LoadInterFaceError - return nil, e, LoadInterFaceError + return nil, LoadInterFaceError, e } factory := vp() if factory == nil || reflect.ValueOf(factory).IsNil() { e := fmt.Errorf("The builder result is nil:%s ", name) m.errors[name] = e m.errorCodes[name] = LoadInterFaceError - return nil, e, LoadInterFaceError + fmt.Println(e) + return nil, LoadInterFaceError, e } m.gloadPlugin[name] = factory m.errorCodes[name] = LoadOk m.errors[name] = nil - return factory, nil, LoadOk + return factory, LoadOk, nil } diff --git a/node/router/httprouter/router.go b/node/router/httprouter/router.go index df3cf7fc6a9f652ec5d47cfb02b5e3763dfa814b..207fa78cb81e791762eb9628f248fa2385097494 100644 --- a/node/router/httprouter/router.go +++ b/node/router/httprouter/router.go @@ -4,8 +4,8 @@ import ( "net/http" "github.com/eolinker/goku-api-gateway/goku-node/common" + "github.com/eolinker/goku-api-gateway/module/httprouter" "github.com/eolinker/goku-api-gateway/node/router" - "github.com/julienschmidt/httprouter" ) //HTTPRouter httpRouter @@ -29,6 +29,7 @@ type Engine struct { //AddRouter addRouter func (r *Engine) AddRouter(method, path string, router router.IRouter) { + r.router.Handle(method, path, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) { ctx := ContextFromRequest(req) diff --git a/node/routerRule/internal/rule.go b/node/routerRule/internal/rule.go new file mode 100644 index 0000000000000000000000000000000000000000..04123989774d554e721b204393f496eba1985246 --- /dev/null +++ b/node/routerRule/internal/rule.go @@ -0,0 +1,7 @@ +package internal + +//RouterRule RouterRule +type RouterRule interface { + GetTargets() []int + Match(arg ...string) bool +} diff --git a/node/routerRule/manager.go b/node/routerRule/manager.go new file mode 100644 index 0000000000000000000000000000000000000000..020259d51c13806d89b1f75b8a89719c27f40fee --- /dev/null +++ b/node/routerRule/manager.go @@ -0,0 +1,95 @@ +package routerRule + +import ( + "encoding/json" + "sort" + "strings" + + "github.com/eolinker/goku-api-gateway/config" + "github.com/eolinker/goku-api-gateway/utils" +) + +//Router router +type Router struct { + Host string `json:"host"` + StrategyID string `json:"strategyID"` + ID string `json:"id"` +} + +//Match match +func (r *Router) Match(c *config.RouterRule) (bool, string) { + if r.Host != "" && !matchHost(r.Host, c.Host) { + return false, "" + } + + if r.StrategyID != "" && r.StrategyID != c.StrategyID { + return false, "" + } + return true, r.ID +} + +var router = make([]*Router, 0) + +func newRouter(rs []*config.Router) []*Router { + newRs := make([]*Router, 0, len(rs)) + if rs == nil { + return newRs + } + for _, r := range rs { + rls := make([]*config.RouterRule, 0) + err := json.Unmarshal([]byte(r.Rules), &rls) + if err != nil { + continue + } + ts := make([]int, 0, 2) + err = json.Unmarshal([]byte(r.Target), &ts) + if err != nil { + continue + } + if len(ts) == 1 && ts[0] == 0 { + // 指标只有策略ID + newRs = append(newRs, &Router{Host: "", StrategyID: ""}) + continue + } + commonRs := make([]*Router, 0, len(rls)) + for _, rl := range rls { + var host, strategyID string + if strings.Contains(r.Target, "0") { + // 指标包括策略ID + strategyID = rl.StrategyID + } + if strings.Contains(r.Target, "1") { + // 指标包括Host + host = rl.Host + } + commonRs = append(commonRs, &Router{Host: host, StrategyID: strategyID, ID: rl.StrategyID}) + } + sort.Sort(Routers(commonRs)) + newRs = append(newRs, commonRs...) + } + return newRs +} + +//Load load +func Load(rs []*config.Router) { + router = newRouter(rs) +} + +//Get get +func Get() []*Router { + return router +} + +func matchHost(org, match string) bool { + if org == "*" || org == match { + return true + } + + _, o := utils.Intercept(org, ".") + _, m := utils.Intercept(match, ".") + if o == m && string(org[0]) == "*" { + return true + } + + return false +} diff --git a/node/routerRule/sort.go b/node/routerRule/sort.go new file mode 100644 index 0000000000000000000000000000000000000000..5541b595be231b808d04d1feb16993c5a2c307e1 --- /dev/null +++ b/node/routerRule/sort.go @@ -0,0 +1,30 @@ +package routerRule + +import "strings" + +//Routers Routers +type Routers []*Router + +func (p Routers) Len() int { + return len(p) +} + +func (p Routers) Less(i, j int) bool { + if p[i].Host == "*" { + return false + } + if p[j].Host == "*" { + return true + } + if strings.Contains(p[i].Host, "*") { + return false + } + if strings.Contains(p[j].Host, "*") { + return true + } + return false +} + +func (p Routers) Swap(i, j int) { + p[i], p[j] = p[j], p[i] +} diff --git a/node/server.go b/node/server.go new file mode 100644 index 0000000000000000000000000000000000000000..8948864f44af2aa5a578332deb9b18a469c87d87 --- /dev/null +++ b/node/server.go @@ -0,0 +1,14 @@ +package node + +import ( + log "github.com/eolinker/goku-api-gateway/goku-log" + + redis_plugin_proxy "github.com/eolinker/goku-api-gateway/goku-node/redis-plugin-proxy" + goku_plugin "github.com/eolinker/goku-plugin" +) + +func InitPluginUtils() { + goku_plugin.SetRedisManager(redis_plugin_proxy.Create()) + goku_plugin.InitLog(log.GetLogger()) + //goku_plugin.SetLog(new(log_plugin_proxy.LoggerGeneral)) +} diff --git a/node/server/admin.go b/node/server/admin.go index 44e34197fbe6dac0eea6fb4a9f184dc2e5aa8ccf..7ecbe029b9a5bec5c845bcd0bd79d853bdabf5ab 100644 --- a/node/server/admin.go +++ b/node/server/admin.go @@ -1,19 +1,26 @@ package server import ( - "github.com/eolinker/goku-api-gateway/common/endless" - "github.com/eolinker/goku-api-gateway/node/admin" "log" "sync" -) -var (adminOnce = sync.Once{}) -func StartAdmin(address string) { + "github.com/eolinker/goku-api-gateway/common/endless" + + "github.com/eolinker/goku-api-gateway/node/admin" +) +var ( + adminOnce = sync.Once{} +) +//StartAdmin 启动节点管理端 +func StartAdmin(address string) { go adminOnce.Do(func() { - err :=endless.ListenAndServe(address,admin.Handler()) - if err!=nil{ + server := endless.NewServer(address, admin.Handler()) + endless.SetAdminServer(server) + err := server.ListenAndServe() + //err := http.ListenAndServe(address, admin.Handler()) + if err != nil { log.Fatal(err) } }) diff --git a/node/server/log.go b/node/server/log.go index 4dd7686f7fb24add976589fd0e17d9568bc9d190..aea36e2f7c9752d3f7fad552537facb009307374 100644 --- a/node/server/log.go +++ b/node/server/log.go @@ -67,6 +67,7 @@ func defaultAccessLogConfig() *config.AccessLogConfig { Dir: "work/logs/", File: "access.log", Period: "hour", + Expire: 3, Fields: nil, } } diff --git a/node/server/server.go b/node/server/server.go index b1c1b8dbfc9eba81153da08ce63197a9713b400e..e447e0db16730be4ab893e624f46d240c0fa998a 100644 --- a/node/server/server.go +++ b/node/server/server.go @@ -2,13 +2,25 @@ package server import ( "errors" + "fmt" + "net/http" + "runtime/debug" + + "github.com/eolinker/goku-api-gateway/common/endless" + + "github.com/eolinker/goku-api-gateway/goku-service/application" + + "github.com/eolinker/goku-api-gateway/node/routerRule" + + redis_manager "github.com/eolinker/goku-api-gateway/common/redis-manager" + "github.com/eolinker/goku-api-gateway/node" + "github.com/eolinker/goku-api-gateway/diting" "github.com/eolinker/goku-api-gateway/module" "github.com/eolinker/goku-api-gateway/node/admin" "github.com/eolinker/goku-api-gateway/node/monitor" - "net/http" + entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" - "github.com/eolinker/goku-api-gateway/common/endless" "github.com/eolinker/goku-api-gateway/config" log "github.com/eolinker/goku-api-gateway/goku-log" "github.com/eolinker/goku-api-gateway/node/console" @@ -20,7 +32,7 @@ import ( type Server struct { //port int //console *console.Console - router http.Handler + router http.Handler } //NewServer newServer @@ -28,7 +40,7 @@ func NewServer() *Server { return &Server{ //port: port, //console: nil, - router: nil, + router: nil, } } @@ -38,72 +50,115 @@ func (s *Server) SetRouter(r http.Handler) error { return nil } - -//Server server -func (s *Server) ServerWidthConsole(console *console.Console ) error { - if console == nil { +//ServerWidthConsole 开启节点监听服务 +func (s *Server) ServerWidthConsole(console console.ConfigConsole) error { + if console == nil { return errors.New("can not start server widthout router and console") } if console != nil { - conf, err := console.GetConfig() + conf, err := console.RegisterToConsole() if err != nil { return err } console.AddListen(s.FlushRouter) console.AddListen(s.FlushModule) - return s.ServerWidthConfig(conf) + console.AddListen(s.FlushRedisConfig) + console.AddListen(s.FlushRouterRule) + console.AddListen(s.FlushGatewayBasicConfig) + + console.Listen() + + return s.ServerWidthConfig(conf) } - return errors.New("can not start server widthout router and console") + return errors.New("can not start server widthout router and console") } -func (s *Server)ServerWidthConfig(conf *config.GokuConfig)error { +//ServerWidthConfig 处理配置 +func (s *Server) ServerWidthConfig(conf *config.GokuConfig) error { - if conf == nil{ + if conf == nil { return errors.New("can not start server width out config") } - + s.FlushRedisConfig(conf) r, err := gateway.Parse(conf, httprouter.Factory()) if err != nil { log.Panic("parse config error:", err) } + if conf.GatewayBasicInfo != nil { + application.SetSkipCertificate(conf.GatewayBasicInfo.SkipCertificate) + } e := s.SetRouter(r) if e != nil { return e } + routerRule.Load(conf.Routers) + // 初始化监控模块 - monitor.Init(conf.Cluster,conf.Instance) + monitor.Init(conf.Cluster, conf.Instance) s.FlushModule(conf) - if conf.BindAddress == ""{ + if conf.BindAddress == "" { log.Panic("invalid bind address") } - //if conf.AdminAddress == ""{ - // log.Panic("invalid admin address") - //} + // 启用管理接口 - if conf.AdminAddress != ""{ + if conf.AdminAddress != "" { StartAdmin(conf.AdminAddress) } return endless.ListenAndServe(conf.BindAddress, s) + //return http.ListenAndServe(conf.BindAddress, s) } + //FlushRouter flushConfig func (s *Server) FlushRouter(config *config.GokuConfig) { + r, err := gateway.Parse(config, httprouter.Factory()) + if err != nil { + log.Error("parse config error:", err) + return + } + _ = s.SetRouter(r) +} +//FlushRouterRule flushConfig +func (s *Server) FlushRouterRule(config *config.GokuConfig) { + routerRule.Load(config.Routers) +} - r, err := gateway.Parse(config, httprouter.Factory()) - if err != nil { - log.Error("parse config error:", err) +//FlushGatewayBasicConfig 刷新网关基础配置 +func (s *Server) FlushGatewayBasicConfig(config *config.GokuConfig) { + if config.GatewayBasicInfo != nil { + application.SetSkipCertificate(config.GatewayBasicInfo.SkipCertificate) + } +} + +//FlushRedisConfig 刷新redis配置 +func (s *Server) FlushRedisConfig(config *config.GokuConfig) { + if r, ok := config.ExtendsConfig["redis"]; ok { + if r == nil { return } - _=s.SetRouter(r) + rr := r.(map[string]interface{}) + rdsConfig := &entity.ClusterRedis{ + Addrs: rr["addrs"].(string), + DbIndex: int(rr["dbIndex"].(float64)), + Masters: rr["masters"].(string), + Mode: rr["mode"].(string), + Password: rr["password"].(string), + } + rds := redis_manager.Create(rdsConfig) + log.Info(rdsConfig) + redis_manager.SetDefault(rds) + node.InitPluginUtils() + } } -//FlushRouter flushConfig + +//FlushModule 刷新模块配置 func (s *Server) FlushModule(conf *config.GokuConfig) { SetLog(conf.Log) SetAccessLog(conf.AccessLog) @@ -119,6 +174,13 @@ func (s *Server) FlushModule(conf *config.GokuConfig) { } func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) { + defer func() { + if err := recover(); err != nil { + fmt.Println(err) + print(err) + debug.PrintStack() + } + }() if s.router == nil { w.WriteHeader(404) return diff --git a/server/dao/console-sqlite3/api.go b/server/dao/console-sqlite3/api.go index aebfdb013623e17c04ee98afa342b901ed125d4e..4da2032fb42954d0105eac8496882eb152c1ae7c 100644 --- a/server/dao/console-sqlite3/api.go +++ b/server/dao/console-sqlite3/api.go @@ -8,16 +8,34 @@ import ( "strings" "time" - database2 "github.com/eolinker/goku-api-gateway/common/database" + "github.com/eolinker/goku-api-gateway/server/dao" + entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +//APIDao APIDao +type APIDao struct { + db *SQL.DB +} + +//NewAPIDao new APIDao +func NewAPIDao() *APIDao { + return &APIDao{} +} + +//Create create +func (d *APIDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.APIDao = d + return &i, nil +} + // AddAPI 新增接口 -func AddAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkAPIs, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, managerID, userID, apiType int) (bool, int, error) { - db := database2.GetConnection() +func (d *APIDao) AddAPI(apiName, alias, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkAPIs, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, managerID, userID, apiType int) (bool, int, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") Tx, _ := db.Begin() - res, err := Tx.Exec("INSERT INTO goku_gateway_api (projectID,groupID,apiName,requestURL,targetURL,requestMethod,targetMethod,protocol,linkAPIs,staticResponse,responseDataType,balanceName,isFollow,timeout,retryCount,alertValve,createTime,updateTime,managerID,lastUpdateUserID,createUserID,apiType) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);", projectID, groupID, apiName, requestURL, targetURL, requestMethod, targetMethod, protocol, linkAPIs, staticResponse, responseDataType, balanceName, isFollow, timeout, retryCount, alertValve, now, now, managerID, userID, userID, apiType) + res, err := Tx.Exec("INSERT INTO goku_gateway_api (projectID,groupID,apiName,alias,requestURL,targetURL,requestMethod,targetMethod,protocol,linkAPIs,staticResponse,responseDataType,balanceName,isFollow,timeout,retryCount,alertValve,createTime,updateTime,managerID,lastUpdateUserID,createUserID,apiType) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);", projectID, groupID, apiName, alias, requestURL, targetURL, requestMethod, targetMethod, protocol, linkAPIs, staticResponse, responseDataType, balanceName, isFollow, timeout, retryCount, alertValve, now, now, managerID, userID, userID, apiType) if err != nil { Tx.Rollback() @@ -35,11 +53,11 @@ func AddAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollo } // EditAPI 修改接口 -func EditAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkAPIs, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, apiID, managerID, userID int) (bool, error) { - db := database2.GetConnection() +func (d *APIDao) EditAPI(apiName, alias, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkAPIs, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, apiID, managerID, userID int) (bool, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") Tx, _ := db.Begin() - _, err := Tx.Exec("UPDATE goku_gateway_api SET projectID = ?,groupID = ?,apiName = ?,requestURL = ?,targetURL = ?,requestMethod = ?,protocol = ?,balanceName = ?,targetMethod = ?,isFollow = ?,linkAPIs = ?,staticResponse = ?,responseDataType = ?,timeout = ?,retryCount = ?,alertValve = ?,updateTime = ?,managerID = ?,lastUpdateUserID = ? WHERE apiID = ?", projectID, groupID, apiName, requestURL, targetURL, requestMethod, protocol, balanceName, targetMethod, isFollow, linkAPIs, staticResponse, responseDataType, timeout, retryCount, alertValve, now, managerID, userID, apiID) + _, err := Tx.Exec("UPDATE goku_gateway_api SET projectID = ?,groupID = ?,apiName = ?,alias = ?,requestURL = ?,targetURL = ?,requestMethod = ?,protocol = ?,balanceName = ?,targetMethod = ?,isFollow = ?,linkAPIs = ?,staticResponse = ?,responseDataType = ?,timeout = ?,retryCount = ?,alertValve = ?,updateTime = ?,managerID = ?,lastUpdateUserID = ? WHERE apiID = ?", projectID, groupID, apiName, alias, requestURL, targetURL, requestMethod, protocol, balanceName, targetMethod, isFollow, linkAPIs, staticResponse, responseDataType, timeout, retryCount, alertValve, now, managerID, userID, apiID) if err != nil { Tx.Rollback() @@ -56,9 +74,9 @@ func EditAPI(apiName, requestURL, targetURL, requestMethod, targetMethod, isFoll } // GetAPIInfo 获取接口信息 -func GetAPIInfo(apiID int) (bool, *entity.API, error) { - db := database2.GetConnection() - sql := `SELECT goku_gateway_api.apiID,goku_gateway_api.groupID,goku_gateway_api.apiName,goku_gateway_api.requestURL,goku_gateway_api.targetURL,goku_gateway_api.requestMethod,goku_gateway_api.targetMethod,IFNULL(goku_gateway_api.protocol,"http"),IFNULL(goku_gateway_api.balanceName,""),goku_gateway_api.isFollow,goku_gateway_api.timeout,goku_gateway_api.retryCount,goku_gateway_api.alertValve,goku_gateway_api.createTime,goku_gateway_api.updateTime,goku_gateway_api.managerID,goku_gateway_api.lastUpdateUserID,goku_gateway_api.createUserID,IFNULL(goku_gateway_api_group.groupPath,"0"),goku_gateway_api.apiType,IFNULL(goku_gateway_api.linkAPIs,''),IFNULL(goku_gateway_api.staticResponse,''),IFNULL(goku_gateway_api.responseDataType,'origin') FROM goku_gateway_api LEFT JOIN goku_gateway_api_group ON goku_gateway_api.groupID = goku_gateway_api_group.groupID WHERE goku_gateway_api.apiID = ?` +func (d *APIDao) GetAPIInfo(apiID int) (bool, *entity.API, error) { + db := d.db + sql := `SELECT A.apiID,A.groupID,A.apiName,A.requestURL,A.targetURL,A.requestMethod,A.targetMethod,IFNULL(A.protocol,"http"),IFNULL(A.balanceName,""),A.isFollow,A.timeout,A.retryCount,A.alertValve,A.createTime,A.updateTime,A.managerID,A.lastUpdateUserID,A.createUserID,IFNULL(goku_gateway_api_group.groupPath,"0"),A.apiType,IFNULL(A.linkAPIs,''),IFNULL(A.staticResponse,''),IFNULL(A.responseDataType,'origin') FROM goku_gateway_api A LEFT JOIN goku_gateway_api_group ON A.groupID = goku_gateway_api_group.groupID WHERE A.apiID = ?` api := &entity.API{} var managerInfo entity.ManagerInfo var linkAPIs string @@ -93,10 +111,10 @@ func GetAPIInfo(apiID int) (bool, *entity.API, error) { } //GetAPIListByGroupList 通过分组列表获取接口列表 -func GetAPIListByGroupList(projectID int, groupIDList string) (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *APIDao) GetAPIListByGroupList(projectID int, groupIDList string) (bool, []map[string]interface{}, error) { + db := d.db // 获取分组ID列表 - sql := `SELECT goku_gateway_api.apiID,goku_gateway_api.apiName,goku_gateway_api.requestURL,IFNULL(goku_gateway_api.updateTime,""),goku_gateway_api.lastUpdateUserID,goku_gateway_api.managerID FROM goku_gateway_api WHERE goku_gateway_api.projectID = ? AND goku_gateway_api.groupID IN (` + groupIDList + `) ORDER BY goku_gateway_api.updateTime DESC;` + sql := `SELECT A.apiID,A.apiName,A.requestURL,IFNULL(A.updateTime,""),A.lastUpdateUserID,A.managerID FROM goku_gateway_api A WHERE A.projectID = ? AND A.groupID IN (` + groupIDList + `) ORDER BY A.updateTime DESC;` rows, err := db.Query(sql, projectID) if err != nil { @@ -182,8 +200,8 @@ func getAPIRule(projectID int, keyword string, condition int, ids []int) []strin } // GetAPIIDList 获取接口ID列表 -func GetAPIIDList(projectID int, groupID int, keyword string, condition int, ids []int) (bool, []int, error) { - db := database2.GetConnection() +func (d *APIDao) GetAPIIDList(projectID int, groupID int, keyword string, condition int, ids []int) (bool, []int, error) { + db := d.db rule := getAPIRule(projectID, keyword, condition, ids) if groupID < 1 { @@ -213,7 +231,7 @@ func GetAPIIDList(projectID int, groupID int, keyword string, condition int, ids ruleStr += "WHERE " + strings.Join(rule, " AND ") } - sql := fmt.Sprintf(`SELECT A.apiID FROM goku_gateway_api A %s`, ruleStr) + sql := fmt.Sprintf(`SELECT A.apiID FROM goku_gateway_api A %s`, ruleStr) rows, err := db.Query(sql) if err != nil { return false, make([]int, 0), err @@ -234,8 +252,8 @@ func GetAPIIDList(projectID int, groupID int, keyword string, condition int, ids } // GetAPIList 获取所有接口列表 -func GetAPIList(projectID int, groupID int, keyword string, condition, page, pageSize int, ids []int) (bool, []map[string]interface{}, int, error) { - db := database2.GetConnection() +func (d *APIDao) GetAPIList(projectID int, groupID int, keyword string, condition, page, pageSize int, ids []int) (bool, []map[string]interface{}, int, error) { + db := d.db rule := getAPIRule(projectID, keyword, condition, ids) if groupID < 1 { @@ -265,9 +283,9 @@ func GetAPIList(projectID int, groupID int, keyword string, condition, page, pag ruleStr += "WHERE " + strings.Join(rule, " AND ") } - sql := fmt.Sprintf(`SELECT A.apiID,A.apiName,A.requestURL,A.requestMethod,CASE WHEN A.apiType=0 THEN A.targetURL ELSE '' END,A.apiType,IFNULL(A.balanceName,''),IFNULL(A.updateTime,""),CASE WHEN B.remark is null or B.remark = "" THEN B.loginCall ELSE B.remark END AS updaterName,CASE WHEN C.remark is null or C.remark = "" THEN C.loginCall ELSE C.remark END AS managerName,A.lastUpdateUserID,A.managerID,A.isFollow,IFNULL(A.protocol,"http"),A.targetMethod,A.groupID,IFNULL(D.groupPath,"0"),IFNULL(D.groupName,"未分组") FROM goku_gateway_api A INNER JOIN goku_admin B ON A.lastUpdateUserID = B.userID INNER JOIN goku_admin C ON A.managerID=C.userID LEFT JOIN goku_gateway_api_group D ON D.groupID = A.groupID %s`, ruleStr) - count := getCountSQL(sql) - rows, err := getPageSQL(sql, "A.updateTime", "DESC", page, pageSize) + sql := fmt.Sprintf(`SELECT A.apiID,A.apiName,A.requestURL,A.requestMethod,CASE WHEN A.apiType=0 THEN A.targetURL ELSE '' END,A.apiType,IFNULL(A.balanceName,''),IFNULL(A.updateTime,""),CASE WHEN B.remark is null or B.remark = "" THEN B.loginCall ELSE B.remark END AS updaterName,CASE WHEN C.remark is null or C.remark = "" THEN C.loginCall ELSE C.remark END AS managerName,A.lastUpdateUserID,A.managerID,A.isFollow,IFNULL(A.protocol,"http"),A.targetMethod,A.groupID,IFNULL(D.groupPath,"0"),IFNULL(D.groupName,"未分组") FROM goku_gateway_api A INNER JOIN goku_admin B ON A.lastUpdateUserID = B.userID INNER JOIN goku_admin C ON A.managerID=C.userID LEFT JOIN goku_gateway_api_group D ON D.groupID = A.groupID %s`, ruleStr) + count := getCountSQL(d.db, sql) + rows, err := getPageSQL(d.db, sql, "A.updateTime", "DESC", page, pageSize) if err != nil { return false, make([]map[string]interface{}, 0), 0, err } @@ -307,11 +325,11 @@ func GetAPIList(projectID int, groupID int, keyword string, condition, page, pag } //CheckURLIsExist 接口路径是否存在 -func CheckURLIsExist(requestURL, requestMethod string, projectID, apiID int) bool { - db := database2.GetConnection() +func (d *APIDao) CheckURLIsExist(requestURL, requestMethod string, projectID, apiID int) bool { + db := d.db var id int var m string - sql := "SELECT apiID,requestMethod FROM goku_gateway_api WHERE requestURL = ? AND projectID = ?;" + sql := "SELECT apiID,requestMethod FROM goku_gateway_api A WHERE requestURL = ? AND projectID = ?;" err := db.QueryRow(sql, requestURL, projectID).Scan(&id, &m) if err != nil { return false @@ -332,9 +350,9 @@ func CheckURLIsExist(requestURL, requestMethod string, projectID, apiID int) boo } //CheckAPIIsExist 检查接口是否存在 -func CheckAPIIsExist(apiID int) (bool, error) { - db := database2.GetConnection() - sql := "SELECT apiID FROM goku_gateway_api WHERE apiID = ?;" +func (d *APIDao) CheckAPIIsExist(apiID int) (bool, error) { + db := d.db + sql := "SELECT apiID FROM goku_gateway_api A WHERE apiID = ?;" var id int err := db.QueryRow(sql, apiID).Scan(&id) if err != nil { @@ -343,9 +361,29 @@ func CheckAPIIsExist(apiID int) (bool, error) { return true, err } +//CheckAliasIsExist 检查别名是否存在 +func (d *APIDao) CheckAliasIsExist(apiID int, alias string) bool { + if alias == "" { + return false + } + + db := d.db + sql := "SELECT apiID FROM goku_gateway_api A WHERE alias = ?;" + var id int + err := db.QueryRow(sql, apiID).Scan(&id) + if err != nil { + return false + } + if id != 0 && apiID == id { + return false + } + + return true +} + //BatchEditAPIBalance 批量修改接口负载 -func BatchEditAPIBalance(apiIDList []string, balance string) (string, error) { - db := database2.GetConnection() +func (d *APIDao) BatchEditAPIBalance(apiIDList []string, balance string) (string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") sqlTpl := "UPDATE `goku_gateway_api` A LEFT JOIN `goku_gateway_project` P ON A.`projectID` = P.`projectID` SET A.`updateTime` = ?, P.`updateTime`=?, A.`balanceName`=? WHERE A.`apiID` IN (%s)" @@ -365,8 +403,8 @@ func BatchEditAPIBalance(apiIDList []string, balance string) (string, error) { } //BatchEditAPIGroup 批量修改接口分组 -func BatchEditAPIGroup(apiIDList []string, groupID int) (string, error) { - db := database2.GetConnection() +func (d *APIDao) BatchEditAPIGroup(apiIDList []string, groupID int) (string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") sqlTpl := "UPDATE `goku_gateway_api` A LEFT JOIN `goku_gateway_project` P ON A.`projectID` = P.`projectID` SET A.`updateTime` = ?, P.`updateTime`=?, A.`groupID`=? WHERE A.`apiID` IN (%s)" @@ -386,11 +424,11 @@ func BatchEditAPIGroup(apiIDList []string, groupID int) (string, error) { } //BatchDeleteAPI 批量修改接口 -func BatchDeleteAPI(apiIDList string) (bool, string, error) { - db := database2.GetConnection() +func (d *APIDao) BatchDeleteAPI(apiIDList string) (bool, string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") Tx, _ := db.Begin() - sql := "DELETE FROM goku_gateway_api WHERE apiID IN (" + apiIDList + ");" + sql := "DELETE FROM goku_gateway_api A WHERE apiID IN (" + apiIDList + ");" _, err := Tx.Exec(sql) if err != nil { Tx.Rollback() @@ -410,7 +448,7 @@ func BatchDeleteAPI(apiIDList string) (bool, string, error) { } // 查询接口的projectID - rows, err := db.Query("SELECT projectID FROM goku_gateway_api WHERE apiID IN (" + apiIDList + ");") + rows, err := db.Query("SELECT projectID FROM goku_gateway_api A WHERE apiID IN (" + apiIDList + ");") if err != nil { Tx.Rollback() return false, "[ERROR]Fail to excute SQL statement!", err diff --git a/server/dao/console-sqlite3/apiGroup.go b/server/dao/console-sqlite3/apiGroup.go index 023143eda7deb216ac5dbe0e3fb64dff56b81bf2..938b9b848e224e270956ab8e453c54a03e9b8281 100644 --- a/server/dao/console-sqlite3/apiGroup.go +++ b/server/dao/console-sqlite3/apiGroup.go @@ -5,12 +5,38 @@ import ( "strconv" "time" - database2 "github.com/eolinker/goku-api-gateway/common/database" + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" ) +var ( + apiDao dao.APIDao +) + +func init() { + pdao.Need(&apiDao) +} + +//APIGroupDao APIGroupDao +type APIGroupDao struct { + db *SQL.DB +} + +//NewAPIGroupDao new APIGroupDao +func NewAPIGroupDao() *APIGroupDao { + return &APIGroupDao{} +} + +//Create create +func (d *APIGroupDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.APIGroupDao = d + return &i, nil +} + //AddAPIGroup 新建接口分组 -func AddAPIGroup(groupName string, projectID, parentGroupID int) (bool, interface{}, error) { - db := database2.GetConnection() +func (d *APIGroupDao) AddAPIGroup(groupName string, projectID, parentGroupID int) (bool, interface{}, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") Tx, _ := db.Begin() groupPath := "" @@ -69,8 +95,8 @@ func AddAPIGroup(groupName string, projectID, parentGroupID int) (bool, interfac } //EditAPIGroup 修改接口分组 -func EditAPIGroup(groupName string, groupID, projectID int) (bool, string, error) { - db := database2.GetConnection() +func (d *APIGroupDao) EditAPIGroup(groupName string, groupID, projectID int) (bool, string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") Tx, _ := db.Begin() sql := "UPDATE goku_gateway_api_group SET groupName = ? WHERE groupID = ? AND projectID = ?;" @@ -90,8 +116,8 @@ func EditAPIGroup(groupName string, groupID, projectID int) (bool, string, error } //DeleteAPIGroup 删除接口分组 -func DeleteAPIGroup(projectID, groupID int) (bool, string, error) { - db := database2.GetConnection() +func (d *APIGroupDao) DeleteAPIGroup(projectID, groupID int) (bool, string, error) { + db := d.db Tx, _ := db.Begin() var groupPath string // 获取分组信息 @@ -114,7 +140,7 @@ func DeleteAPIGroup(projectID, groupID int) (bool, string, error) { Tx.Rollback() return false, "[ERROR]Fail to delete data!", err } - flag, apiList, _ := GetAPIListByGroupList(projectID, concatGroupID) + flag, apiList, _ := apiDao.GetAPIListByGroupList(projectID, concatGroupID) if flag { listLen := len(apiList) if listLen > 0 { @@ -167,8 +193,8 @@ func DeleteAPIGroup(projectID, groupID int) (bool, string, error) { } //GetAPIGroupList 获取接口分组列表 -func GetAPIGroupList(projectID int) (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *APIGroupDao) GetAPIGroupList(projectID int) (bool, []map[string]interface{}, error) { + db := d.db sql := "SELECT groupID,groupName,parentGroupID,groupDepth FROM goku_gateway_api_group WHERE projectID = ?;" rows, err := db.Query(sql, projectID) if err != nil { diff --git a/server/dao/console-sqlite3/apiPlugin.go b/server/dao/console-sqlite3/apiPlugin.go index ec4e4f81d661463a5529b8ebf4c61595cfa8c552..f23e8360b4c4c119a6e813c9785667e14f5a7dd8 100644 --- a/server/dao/console-sqlite3/apiPlugin.go +++ b/server/dao/console-sqlite3/apiPlugin.go @@ -6,18 +6,33 @@ import ( "fmt" "strings" - log "github.com/eolinker/goku-api-gateway/goku-log" + "github.com/eolinker/goku-api-gateway/server/dao" - database2 "github.com/eolinker/goku-api-gateway/common/database" + log "github.com/eolinker/goku-api-gateway/goku-log" "time" ) -var apiPlugins = []string{"goku-proxy_caching", "goku-circuit_breaker"} +//APIPluginDao APIPluginDao +type APIPluginDao struct { + db *SQL.DB +} + +//NewAPIPluginDao new APIPluginDao +func NewAPIPluginDao() *APIPluginDao { + return &APIPluginDao{} +} + +//Create create +func (d *APIPluginDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.APIPluginDao = d + return &i, nil +} //AddPluginToAPI 新增接口插件 -func AddPluginToAPI(pluginName, config, strategyID string, apiID, userID int) (bool, interface{}, error) { - db := database2.GetConnection() +func (d *APIPluginDao) AddPluginToAPI(pluginName, config, strategyID string, apiID, userID int) (bool, interface{}, error) { + db := d.db // 查询接口是否添加该插件 sql := "SELECT apiID FROM goku_conn_plugin_api WHERE strategyID = ? AND pluginName = ? AND apiID = ?;" var id int @@ -44,8 +59,8 @@ func AddPluginToAPI(pluginName, config, strategyID string, apiID, userID int) (b } //EditAPIPluginConfig 修改接口插件配置 -func EditAPIPluginConfig(pluginName, config, strategyID string, apiID, userID int) (bool, interface{}, error) { - db := database2.GetConnection() +func (d *APIPluginDao) EditAPIPluginConfig(pluginName, config, strategyID string, apiID, userID int) (bool, interface{}, error) { + db := d.db // 查询接口是否添加该插件 t := time.Now() now := t.Format("2006-01-02 15:04:05") @@ -75,8 +90,8 @@ func EditAPIPluginConfig(pluginName, config, strategyID string, apiID, userID in } //GetAPIPluginList 获取接口插件列表 -func GetAPIPluginList(apiID int, strategyID string) (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *APIPluginDao) GetAPIPluginList(apiID int, strategyID string) (bool, []map[string]interface{}, error) { + db := d.db sql := `SELECT goku_conn_plugin_api.connID,goku_conn_plugin_api.pluginName,IFNULL(goku_conn_plugin_api.createTime,""),IFNULL(goku_conn_plugin_api.updateTime,""),goku_conn_plugin_api.pluginConfig,goku_plugin.pluginPriority, IF(goku_plugin.pluginStatus=0,-1,goku_conn_plugin_api.pluginStatus) as pluginStatus,goku_gateway_api.requestURL FROM goku_conn_plugin_api INNER JOIN goku_plugin ON goku_plugin.pluginName = goku_conn_plugin_api.pluginName INNER goku_gateway_api.apiID = goku_conn_plugin_api.apiID WHERE goku_conn_plugin_api.apiID = ? AND goku_conn_plugin_api.strategyID = ? ORDER BY pluginStatus DESC,goku_conn_plugin_api.updateTime DESC;` rows, err := db.Query(sql, apiID, strategyID) if err != nil { @@ -110,8 +125,8 @@ func GetAPIPluginList(apiID int, strategyID string) (bool, []map[string]interfac } //GetPluginIndex 获取插件优先级 -func GetPluginIndex(pluginName string) (bool, int, error) { - db := database2.GetConnection() +func (d *APIPluginDao) GetPluginIndex(pluginName string) (bool, int, error) { + db := d.db var pluginPriority int sql := "SELECT pluginPriority FROM goku_plugin WHERE pluginName = ?;" err := db.QueryRow(sql, pluginName).Scan(pluginPriority) @@ -122,8 +137,8 @@ func GetPluginIndex(pluginName string) (bool, int, error) { } //GetAPIPluginConfig 通过APIID获取配置信息 -func GetAPIPluginConfig(apiID int, strategyID, pluginName string) (bool, map[string]string, error) { - db := database2.GetConnection() +func (d *APIPluginDao) GetAPIPluginConfig(apiID int, strategyID, pluginName string) (bool, map[string]string, error) { + db := d.db sql := "SELECT goku_gateway_api.apiName,goku_gateway_api.requestURL,goku_conn_plugin_api.pluginConfig FROM goku_conn_plugin_api INNER JOIN goku_gateway_api ON goku_gateway_api.apiID = goku_conn_plugin_api.apiID WHERE goku_conn_plugin_api.apiID = ? AND goku_conn_plugin_api.strategyID = ? AND goku_conn_plugin_api.pluginName = ?;" var p, apiName, requestURL string err := db.QueryRow(sql, apiID, strategyID, pluginName).Scan(&apiName, &requestURL, &p) @@ -142,8 +157,8 @@ func GetAPIPluginConfig(apiID int, strategyID, pluginName string) (bool, map[str } //CheckPluginIsExistInAPI 检查策略组是否绑定插件 -func CheckPluginIsExistInAPI(strategyID, pluginName string, apiID int) (bool, error) { - db := database2.GetConnection() +func (d *APIPluginDao) CheckPluginIsExistInAPI(strategyID, pluginName string, apiID int) (bool, error) { + db := d.db sql := "SELECT apiID FROM goku_conn_plugin_api WHERE strategyID = ? AND pluginName = ? AND apiID = ?;" var id int err := db.QueryRow(sql, strategyID, pluginName, apiID).Scan(&id) @@ -154,8 +169,8 @@ func CheckPluginIsExistInAPI(strategyID, pluginName string, apiID int) (bool, er } // GetAPIPluginInStrategyByAPIID 通过接口ID获取策略组中接口插件列表 -func GetAPIPluginInStrategyByAPIID(strategyID string, apiID int, keyword string, condition int) (bool, []map[string]interface{}, map[string]interface{}, error) { - db := database2.GetConnection() +func (d *APIPluginDao) GetAPIPluginInStrategyByAPIID(strategyID string, apiID int, keyword string, condition int) (bool, []map[string]interface{}, map[string]interface{}, error) { + db := d.db var ( apiName string requestURL string @@ -224,8 +239,8 @@ func GetAPIPluginInStrategyByAPIID(strategyID string, apiID int, keyword string, } //GetAllAPIPluginInStrategy 获取策略组中所有接口插件列表 -func GetAllAPIPluginInStrategy(strategyID string) (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *APIPluginDao) GetAllAPIPluginInStrategy(strategyID string) (bool, []map[string]interface{}, error) { + db := d.db sql := `SELECT goku_conn_plugin_api.connID,goku_conn_plugin_api.apiID,goku_gateway_api.apiName,goku_gateway_api.requestURL,goku_conn_plugin_api.pluginName,IFNULL(goku_conn_plugin_api.createTime,""),IFNULL(goku_conn_plugin_api.updateTime,""),IF(goku_plugin.pluginStatus=0,-1,goku_conn_plugin_api.pluginStatus) as pluginStatus,IFNULL(goku_plugin.pluginDesc,"") FROM goku_conn_plugin_api INNER JOIN goku_gateway_api ON goku_gateway_api.apiID = goku_conn_plugin_api.apiID INNER JOIN goku_plugin ON goku_plugin.pluginName = goku_conn_plugin_api.pluginName WHERE goku_conn_plugin_api.strategyID = ? ORDER BY pluginStatus DESC,goku_conn_plugin_api.updateTime DESC;` rows, err := db.Query(sql, strategyID) if err != nil { @@ -259,8 +274,8 @@ func GetAllAPIPluginInStrategy(strategyID string) (bool, []map[string]interface{ } //BatchEditAPIPluginStatus 批量修改策略组插件状态 -func BatchEditAPIPluginStatus(connIDList, strategyID string, pluginStatus, userID int) (bool, string, error) { - db := database2.GetConnection() +func (d *APIPluginDao) BatchEditAPIPluginStatus(connIDList, strategyID string, pluginStatus, userID int) (bool, string, error) { + db := d.db t := time.Now() now := t.Format("2006-01-02 15:04:05") updateTag := t.Format("20060102150405") @@ -301,8 +316,8 @@ func BatchEditAPIPluginStatus(connIDList, strategyID string, pluginStatus, userI } //BatchDeleteAPIPlugin 批量删除策略组插件 -func BatchDeleteAPIPlugin(connIDList, strategyID string) (bool, string, error) { - db := database2.GetConnection() +func (d *APIPluginDao) BatchDeleteAPIPlugin(connIDList, strategyID string) (bool, string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") Tx, _ := db.Begin() apiIDList := make([]int, 0) @@ -343,8 +358,8 @@ func BatchDeleteAPIPlugin(connIDList, strategyID string) (bool, string, error) { } //GetAPIPluginName 通过connID获取插件名称 -func GetAPIPluginName(connID int) (bool, string, error) { - db := database2.GetConnection() +func (d *APIPluginDao) GetAPIPluginName(connID int) (bool, string, error) { + db := d.db var pluginName string sql := "SELECT pluginName FROM goku_conn_plugin_api WHERE connID = ?" err := db.QueryRow(sql, connID).Scan(&pluginName) @@ -355,8 +370,8 @@ func GetAPIPluginName(connID int) (bool, string, error) { } //CheckAPIPluginIsExistByConnIDList 通过connIDList判断插件是否存在 -func CheckAPIPluginIsExistByConnIDList(connIDList, pluginName string) (bool, []int, error) { - db := database2.GetConnection() +func (d *APIPluginDao) CheckAPIPluginIsExistByConnIDList(connIDList, pluginName string) (bool, []int, error) { + db := d.db sql := "SELECT apiID FROM goku_conn_plugin_api WHERE connID IN (" + connIDList + ") AND pluginName = ?;" rows, err := db.Query(sql, pluginName) if err != nil { @@ -377,8 +392,8 @@ func CheckAPIPluginIsExistByConnIDList(connIDList, pluginName string) (bool, []i } //GetAPIPluginListWithNotAssignAPIList 获取没有绑定嵌套插件列表 -func GetAPIPluginListWithNotAssignAPIList(strategyID string) (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *APIPluginDao) GetAPIPluginListWithNotAssignAPIList(strategyID string) (bool, []map[string]interface{}, error) { + db := d.db sql := "SELECT pluginID,pluginDesc,pluginName FROM goku_plugin WHERE pluginType = 2 AND pluginStatus = 1;" rows, err := db.Query(sql) if err != nil { diff --git a/server/dao/console-sqlite3/apiStrategy.go b/server/dao/console-sqlite3/apiStrategy.go index c85a74c5e5a312f624940068b5fdf4d1a5478c03..7d88c63dc0d954c3c83758772b220f785587eed4 100644 --- a/server/dao/console-sqlite3/apiStrategy.go +++ b/server/dao/console-sqlite3/apiStrategy.go @@ -1,17 +1,35 @@ package console_sqlite3 import ( + "database/sql" "fmt" "strconv" "strings" "time" - database2 "github.com/eolinker/goku-api-gateway/common/database" + "github.com/eolinker/goku-api-gateway/server/dao" ) +//APIStrategyDao APIStrategyDao +type APIStrategyDao struct { + db *sql.DB +} + +//NewAPIStrategyDao new APIStrategyDao +func NewAPIStrategyDao() *APIStrategyDao { + return &APIStrategyDao{} +} + +//Create create +func (d *APIStrategyDao) Create(db *sql.DB) (interface{}, error) { + d.db = db + var i dao.APIStrategyDao = d + return &i, nil +} + //AddAPIToStrategy 将接口加入策略组 -func AddAPIToStrategy(apiList []string, strategyID string) (bool, string, error) { - db := database2.GetConnection() +func (d *APIStrategyDao) AddAPIToStrategy(apiList []string, strategyID string) (bool, string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") sql2 := "SELECT apiID FROM goku_conn_strategy_api WHERE apiID = ? AND strategyID = ?" sql1 := "SELECT apiID FROM goku_gateway_api WHERE apiID = ?" @@ -60,8 +78,8 @@ func AddAPIToStrategy(apiList []string, strategyID string) (bool, string, error) } // SetAPITargetOfStrategy 重定向接口负载 -func SetAPITargetOfStrategy(apiID int, strategyID string, target string) (bool, string, error) { - db := database2.GetConnection() +func (d *APIStrategyDao) SetAPITargetOfStrategy(apiID int, strategyID string, target string) (bool, string, error) { + db := d.db sql := "UPDATE goku_conn_strategy_api SET `target` = ? where apiID = ? AND strategyID = ? " stmt, err := db.Prepare(sql) if err != nil { @@ -78,7 +96,7 @@ func SetAPITargetOfStrategy(apiID int, strategyID string, target string) (bool, } // BatchSetAPITargetOfStrategy 批量重定向接口负载 -func BatchSetAPITargetOfStrategy(apiIds []int, strategyID string, target string) (bool, string, error) { +func (d *APIStrategyDao) BatchSetAPITargetOfStrategy(apiIds []int, strategyID string, target string) (bool, string, error) { idLen := len(apiIds) s := make([]interface{}, 0, idLen+2) c := "" @@ -90,7 +108,7 @@ func BatchSetAPITargetOfStrategy(apiIds []int, strategyID string, target string) } s = append(s, id) } - db := database2.GetConnection() + db := d.db sql := fmt.Sprintf("UPDATE goku_conn_strategy_api SET `target` = ? where strategyID = ? AND apiID IN (%s) ", c) stmt, err := db.Prepare(sql) if err != nil { @@ -106,7 +124,7 @@ func BatchSetAPITargetOfStrategy(apiIds []int, strategyID string, target string) return true, "", nil } -func getAPIOfStrategyRule(condition int, balanceNames []string, ids []int) []string { +func (d *APIStrategyDao) getAPIOfStrategyRule(condition int, balanceNames []string, ids []int) []string { rule := make([]string, 0, 2) switch condition { case 1, 2: @@ -149,7 +167,7 @@ func getAPIOfStrategyRule(condition int, balanceNames []string, ids []int) []str } // GetAPIIDListFromStrategy 获取策略组接口列表 -func GetAPIIDListFromStrategy(strategyID, keyword string, condition int, ids []int, balanceNames []string) (bool, []int, error) { +func (d *APIStrategyDao) GetAPIIDListFromStrategy(strategyID, keyword string, condition int, ids []int, balanceNames []string) (bool, []int, error) { rule := make([]string, 0, 10) rule = append(rule, fmt.Sprintf("S.strategyID = '%s'", strategyID)) @@ -159,14 +177,14 @@ func GetAPIIDListFromStrategy(strategyID, keyword string, condition int, ids []i rule = append(rule, searchRule) } if condition > 0 { - rule = append(rule, getAPIOfStrategyRule(condition, balanceNames, ids)...) + rule = append(rule, d.getAPIOfStrategyRule(condition, balanceNames, ids)...) } ruleStr := "" if len(rule) > 0 { ruleStr += "WHERE " + strings.Join(rule, " AND ") } sql := fmt.Sprintf("SELECT A.`apiID` FROM `goku_gateway_api` A INNER JOIN `goku_conn_strategy_api` S ON S.`apiID` = A.`apiID` %s", ruleStr) - rows, err := database2.GetConnection().Query(sql) + rows, err := d.db.Query(sql) if err != nil { return false, make([]int, 0), err } @@ -186,7 +204,7 @@ func GetAPIIDListFromStrategy(strategyID, keyword string, condition int, ids []i } // GetAPIListFromStrategy 获取策略组接口列表 -func GetAPIListFromStrategy(strategyID, keyword string, condition, page, pageSize int, ids []int, balanceNames []string) (bool, []map[string]interface{}, int, error) { +func (d *APIStrategyDao) GetAPIListFromStrategy(strategyID, keyword string, condition, page, pageSize int, ids []int, balanceNames []string) (bool, []map[string]interface{}, int, error) { rule := make([]string, 0, 2) rule = append(rule, fmt.Sprintf("S.strategyID = '%s'", strategyID)) @@ -196,7 +214,7 @@ func GetAPIListFromStrategy(strategyID, keyword string, condition, page, pageSiz rule = append(rule, searchRule) } if condition > 0 { - rule = append(rule, getAPIOfStrategyRule(condition, balanceNames, ids)...) + rule = append(rule, d.getAPIOfStrategyRule(condition, balanceNames, ids)...) } ruleStr := "" if len(rule) > 0 { @@ -204,8 +222,8 @@ func GetAPIListFromStrategy(strategyID, keyword string, condition, page, pageSiz } sql := fmt.Sprintf("SELECT A.`apiID`, A.`apiName`, A.`requestURL`,A.`requestMethod`,CASE WHEN A.`apiType`=0 THEN A.`targetURL` ELSE '' END,A.apiType,IFNULL(A.`targetMethod`,''), A.`isFollow`, IFNULL(A.`updateTime`,'') AS updateTime, A.`lastUpdateUserID`, A.`managerID`, IFNULL(A.`balanceName`,'') As `target`, IFNULL(S.`target`,'') as `rewriteTarget`, CASE WHEN AD.`remark` is null or AD.`remark` = '' THEN AD.`loginCall` ELSE AD.`remark` END AS managerName, CASE WHEN AD2.`remark` is null or AD2.`remark` = '' THEN AD2.`loginCall` ELSE AD2.`remark` END AS updaterName FROM `goku_gateway_api` A INNER JOIN `goku_conn_strategy_api` S ON S.`apiID` = A.`apiID` LEFT JOIN `goku_admin` AD ON A.`managerID` = AD.`userID` LEFT JOIN `goku_admin` AD2 ON A.`lastUpdateUserID` = AD2.`userID` %s", ruleStr) - count := getCountSQL(sql) - rows, err := getPageSQL(sql, "S.`connID`", "DESC", page, pageSize) + count := getCountSQL(d.db, sql) + rows, err := getPageSQL(d.db, sql, "S.`connID`", "DESC", page, pageSize) if err != nil { return false, make([]map[string]interface{}, 0), 0, err } @@ -242,8 +260,8 @@ func GetAPIListFromStrategy(strategyID, keyword string, condition, page, pageSiz } // CheckIsExistAPIInStrategy 检查插件是否添加进策略组 -func CheckIsExistAPIInStrategy(apiID int, strategyID string) (bool, string, error) { - db := database2.GetConnection() +func (d *APIStrategyDao) CheckIsExistAPIInStrategy(apiID int, strategyID string) (bool, string, error) { + db := d.db var id int sql := "SELECT connID FROM goku_conn_strategy_api WHERE apiID = ? AND strategyID = ?" err := db.QueryRow(sql, apiID, strategyID).Scan(&id) @@ -254,8 +272,8 @@ func CheckIsExistAPIInStrategy(apiID int, strategyID string) (bool, string, erro } // 获取策略绑定的简易接口列表 -func getSimpleAPIListInStrategy(strategyID string, projectID int) map[string]string { - db := database2.GetConnection() +func (d *APIStrategyDao) getSimpleAPIListInStrategy(strategyID string, projectID int) map[string]string { + db := d.db sql := "SELECT goku_gateway_api.requestURL,GROUP_CONCAT(DISTINCT goku_gateway_api.requestMethod) AS requestMethod FROM goku_gateway_api INNER JOIN goku_conn_strategy_api ON goku_gateway_api.apiID = goku_conn_strategy_api.apiID where goku_conn_strategy_api.strategyID = ? AND goku_gateway_api.projectID = ? GROUP BY requestURL" rows, err := db.Query(sql, strategyID, projectID) if err != nil { @@ -275,8 +293,8 @@ func getSimpleAPIListInStrategy(strategyID string, projectID int) map[string]str } // GetAPIIDListNotInStrategy 获取未被该策略组绑定的接口ID列表(通过项目) -func GetAPIIDListNotInStrategy(strategyID string, projectID, groupID int, keyword string) (bool, []int, error) { - requestMap := getSimpleAPIListInStrategy(strategyID, projectID) +func (d *APIStrategyDao) GetAPIIDListNotInStrategy(strategyID string, projectID, groupID int, keyword string) (bool, []int, error) { + requestMap := d.getSimpleAPIListInStrategy(strategyID, projectID) rule := make([]string, 0, 3) rule = append(rule, fmt.Sprintf("A.projectID = %d", projectID)) @@ -286,7 +304,7 @@ func GetAPIIDListNotInStrategy(strategyID string, projectID, groupID int, keywor searchRule += " OR IFNULL(A.balanceName,'') LIKE '%" + keyword + "%' OR A.targetURL LIKE '%" + keyword + "%')" rule = append(rule, searchRule) } - groupRule, err := getAPIGroupRule(projectID, groupID) + groupRule, err := d.getAPIGroupRule(projectID, groupID) if err != nil { return false, make([]int, 0), err } @@ -299,7 +317,7 @@ func GetAPIIDListNotInStrategy(strategyID string, projectID, groupID int, keywor } sql := fmt.Sprintf("SELECT A.apiID,A.requestURL,A.requestMethod FROM goku_gateway_api A %s", ruleStr) - rows, err := database2.GetConnection().Query(sql) + rows, err := d.db.Query(sql) if err != nil { return false, make([]int, 0), err } @@ -323,8 +341,8 @@ func GetAPIIDListNotInStrategy(strategyID string, projectID, groupID int, keywor return true, apiIDList, nil } -func getAPIGroupRule(projectID, groupID int) (string, error) { - db := database2.GetConnection() +func (d *APIStrategyDao) getAPIGroupRule(projectID, groupID int) (string, error) { + db := d.db if groupID < 1 { if groupID == 0 { groupRule := fmt.Sprintf("A.groupID = %d", groupID) @@ -349,8 +367,8 @@ func getAPIGroupRule(projectID, groupID int) (string, error) { } // GetAPIListNotInStrategy 获取未被该策略组绑定的接口列表(通过项目) -func GetAPIListNotInStrategy(strategyID string, projectID, groupID, page, pageSize int, keyword string) (bool, []map[string]interface{}, int, error) { - requestMap := getSimpleAPIListInStrategy(strategyID, projectID) +func (d *APIStrategyDao) GetAPIListNotInStrategy(strategyID string, projectID, groupID, page, pageSize int, keyword string) (bool, []map[string]interface{}, int, error) { + requestMap := d.getSimpleAPIListInStrategy(strategyID, projectID) rule := make([]string, 0, 3) rule = append(rule, fmt.Sprintf("A.projectID = %d", projectID)) @@ -361,7 +379,7 @@ func GetAPIListNotInStrategy(strategyID string, projectID, groupID, page, pageSi rule = append(rule, searchRule) } - groupRule, err := getAPIGroupRule(projectID, groupID) + groupRule, err := d.getAPIGroupRule(projectID, groupID) if err != nil { return false, make([]map[string]interface{}, 0), 0, err } @@ -374,8 +392,8 @@ func GetAPIListNotInStrategy(strategyID string, projectID, groupID, page, pageSi ruleStr += "WHERE " + strings.Join(rule, " AND ") } sql := fmt.Sprintf("SELECT A.apiID,A.apiName,A.requestURL,A.requestMethod,IFNULL(A.balanceName,''),CASE WHEN A.apiType=0 THEN A.targetURL ELSE '' END,A.apiType,IFNULL(A.`targetMethod`,''), A.`isFollow`,A.groupID,IFNULL(G.groupPath,A.groupID) FROM goku_gateway_api A LEFT JOIN goku_gateway_api_group G ON G.groupID = A.groupID %s", ruleStr) - count := getCountSQL(sql) - rows, err := getPageSQL(sql, "A.`updateTime`", "DESC", page, pageSize) + count := getCountSQL(d.db, sql) + rows, err := getPageSQL(d.db, sql, "A.`updateTime`", "DESC", page, pageSize) if err != nil { return false, make([]map[string]interface{}, 0), 0, err } @@ -415,8 +433,8 @@ func GetAPIListNotInStrategy(strategyID string, projectID, groupID, page, pageSi } //BatchDeleteAPIInStrategy 批量删除策略组接口 -func BatchDeleteAPIInStrategy(apiIDList, strategyID string) (bool, string, error) { - db := database2.GetConnection() +func (d *APIStrategyDao) BatchDeleteAPIInStrategy(apiIDList, strategyID string) (bool, string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") Tx, _ := db.Begin() sql := "DELETE FROM goku_conn_strategy_api WHERE strategyID = ? AND apiID IN (" + apiIDList + ")" diff --git a/server/dao/console-sqlite3/auth.go b/server/dao/console-sqlite3/auth.go index 0f42c389327d9758a1c3253d41806dc60046c445..2017a02c73e90be3d5239492aeda2cb3c36e5684 100644 --- a/server/dao/console-sqlite3/auth.go +++ b/server/dao/console-sqlite3/auth.go @@ -1,12 +1,13 @@ package console_sqlite3 import ( + "database/sql" "encoding/json" "time" - log "github.com/eolinker/goku-api-gateway/goku-log" + "github.com/eolinker/goku-api-gateway/server/dao" - database2 "github.com/eolinker/goku-api-gateway/common/database" + log "github.com/eolinker/goku-api-gateway/goku-log" ) type basicAuthConf struct { @@ -66,9 +67,29 @@ type oauth2Credential struct { Remark string `json:"remark"` } +//AuthDao AuthDao +type AuthDao struct { + db *sql.DB +} + +//NewAuthDao new AuthDao +func NewAuthDao() *AuthDao { + return &AuthDao{} +} + +//Create create +func (d *AuthDao) Create(db *sql.DB) (interface{}, error) { + + d.db = db + + var i dao.AuthDao = d + + return &i, nil +} + //GetAuthStatus 获取认证状态 -func GetAuthStatus(strategyID string) (bool, map[string]interface{}, error) { - db := database2.GetConnection() +func (d *AuthDao) GetAuthStatus(strategyID string) (bool, map[string]interface{}, error) { + db := d.db var basicStatus, apikeyStatus int sql := `SELECT CASE WHEN goku_plugin.pluginStatus = 0 THEN 0 ELSE goku_conn_plugin_strategy.pluginStatus END AS pluginStatus FROM goku_conn_plugin_strategy INNER JOIN goku_plugin ON goku_plugin.pluginName = goku_conn_plugin_strategy.pluginName WHERE goku_conn_plugin_strategy.pluginName = ? AND goku_conn_plugin_strategy.strategyID = ?;` db.QueryRow(sql, "goku-basic_auth", strategyID).Scan(&basicStatus) @@ -85,8 +106,8 @@ func GetAuthStatus(strategyID string) (bool, map[string]interface{}, error) { } //GetAuthInfo 获取认证信息 -func GetAuthInfo(strategyID string) (bool, map[string]interface{}, error) { - db := database2.GetConnection() +func (d *AuthDao) GetAuthInfo(strategyID string) (bool, map[string]interface{}, error) { + db := d.db var strategyName, auth string sql := "SELECT IFNULL(auth,''),strategyName FROM goku_gateway_strategy WHERE strategyID = ?;" err := db.QueryRow(sql, strategyID).Scan(&auth, &strategyName) @@ -132,8 +153,8 @@ func GetAuthInfo(strategyID string) (bool, map[string]interface{}, error) { } //EditAuthInfo 编辑认证信息 -func EditAuthInfo(strategyID, strategyName, basicAuthList, apikeyList, jwtCredentialList, oauth2CredentialList string, delClientIDList []string) (bool, error) { - db := database2.GetConnection() +func (d *AuthDao) EditAuthInfo(strategyID, strategyName, basicAuthList, apikeyList, jwtCredentialList, oauth2CredentialList string, delClientIDList []string) (bool, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") sql := "UPDATE goku_gateway_strategy SET strategyName = ? WHERE strategyID = ?;" stmt, err := db.Prepare(sql) diff --git a/server/dao/console-sqlite3/cluster.go b/server/dao/console-sqlite3/cluster.go index cc5684e598a157d74ebb2b7c90c6df1f529cd4c4..afd9f22f3767d2300d2323449c938fd17bff3dd0 100644 --- a/server/dao/console-sqlite3/cluster.go +++ b/server/dao/console-sqlite3/cluster.go @@ -1,13 +1,35 @@ package console_sqlite3 import ( - "github.com/eolinker/goku-api-gateway/common/database" + "database/sql" + + "github.com/eolinker/goku-api-gateway/server/dao" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +//ClusterDao ClusterDao +type ClusterDao struct { + db *sql.DB +} + +//NewClusterDao new ClusterDao +func NewClusterDao() *ClusterDao { + return &ClusterDao{} +} + +//Create create +func (d *ClusterDao) Create(db *sql.DB) (interface{}, error) { + + d.db = db + + var i dao.ClusterDao = d + + return &i, nil +} + //AddCluster 新增集群 -func AddCluster(name, title, note string) error { - db := database.GetConnection() +func (d *ClusterDao) AddCluster(name, title, note string) error { + db := d.db sql := "INSERT INTO goku_cluster (`name`,`title`,`note`) VALUES (?,?,?)" stmt, err := db.Prepare(sql) if err != nil { @@ -19,8 +41,8 @@ func AddCluster(name, title, note string) error { } //EditCluster 修改集群信息 -func EditCluster(name, title, note string) error { - db := database.GetConnection() +func (d *ClusterDao) EditCluster(name, title, note string) error { + db := d.db sql := "UPDATE goku_cluster SET `title` = ?,`note` = ? WHERE `name` = ?" stmt, err := db.Prepare(sql) if err != nil { @@ -32,8 +54,8 @@ func EditCluster(name, title, note string) error { } //DeleteCluster 删除集群 -func DeleteCluster(name string) error { - db := database.GetConnection() +func (d *ClusterDao) DeleteCluster(name string) error { + db := d.db sql := "DELETE FROM goku_cluster WHERE `name` = ?" stmt, err := db.Prepare(sql) if err != nil { @@ -45,8 +67,8 @@ func DeleteCluster(name string) error { } //GetClusterCount 获取集群数量 -func GetClusterCount() int { - db := database.GetConnection() +func (d *ClusterDao) GetClusterCount() int { + db := d.db var count int sql := "SELECT COUNT(*) FROM goku_cluster;" err := db.QueryRow(sql).Scan(&count) @@ -57,8 +79,8 @@ func GetClusterCount() int { } //GetClusterNodeCount 获取集群节点数量 -func GetClusterNodeCount(name string) int { - db := database.GetConnection() +func (d *ClusterDao) GetClusterNodeCount(name string) int { + db := d.db var count int sql := "SELECT COUNT(*) FROM goku_node_info INNER JOIN goku_cluster ON goku_node_info.clusterID = goku_clutser.id WHERE goku_clutser.`name` = ?;" err := db.QueryRow(sql, name).Scan(&count) @@ -69,8 +91,8 @@ func GetClusterNodeCount(name string) int { } //GetClusterIDByName 通过集群名称获取集群ID -func GetClusterIDByName(name string) int { - db := database.GetConnection() +func (d *ClusterDao) GetClusterIDByName(name string) int { + db := d.db var id int sql := "SELECT `id` FROM goku_cluster WHERE `name` = ?" err := db.QueryRow(sql, name).Scan(&id) @@ -80,9 +102,21 @@ func GetClusterIDByName(name string) int { return id } +//GetClusterByID 获取集群信息 +func (d *ClusterDao) GetClusterByID(id int) (*entity.Cluster, error) { + db := d.db + sql := "SELECT `id`,`name`,`title`,`note` FROM goku_cluster WHERE `id` = ?" + var cluster entity.Cluster + err := db.QueryRow(sql, id).Scan(&cluster.ID, &cluster.Name, &cluster.Title, &cluster.Note) + if err != nil { + return nil, err + } + return &cluster, nil +} + //GetClusters 获取集群列表 -func GetClusters() ([]*entity.Cluster, error) { - db := database.GetConnection() +func (d *ClusterDao) GetClusters() ([]*entity.Cluster, error) { + db := d.db sql := "SELECT `id`,`name`,`title`,`note`,count(I.`nodeID`) as num FROM `goku_cluster` C left join `goku_node_info` I on c.id = I.`clusterID` group by `id`,`name`,`title`,`note`;" rows, err := db.Query(sql) if err != nil { @@ -92,7 +126,7 @@ func GetClusters() ([]*entity.Cluster, error) { defer rows.Close() for rows.Next() { var cluster entity.Cluster - err = rows.Scan(&cluster.ID, &cluster.Name, &cluster.Title, &cluster.Note,&cluster.NodeCount) + err = rows.Scan(&cluster.ID, &cluster.Name, &cluster.Title, &cluster.Note, &cluster.NodeCount) if err != nil { return []*entity.Cluster{}, err } @@ -102,8 +136,8 @@ func GetClusters() ([]*entity.Cluster, error) { } //GetCluster 获取集群信息 -func GetCluster(name string) (*entity.Cluster, error) { - db := database.GetConnection() +func (d *ClusterDao) GetCluster(name string) (*entity.Cluster, error) { + db := d.db sql := "SELECT `id`,`name`,`title`,`note` FROM goku_cluster WHERE `name` = ?" var cluster entity.Cluster err := db.QueryRow(sql, name).Scan(&cluster.ID, &cluster.Name, &cluster.Title, &cluster.Note) @@ -114,8 +148,8 @@ func GetCluster(name string) (*entity.Cluster, error) { } //CheckClusterNameIsExist 判断集群名称是否存在 -func CheckClusterNameIsExist(name string) bool { - db := database.GetConnection() +func (d *ClusterDao) CheckClusterNameIsExist(name string) bool { + db := d.db sql := "SELECT `name` FROM goku_cluster WHERE `name` = ?" var clusterName string err := db.QueryRow(sql, name).Scan(&clusterName) diff --git a/server/dao/console-sqlite3/config-log/log.go b/server/dao/console-sqlite3/config-log/log.go index 805517a697e01b6b970996cde538593c07489b53..269dbc8d1e2cf4de2ef01f08e7b6f00e71729aaa 100644 --- a/server/dao/console-sqlite3/config-log/log.go +++ b/server/dao/console-sqlite3/config-log/log.go @@ -1,16 +1,35 @@ package config_log import ( - "github.com/eolinker/goku-api-gateway/common/database" + "database/sql" + + "github.com/eolinker/goku-api-gateway/server/dao" entity "github.com/eolinker/goku-api-gateway/server/entity/config-log" ) const sqlSelect = "SELECT `name`,`enable`,`dir`,`file`,`level`,`period`,`expire`,`fields` FROM `goku_config_log` WHERE `name` = ? LIMIT 1;" const sqlInsert = "REPLACE INTO `goku_config_log`(`name`,`enable`,`dir`,`file`,`level`,`period`,`expire`,`fields`)VALUES(?,?,?,?,?,?,?,?);" +//ConfigLogDao ConfigLogDao +type ConfigLogDao struct { + db *sql.DB +} + +//NewConfigLogDao new ConfigLogDao +func NewConfigLogDao() *ConfigLogDao { + return &ConfigLogDao{} +} + +//Create create +func (d *ConfigLogDao) Create(db *sql.DB) (interface{}, error) { + d.db = db + var i dao.ConfigLogDao = d + return &i, nil +} + //Get get -func Get(name string) (*entity.LogConfig, error) { - stmt, e := database.GetConnection().Prepare(sqlSelect) +func (d *ConfigLogDao) Get(name string) (*entity.LogConfig, error) { + stmt, e := d.db.Prepare(sqlSelect) if e != nil { return nil, e } @@ -33,8 +52,8 @@ func Get(name string) (*entity.LogConfig, error) { } //Set set -func Set(ent *entity.LogConfig) error { - stmt, e := database.GetConnection().Prepare(sqlInsert) +func (d *ConfigLogDao) Set(ent *entity.LogConfig) error { + stmt, e := d.db.Prepare(sqlInsert) if e != nil { return e } diff --git a/server/dao/console-sqlite3/dao-balance-update/update.go b/server/dao/console-sqlite3/dao-balance-update/update.go index 8ff0b881f488eae4a3309b7d57f5d3f25af78dd8..1ffd9576efdf17be7546ddcae6a6723aa7ad5e00 100644 --- a/server/dao/console-sqlite3/dao-balance-update/update.go +++ b/server/dao/console-sqlite3/dao-balance-update/update.go @@ -1,15 +1,40 @@ package dao_balance_update import ( - "github.com/eolinker/goku-api-gateway/common/database" - dao_service2 "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-service" + "database/sql" + + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao" entity "github.com/eolinker/goku-api-gateway/server/entity/balance-entity" ) +var serviceDao dao.ServiceDao + +func init() { + pdao.Need(&serviceDao) +} + +//BalanceUpdateDao BalanceUpdateDao +type BalanceUpdateDao struct { + db *sql.DB +} + +//NewBalanceUpdateDao new BalanceUpdateDao +func NewBalanceUpdateDao() *BalanceUpdateDao { + return &BalanceUpdateDao{} +} + +//Create create +func (d *BalanceUpdateDao) Create(db *sql.DB) (interface{}, error) { + d.db = db + i := dao.BalanceUpdateDao(d) + return &i, nil +} + //GetAllOldVerSion 获取所有旧负载配置 -func GetAllOldVerSion() ([]*entity.BalanceInfoEntity, error) { +func (d *BalanceUpdateDao) GetAllOldVerSion() ([]*entity.BalanceInfoEntity, error) { const sql = "SELECT `balanceName`,IFNULL(`balanceDesc`, ''),IFNULL(`balanceConfig`, ''),IFNULL(`defaultConfig`, ''),IFNULL(`clusterConfig`, ''),`updateTime`,`createTime` FROM `goku_balance` WHERE `serviceName` = '';" - db := database.GetConnection() + db := d.db rows, err := db.Query(sql) if err != nil { return nil, err @@ -30,14 +55,14 @@ func GetAllOldVerSion() ([]*entity.BalanceInfoEntity, error) { } //GetDefaultServiceStatic 获取默认静态负载 -func GetDefaultServiceStatic() string { +func (d *BalanceUpdateDao) GetDefaultServiceStatic() string { - tx := database.GetConnection() + tx := d.db name := "" err := tx.QueryRow("SELECT `name` FROM `goku_service_config` WHERE `driver`='static' ORDER BY `default` DESC LIMIT 1; ").Scan(&name) if err != nil { name = "static" - dao_service2.Add(name, "static", "默认静态服务", "", "", false, false, "", "", 5, 300) + serviceDao.Add(name, "static", "默认静态服务", "", "", false, false, "", "", 5, 300) } return name diff --git a/server/dao/console-sqlite3/dao-balance/add.go b/server/dao/console-sqlite3/dao-balance/add.go index 2c07e8191a58812447ee5908dc0e151d9d9c4985..93c4ed124c022b406d3a236e6652fdd51739b6ec 100644 --- a/server/dao/console-sqlite3/dao-balance/add.go +++ b/server/dao/console-sqlite3/dao-balance/add.go @@ -1,33 +1,11 @@ package dao_balance -import ( - "github.com/eolinker/goku-api-gateway/common/database" -) - -//Add add -func Add(name, serviceName, desc, appName, static, staticCluster, now string) (string, error) { - - //const sql = "INSERT INTO goku_balance (`balanceName`,`serviceName`,`appName`,`balanceDesc`,`static`,`staticCluster`,`createTime`,`updateTime`) VALUES (?,?,?,?,?,?,?,?,);" - // - //db := database.GetConnection() - //stmt, err := db.Prepare(sql) - //if err != nil { - // return "[ERROR]Illegal SQL statement!", err - //} - //defer stmt.Close() - //_, err = stmt.Exec(name,serviceName,appName, desc, static, staticCluster, now, now) - //if err != nil { - // return "[ERROR]Failed to add data!", err - //} - return "", nil -} - //AddStatic 新增静态负载 -func AddStatic(name, serviceName, static, staticCluster, desc, now string) (string, error) { +func (b *BalanceDao) AddStatic(name, serviceName, static, staticCluster, desc, now string) (string, error) { const sql = "INSERT INTO goku_balance (`balanceName`,`serviceName`,`static`,`staticCluster`,`balanceDesc`,`createTime`,`updateTime`,`appName`,`defaultConfig`,`clusterConfig`,`balanceConfig`) VALUES (?,?,?,?,?,?,?,'','','','');" - db := database.GetConnection() + db := b.db stmt, err := db.Prepare(sql) if err != nil { return "[ERROR]Illegal SQL statement!", err @@ -41,11 +19,11 @@ func AddStatic(name, serviceName, static, staticCluster, desc, now string) (stri } //AddDiscovery 新增服务发现 -func AddDiscovery(name, serviceName, appName, desc, now string) (string, error) { +func (b *BalanceDao) AddDiscovery(name, serviceName, appName, desc, now string) (string, error) { const sql = "INSERT INTO goku_balance (`balanceName`,`serviceName`,`appName`,`balanceDesc`,`createTime`,`updateTime`,`static`,`staticCluster`,`defaultConfig`,`clusterConfig`,`balanceConfig`) VALUES (?,?,?,?,?,?,'','','','','');" - db := database.GetConnection() + db := b.db stmt, err := db.Prepare(sql) if err != nil { return "[ERROR]Illegal SQL statement!", err @@ -59,9 +37,9 @@ func AddDiscovery(name, serviceName, appName, desc, now string) (string, error) } //SaveStatic 保存静态负载信息 -func SaveStatic(name, serviceName, static, staticCluster, desc string, now string) (string, error) { +func (b *BalanceDao) SaveStatic(name, serviceName, static, staticCluster, desc string, now string) (string, error) { const sql = "UPDATE `goku_balance` SET `serviceName`=? ,`static` = ?,`staticCluster`=?,`balanceDesc` =?,`updateTime`=? WHERE `balanceName`=?;" - db := database.GetConnection() + db := b.db stmt, err := db.Prepare(sql) if err != nil { return "[ERROR]Illegal SQL statement!", err @@ -75,9 +53,9 @@ func SaveStatic(name, serviceName, static, staticCluster, desc string, now strin } //SaveDiscover 保存服务发现信息 -func SaveDiscover(name, serviceName, appName, desc string, now string) (string, error) { +func (b *BalanceDao) SaveDiscover(name, serviceName, appName, desc string, now string) (string, error) { const sql = "UPDATE `goku_balance` SET `serviceName`=? ,`appName` = ?,`balanceDesc` =?,`updateTime`=? WHERE `balanceName`=?;" - db := database.GetConnection() + db := b.db stmt, err := db.Prepare(sql) if err != nil { return "[ERROR]Illegal SQL statement!", err @@ -90,27 +68,10 @@ func SaveDiscover(name, serviceName, appName, desc string, now string) (string, return "", nil } -//Save save -func Save(name, desc, static, staticCluster, now string) (string, error) { - //const sql = "UPDATE `goku_balance` SET `balanceDesc` = ?,`static` =?,`staticCluster`=?,`updateTime`=? WHERE `balanceName` = ?;" - // - //db := database.GetConnection() - //stmt, err := db.Prepare(sql) - //if err != nil { - // return "[ERROR]Illegal SQL statement!", err - //} - //defer stmt.Close() - //_, err = stmt.Exec(desc, defaultConfig, clusterConfig, now, name) - //if err != nil { - // return "[ERROR]Failed to add data!", err - //} - return "", nil -} - //Delete 删除负载 -func Delete(name string) (string, error) { +func (b *BalanceDao) Delete(name string) (string, error) { const sql = "DELETE FROM `goku_balance` WHERE `balanceName`= ?;" - db := database.GetConnection() + db := b.db stmt, err := db.Prepare(sql) if err != nil { return "[ERROR]Illegal SQL statement!", err @@ -121,12 +82,11 @@ func Delete(name string) (string, error) { return "[ERROR]DELETE fail", err } return "", nil - } //BatchDelete 批量删除负载 -func BatchDelete(balanceNames []string) (string, error) { - db := database.GetConnection() +func (b *BalanceDao) BatchDelete(balanceNames []string) (string, error) { + db := b.db sql := "DELETE FROM `goku_balance` WHERE `balanceName` = ?;" sql2 := "UPDATE goku_conn_strategy_api SET target = '' WHERE target = ?" stmt, err := db.Prepare(sql) diff --git a/server/dao/console-sqlite3/dao-balance/balance.go b/server/dao/console-sqlite3/dao-balance/balance.go index 61f1f8e5181bc248d7c562857e0740a810241dbc..59c2d14c69cf5a36971baff7502a652402fe27cb 100644 --- a/server/dao/console-sqlite3/dao-balance/balance.go +++ b/server/dao/console-sqlite3/dao-balance/balance.go @@ -1,33 +1,24 @@ package dao_balance import ( - "github.com/eolinker/goku-api-gateway/common/database" -) + "database/sql" -//GetBalanceNames 获取负载名称列表 -func GetBalanceNames() (bool, []string, error) { - db := database.GetConnection() - sql := "SELECT balanceName FROM goku_balance ;" + dao "github.com/eolinker/goku-api-gateway/server/dao" +) - rows, err := db.Query(sql) - if err != nil { - return false, nil, err - } - defer rows.Close() - //获取记录列 +//BalanceDao BalanceDao +type BalanceDao struct { + db *sql.DB +} - if _, err = rows.Columns(); err != nil { - return false, nil, err - } - balanceList := make([]string, 0) - for rows.Next() { - balanceName := "" - err = rows.Scan(&balanceName) - if err != nil { - return false, nil, err - } - balanceList = append(balanceList, balanceName) - } - return true, balanceList, nil +//NewBalanceDao new BalanceDao +func NewBalanceDao() *BalanceDao { + return &BalanceDao{} +} +//Create create +func (b *BalanceDao) Create(db *sql.DB) (interface{}, error) { + b.db = db + i := dao.BalanceDao(b) + return &i, nil } diff --git a/server/dao/console-sqlite3/dao-balance/get.go b/server/dao/console-sqlite3/dao-balance/get.go index c7d2dd540b4c033b9b1681e9c5adc8002af90d33..006e8f532452264f350ff1d05485d1f892762d8e 100644 --- a/server/dao/console-sqlite3/dao-balance/get.go +++ b/server/dao/console-sqlite3/dao-balance/get.go @@ -1,17 +1,45 @@ package dao_balance import ( + sql2 "database/sql" "fmt" "strings" - "github.com/eolinker/goku-api-gateway/common/database" entity "github.com/eolinker/goku-api-gateway/server/entity/balance-entity-service" ) +//GetBalanceNames 获取负载名称列表 +func (b *BalanceDao) GetBalanceNames() (bool, []string, error) { + db := b.db + sql := "SELECT balanceName FROM goku_balance ;" + + rows, err := db.Query(sql) + if err != nil { + return false, nil, err + } + defer rows.Close() + //获取记录列 + + if _, err = rows.Columns(); err != nil { + return false, nil, err + } + balanceList := make([]string, 0) + for rows.Next() { + balanceName := "" + err = rows.Scan(&balanceName) + if err != nil { + return false, nil, err + } + balanceList = append(balanceList, balanceName) + } + return true, balanceList, nil + +} + //Get 根据负载名获取负载配置 -func Get(name string) (*entity.Balance, error) { +func (b *BalanceDao) Get(name string) (*entity.Balance, error) { const sql = "SELECT A.`balanceName`,A.`serviceName`,IFNULL(B.`driver`,''),A.`appName`,IFNULL(A.`static`,''),IFNULL(A.`staticCluster`,''),A.`balanceDesc`,A.`updateTime`,A.`createTime` FROM `goku_balance` A LEFT JOIN `goku_service_config` B ON A.`serviceName` = B.`NAME` WHERE A.`balanceName`= ?;" - db := database.GetConnection() + db := b.db v := new(entity.Balance) err := db.QueryRow(sql, name).Scan(&v.Name, &v.ServiceName, &v.ServiceDriver, &v.AppName, &v.Static, &v.StaticCluster, &v.Desc, &v.UpdateTime, &v.CreateTime) if err != nil { @@ -22,9 +50,9 @@ func Get(name string) (*entity.Balance, error) { } //GetAll 获取所有负载配置 -func GetAll() ([]*entity.Balance, error) { +func (b *BalanceDao) GetAll() ([]*entity.Balance, error) { const sql = "SELECT A.`balanceName`,A.`serviceName`,IFNULL(B.`driver`,''),A.`appName`,IFNULL(A.`static`,''),IFNULL(A.`staticCluster`,''),A.`balanceDesc`,A.`updateTime`,A.`createTime` FROM `goku_balance` A LEFT JOIN `goku_service_config` B ON A.`serviceName` = B.`name` ORDER BY A.`updateTime` DESC;" - db := database.GetConnection() + db := b.db rows, err := db.Query(sql) if err != nil { return nil, err @@ -44,7 +72,7 @@ func GetAll() ([]*entity.Balance, error) { } //Search 关键字获取负载列表 -func Search(keyword string) ([]*entity.Balance, error) { +func (b *BalanceDao) Search(keyword string) ([]*entity.Balance, error) { const sqlTpl = "SELECT A.`balanceName`,A.`serviceName`,IFNULL(B.`driver`,''),A.`appName`,IFNULL(A.`static`,''),IFNULL(A.`staticCluster`,''),A.`balanceDesc`,A.`updateTime`,A.`createTime` FROM `goku_balance` A LEFT JOIN `goku_service_config` B ON A.`serviceName` = B.`name` %s ORDER BY `updateTime` DESC;" where := "" @@ -56,7 +84,7 @@ func Search(keyword string) ([]*entity.Balance, error) { args = append(args, kp, kp, kp) } sql := fmt.Sprintf(sqlTpl, where) - db := database.GetConnection() + db := b.db rows, err := db.Query(sql, args...) if err != nil { return nil, err @@ -74,3 +102,31 @@ func Search(keyword string) ([]*entity.Balance, error) { } return r, nil } + +//GetUseBalanceNames 获取使用的负载名称列表 +func (b *BalanceDao) GetUseBalanceNames() (map[string]int, error) { + const sql = "SELECT `balanceName` as `name` FROM goku_gateway_api UNION SELECT `target` as `name` FROM goku_conn_strategy_api;" + db := b.db + rows, err := db.Query(sql) + if err != nil { + return nil, err + } + defer rows.Close() + + r := make(map[string]int) + for rows.Next() { + var balanceName sql2.NullString + err := rows.Scan(&balanceName) + if err != nil { + return nil, err + } + if balanceName.Valid == false || balanceName.String == "" { + continue + } + if _, ok := r[balanceName.String]; !ok { + r[balanceName.String] = 0 + } + r[balanceName.String] = r[balanceName.String] + 1 + } + return r, nil +} diff --git a/server/dao/console-sqlite3/dao-service/add.go b/server/dao/console-sqlite3/dao-service/add.go index c5d117106759f78aad8739c3dcf70041f763eb4c..2cfcfa30c106221714b3c16d175f130412e110dc 100644 --- a/server/dao/console-sqlite3/dao-service/add.go +++ b/server/dao/console-sqlite3/dao-service/add.go @@ -2,22 +2,21 @@ package dao_service import ( "time" - - "github.com/eolinker/goku-api-gateway/common/database" ) const sqlAdd = "INSERT INTO `goku_service_config`(`name`,`driver`,`default`,`desc`,`config`,`clusterConfig`,`healthCheck`,`healthCheckPath`,`healthCheckPeriod`,`healthCheckCode`,`healthCheckTimeOut`,`createTime`,`updateTime`)VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?);" //Add 新增服务 -func Add(name, driver, desc, config, clusterConfig string, isDefault, healthCheck bool, healthCheckPath string, healthCheckCode string, healthCheckPeriod, healthCheckTimeOut int) error { +func (d *ServiceDao) Add(name, driver, desc, config, clusterConfig string, isDefault, healthCheck bool, healthCheckPath string, healthCheckCode string, healthCheckPeriod, healthCheckTimeOut int) error { now := time.Now().Format("2006-01-02 15:04:05") - stmt, e := database.GetConnection().Prepare(sqlAdd) + stmt, e := d.db.Prepare(sqlAdd) if e != nil { return e } defer stmt.Close() + _, err := stmt.Exec(name, driver, isDefault, desc, config, clusterConfig, healthCheck, healthCheckPath, healthCheckPeriod, healthCheckCode, healthCheckTimeOut, now, now) return err } diff --git a/server/dao/console-sqlite3/dao-service/dao.go b/server/dao/console-sqlite3/dao-service/dao.go new file mode 100644 index 0000000000000000000000000000000000000000..e8e34e4e8ad409e23e0ee0f5bdfa09860db1656c --- /dev/null +++ b/server/dao/console-sqlite3/dao-service/dao.go @@ -0,0 +1,24 @@ +package dao_service + +import ( + "database/sql" + + "github.com/eolinker/goku-api-gateway/server/dao" +) + +//ServiceDao ServiceDao +type ServiceDao struct { + db *sql.DB +} + +//NewServiceDao new ServiceDao +func NewServiceDao() *ServiceDao { + return &ServiceDao{} +} + +//Create create +func (d *ServiceDao) Create(db *sql.DB) (interface{}, error) { + d.db = db + i := dao.ServiceDao(d) + return &i, nil +} diff --git a/server/dao/console-sqlite3/dao-service/default.go b/server/dao/console-sqlite3/dao-service/default.go index edcf25a36fc3bde6af1678e227676cdeda06985b..af67b00928a3623b7239f8ae61ef55ca57bf6b58 100644 --- a/server/dao/console-sqlite3/dao-service/default.go +++ b/server/dao/console-sqlite3/dao-service/default.go @@ -2,14 +2,12 @@ package dao_service import ( "fmt" - - "github.com/eolinker/goku-api-gateway/common/database" ) //SetDefault 设置默认服务 -func SetDefault(name string) error { +func (d *ServiceDao) SetDefault(name string) error { count := 0 - err := database.GetConnection().QueryRow("SELECT count(1) FROM `goku_service_config` WHERE `name` = ?;", name).Scan(&count) + err := d.db.QueryRow("SELECT count(1) FROM `goku_service_config` WHERE `name` = ?;", name).Scan(&count) if err != nil { return err @@ -18,7 +16,7 @@ func SetDefault(name string) error { return fmt.Errorf("has no name=%s", name) } - tx, e := database.GetConnection().Begin() + tx, e := d.db.Begin() if e != nil { return e } diff --git a/server/dao/console-sqlite3/dao-service/delete.go b/server/dao/console-sqlite3/dao-service/delete.go index e17fef74e3df520df7504566e76bcaa417468bf7..baf0e2f3e7b46850a46f6f21cfbb0054735e142c 100644 --- a/server/dao/console-sqlite3/dao-service/delete.go +++ b/server/dao/console-sqlite3/dao-service/delete.go @@ -2,8 +2,6 @@ package dao_service import ( "fmt" - - "github.com/eolinker/goku-api-gateway/common/database" ) const sqlDelete = "DELETE FROM `goku_service_config` WHERE `name` = ? AND NOT EXISTS (SELECT * FROM `goku_balance` B WHERE B.`serviceName` = `goku_service_config`.`name` ) " @@ -16,16 +14,15 @@ func (e DeleteError) Error() string { } //Delete 删除服务发现 -func Delete(names []string) error { +func (d *ServiceDao) Delete(names []string) error { - tx, err := database.GetConnection().Begin() + tx, err := d.db.Begin() if err != nil { return err } stmt, e := tx.Prepare(sqlDelete) if e != nil { - return e } diff --git a/server/dao/console-sqlite3/dao-service/get.go b/server/dao/console-sqlite3/dao-service/get.go index ddff8f963748b4d655e66fc8afae0e7f224c1ee3..3f661df0af102897f6ee7d031999eade458d84f2 100644 --- a/server/dao/console-sqlite3/dao-service/get.go +++ b/server/dao/console-sqlite3/dao-service/get.go @@ -3,16 +3,15 @@ package dao_service import ( "fmt" - "github.com/eolinker/goku-api-gateway/common/database" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) const sqlGet = "SELECT `name`,`driver`,`default`,`desc`,`config`,`clusterConfig`,`healthCheck`,`healthCheckPath`,`healthCheckPeriod`,`healthCheckCode`,`healthCheckTimeOut`,`createTime`,`updateTime` FROM `goku_service_config` WHERE `name`=?; " //Get 获取服务发现信息 -func Get(name string) (*entity.Service, error) { +func (d *ServiceDao) Get(name string) (*entity.Service, error) { - stmt, e := database.GetConnection().Prepare(sqlGet) + stmt, e := d.db.Prepare(sqlGet) if e != nil { return nil, e } diff --git a/server/dao/console-sqlite3/dao-service/list.go b/server/dao/console-sqlite3/dao-service/list.go index cc434ac500a191ad3aa9aa63f48641ba4263f4a4..d50a1e42f8f390058b4cca335a3c4715b8ac79cc 100644 --- a/server/dao/console-sqlite3/dao-service/list.go +++ b/server/dao/console-sqlite3/dao-service/list.go @@ -3,21 +3,20 @@ package dao_service import ( "fmt" - "github.com/eolinker/goku-api-gateway/common/database" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) const sqlList = "SELECT `name`,`driver`,`default`,`desc`,`config`,`clusterConfig`,`healthCheck`,`healthCheckPath`,`healthCheckPeriod`,`healthCheckCode`,`healthCheckTimeOut`,`createTime`,`updateTime` FROM `goku_service_config` %s ORDER BY `updateTime` DESC;" //List 获取服务发现列表 -func List(keyword string) ([]*entity.Service, error) { +func (d *ServiceDao) List(keyword string) ([]*entity.Service, error) { where := "" if keyword != "" { where = fmt.Sprint("where `name` like '%", keyword, "%' OR `driver` like '%", keyword, "%'") } sql := fmt.Sprintf(sqlList, where) - stmt, e := database.GetConnection().Prepare(sql) + stmt, e := d.db.Prepare(sql) if e != nil { return nil, e } diff --git a/server/dao/console-sqlite3/dao-service/save.go b/server/dao/console-sqlite3/dao-service/save.go index ad54a28288ef63d5fbeccd796b2a6fddd8ca6dbf..28b7d873f11437b4b59d0b6bdc1f2c321d057ffc 100644 --- a/server/dao/console-sqlite3/dao-service/save.go +++ b/server/dao/console-sqlite3/dao-service/save.go @@ -2,21 +2,19 @@ package dao_service import ( "time" - - "github.com/eolinker/goku-api-gateway/common/database" ) const sqlSave = "UPDATE `goku_service_config` SET `desc`=?,`config`=?,`clusterConfig`=?,`healthCheck`=?,`healthCheckPath`=?,`healthCheckPeriod`=?,`healthCheckCode`=?,`healthCheckTimeOut`=?,`updateTime`=? WHERE `name`=?;" //Save 存储服务发现信息 -func Save(name, desc, config, clusterConfig string, healthCheck bool, healthCheckPath string, healthCheckCode string, healthCheckPeriod, healthCheckTimeOut int) error { +func (d *ServiceDao) Save(name, desc, config, clusterConfig string, healthCheck bool, healthCheckPath string, healthCheckCode string, healthCheckPeriod, healthCheckTimeOut int) error { now := time.Now().Format("2006-01-02 15:04:05") - stmt, e := database.GetConnection().Prepare(sqlSave) + stmt, e := d.db.Prepare(sqlSave) if e != nil { return e } - + defer stmt.Close() _, err := stmt.Exec(desc, config, clusterConfig, healthCheck, healthCheckPath, healthCheckPeriod, healthCheckCode, healthCheckTimeOut, now, name) return err } diff --git a/server/dao/console-sqlite3/dao-version-config/api.go b/server/dao/console-sqlite3/dao-version-config/api.go index 28e5629fec7a743cada0be642833e97d51a7011d..1177b3e29d84de229236dc70a4f23e4abb6942e0 100644 --- a/server/dao/console-sqlite3/dao-version-config/api.go +++ b/server/dao/console-sqlite3/dao-version-config/api.go @@ -4,13 +4,12 @@ import ( "encoding/json" "strings" - "github.com/eolinker/goku-api-gateway/common/database" "github.com/eolinker/goku-api-gateway/config" ) //GetAPIContent 获取接口信息 -func GetAPIContent() ([]*config.APIContent, error) { - db := database.GetConnection() +func (d *VersionConfigDao)GetAPIContent() ([]*config.APIContent, error) { + db := d.db sql := "SELECT apiID,apiName,IFNULL(protocol,'http'),IFNULL(balanceName,''),IFNULL(targetURL,''),CASE WHEN isFollow = 'true' THEN 'FOLLOW' ELSE targetMethod END targetMethod,responseDataType,requestURL,requestMethod,timeout,alertValve,retryCount,IFNULL(linkApis,''),IFNULL(staticResponse,'') FROM goku_gateway_api" rows, err := db.Query(sql) if err != nil { diff --git a/server/dao/console-sqlite3/dao-version-config/balance.go b/server/dao/console-sqlite3/dao-version-config/balance.go index 873e5a50103e7f12a346ef05d29d700b4dad35df..0ddf50a96a096ccc1510667e3ab6a85945b38a91 100644 --- a/server/dao/console-sqlite3/dao-version-config/balance.go +++ b/server/dao/console-sqlite3/dao-version-config/balance.go @@ -3,14 +3,13 @@ package dao_version_config import ( "encoding/json" - "github.com/eolinker/goku-api-gateway/common/database" "github.com/eolinker/goku-api-gateway/config" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) //GetBalances 获取balance信息 -func GetBalances(clusters []*entity.Cluster) (map[string]map[string]*config.BalanceConfig, error) { - db := database.GetConnection() +func (d *VersionConfigDao)GetBalances(clusters []*entity.Cluster) (map[string]map[string]*config.BalanceConfig, error) { + db := d.db sql := "SELECT goku_balance.balanceName,goku_balance.static,goku_balance.staticCluster,goku_balance.serviceName,goku_balance.appName,goku_service_config.driver FROM goku_balance INNER JOIN goku_service_config ON goku_service_config.`name` = goku_balance.serviceName" rows, err := db.Query(sql) if err != nil { diff --git a/server/dao/console-sqlite3/dao-version-config/dao.go b/server/dao/console-sqlite3/dao-version-config/dao.go new file mode 100644 index 0000000000000000000000000000000000000000..37c5c06f0caabcb10cedabdbe20891bda71779ff --- /dev/null +++ b/server/dao/console-sqlite3/dao-version-config/dao.go @@ -0,0 +1,25 @@ +package dao_version_config + +import ( + "database/sql" + + "github.com/eolinker/goku-api-gateway/server/dao" +) + +//VersionConfigDao VersionConfigDao +type VersionConfigDao struct { + db *sql.DB +} + +//NewVersionConfigDao new VersionConfigDao +func NewVersionConfigDao() *VersionConfigDao { + return &VersionConfigDao{} +} + +//Create create +func (d *VersionConfigDao) Create(db *sql.DB) (interface{}, error) { + d.db = db + + i := dao.VersionConfigDao(d) + return &i, nil +} diff --git a/server/dao/console-sqlite3/dao-version-config/discovery.go b/server/dao/console-sqlite3/dao-version-config/discovery.go index 6bd56849a881129cd9b3907119cbb3058b6c7400..14c2e95febd95bdf097d300b28157b0a569c95be 100644 --- a/server/dao/console-sqlite3/dao-version-config/discovery.go +++ b/server/dao/console-sqlite3/dao-version-config/discovery.go @@ -5,12 +5,12 @@ import ( entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" - "github.com/eolinker/goku-api-gateway/common/database" "github.com/eolinker/goku-api-gateway/config" ) -func GetDiscoverConfig(clusters []*entity.Cluster) (map[string]map[string]*config.DiscoverConfig, error) { - db := database.GetConnection() +//GetDiscoverConfig 获取服务发现信息 +func (d *VersionConfigDao)GetDiscoverConfig(clusters []*entity.Cluster) (map[string]map[string]*config.DiscoverConfig, error) { + db := d.db sql := "SELECT `name`,`driver`,`config`,`clusterConfig`,`healthCheck`,`healthCheckPath`,`healthCheckPeriod`,`healthCheckCode`,`healthCheckTimeOut` FROM goku_service_config" rows, err := db.Query(sql) if err != nil { diff --git a/server/dao/console-sqlite3/dao-version-config/gateway.go b/server/dao/console-sqlite3/dao-version-config/gateway.go new file mode 100644 index 0000000000000000000000000000000000000000..4b442a4a8eac5d41b335b4cec41f605463c509a1 --- /dev/null +++ b/server/dao/console-sqlite3/dao-version-config/gateway.go @@ -0,0 +1,19 @@ +package dao_version_config + +import ( + "github.com/eolinker/goku-api-gateway/config" +) + +//GetGatewayBasicConfig GetGatewayBasicConfig +func (d *VersionConfigDao) GetGatewayBasicConfig() (*config.Gateway, error) { + db := d.db + sql := "SELECT skipCertificate FROM goku_gateway;" + + var g config.Gateway + err := db.QueryRow(sql).Scan(&g.SkipCertificate) + if err != nil { + return nil, err + } + + return &g, nil +} diff --git a/server/dao/console-sqlite3/dao-version-config/log.go b/server/dao/console-sqlite3/dao-version-config/log.go index 460b65c0e6f02167e5154520a1b40b3c2b1f8654..8310e46c4a2aee85593a5ab5b6af8859899736b2 100644 --- a/server/dao/console-sqlite3/dao-version-config/log.go +++ b/server/dao/console-sqlite3/dao-version-config/log.go @@ -3,12 +3,12 @@ package dao_version_config import ( "encoding/json" - "github.com/eolinker/goku-api-gateway/common/database" "github.com/eolinker/goku-api-gateway/config" ) -func GetLogInfo() (*config.LogConfig, *config.AccessLogConfig, error) { - db := database.GetConnection() +//GetLogInfo 获取日志信息 +func (d *VersionConfigDao)GetLogInfo() (*config.LogConfig, *config.AccessLogConfig, error) { + db := d.db sql := "SELECT `name`,`enable`,`dir`,`file`,`period`,IFNULL(`level`,''),IFNULL(`fields`,''),`expire` FROM goku_config_log;" rows, err := db.Query(sql) if err != nil { diff --git a/server/dao/console-sqlite3/dao-version-config/monitorModule.go b/server/dao/console-sqlite3/dao-version-config/monitorModule.go index 8543c729743b066984b27999d3da9c3bf4c0eca1..2b3bfff2c45f0b6bc8fe42e641099dd7b64351da 100644 --- a/server/dao/console-sqlite3/dao-version-config/monitorModule.go +++ b/server/dao/console-sqlite3/dao-version-config/monitorModule.go @@ -2,12 +2,11 @@ package dao_version_config import ( "fmt" - - "github.com/eolinker/goku-api-gateway/common/database" ) -func GetMonitorModules(status int, isAll bool) (map[string]string, error) { - db := database.GetConnection() +//GetMonitorModules 获取监控模块信息 +func (d *VersionConfigDao)GetMonitorModules(status int, isAll bool) (map[string]string, error) { + db := d.db sql := "SELECT `name`,`config` FROM goku_monitor_module %s;" if isAll { sql = fmt.Sprintf(sql, "") diff --git a/server/dao/console-sqlite3/dao-version-config/plugin.go b/server/dao/console-sqlite3/dao-version-config/plugin.go index a1962695fddca27ad406e50240feb8e10b3afb3c..871c1abd4f4c25c085595166d8acf9141ba1e198 100644 --- a/server/dao/console-sqlite3/dao-version-config/plugin.go +++ b/server/dao/console-sqlite3/dao-version-config/plugin.go @@ -3,13 +3,12 @@ package dao_version_config import ( "strconv" - "github.com/eolinker/goku-api-gateway/common/database" "github.com/eolinker/goku-api-gateway/config" ) //GetGlobalPlugin 获取全局插件 -func GetGlobalPlugin() (*config.GatewayPluginConfig, error) { - db := database.GetConnection() +func (d *VersionConfigDao) GetGlobalPlugin() (*config.GatewayPluginConfig, error) { + db := d.db sql := "SELECT pluginName,isStop,IFNULL(pluginConfig,''),pluginType FROM goku_plugin" rows, err := db.Query(sql) if err != nil { @@ -46,9 +45,9 @@ func GetGlobalPlugin() (*config.GatewayPluginConfig, error) { } //GetAPIPlugins 获取接口插件 -func GetAPIPlugins() (map[string][]*config.PluginConfig, error) { - db := database.GetConnection() - sql := "SELECT goku_conn_plugin_api.apiID,goku_conn_plugin_api.strategyID,goku_conn_plugin_api.pluginName,goku_conn_plugin_api.pluginConfig,goku_plugin.isStop,goku_conn_plugin_api.updateTag FROM goku_conn_plugin_api INNER JOIN goku_plugin ON goku_conn_plugin_api.pluginName = goku_plugin.pluginName" +func (d *VersionConfigDao) GetAPIPlugins() (map[string][]*config.PluginConfig, error) { + db := d.db + sql := "SELECT goku_conn_plugin_api.apiID,goku_conn_plugin_api.strategyID,goku_conn_plugin_api.pluginName,goku_conn_plugin_api.pluginConfig,goku_plugin.isStop FROM goku_conn_plugin_api INNER JOIN goku_plugin ON goku_conn_plugin_api.pluginName = goku_plugin.pluginName" rows, err := db.Query(sql) if err != nil { return nil, err @@ -58,8 +57,8 @@ func GetAPIPlugins() (map[string][]*config.PluginConfig, error) { for rows.Next() { var apiID int var isStop bool - var pluginName, pluginConfig, updateTag, strategyID string - err = rows.Scan(&apiID, &strategyID, &pluginName, &pluginConfig, &isStop, &updateTag) + var pluginName, pluginConfig, strategyID string + err = rows.Scan(&apiID, &strategyID, &pluginName, &pluginConfig, &isStop) if err != nil { return nil, err } @@ -68,10 +67,9 @@ func GetAPIPlugins() (map[string][]*config.PluginConfig, error) { pluginMaps[key] = make([]*config.PluginConfig, 0, 20) } pluginMaps[key] = append(pluginMaps[key], &config.PluginConfig{ - Name: pluginName, - IsStop: isStop, - Config: pluginConfig, - UpdateTag: updateTag, + Name: pluginName, + IsStop: isStop, + Config: pluginConfig, }) } return pluginMaps, nil @@ -79,9 +77,9 @@ func GetAPIPlugins() (map[string][]*config.PluginConfig, error) { } //GetStrategyPlugins 获取策略插件 -func GetStrategyPlugins() (map[string][]*config.PluginConfig, map[string]map[string]string, error) { - db := database.GetConnection() - sql := "SELECT goku_conn_plugin_strategy.strategyID,goku_conn_plugin_strategy.pluginName,goku_conn_plugin_strategy.pluginConfig,goku_plugin.isStop,goku_conn_plugin_strategy.updateTag FROM goku_conn_plugin_strategy INNER JOIN goku_plugin ON goku_conn_plugin_strategy.pluginName = goku_plugin.pluginName WHERE goku_plugin.pluginStatus = 1 AND goku_conn_plugin_strategy.pluginStatus = 1" +func (d *VersionConfigDao) GetStrategyPlugins() (map[string][]*config.PluginConfig, map[string]map[string]string, error) { + db := d.db + sql := "SELECT goku_conn_plugin_strategy.strategyID,goku_conn_plugin_strategy.pluginName,goku_conn_plugin_strategy.pluginConfig,goku_plugin.isStop FROM goku_conn_plugin_strategy INNER JOIN goku_plugin ON goku_conn_plugin_strategy.pluginName = goku_plugin.pluginName WHERE goku_plugin.pluginStatus = 1 AND goku_conn_plugin_strategy.pluginStatus = 1" rows, err := db.Query(sql) if err != nil { return nil, nil, err @@ -91,8 +89,8 @@ func GetStrategyPlugins() (map[string][]*config.PluginConfig, map[string]map[str authMaps := make(map[string]map[string]string) for rows.Next() { var isStop bool - var pluginName, pluginConfig, updateTag, strategyID string - err = rows.Scan(&strategyID, &pluginName, &pluginConfig, &isStop, &updateTag) + var pluginName, pluginConfig, strategyID string + err = rows.Scan(&strategyID, &pluginName, &pluginConfig, &isStop) if err != nil { return nil, nil, err } @@ -108,10 +106,9 @@ func GetStrategyPlugins() (map[string][]*config.PluginConfig, map[string]map[str } pluginMaps[key] = append(pluginMaps[key], &config.PluginConfig{ - Name: pluginName, - IsStop: isStop, - Config: pluginConfig, - UpdateTag: updateTag, + Name: pluginName, + IsStop: isStop, + Config: pluginConfig, }) } return pluginMaps, authMaps, nil diff --git a/server/dao/console-sqlite3/dao-version-config/router.go b/server/dao/console-sqlite3/dao-version-config/router.go new file mode 100644 index 0000000000000000000000000000000000000000..98c15bd434a556bd1496a6f54a54cf716a714f14 --- /dev/null +++ b/server/dao/console-sqlite3/dao-version-config/router.go @@ -0,0 +1,37 @@ +package dao_version_config + +import ( + "fmt" + "strings" + + "github.com/eolinker/goku-api-gateway/config" +) + +//GetRouterRules GetRouterRules +func (d *VersionConfigDao) GetRouterRules(enable int) ([]*config.Router, error) { + db := d.db + sql := "SELECT rules,target FROM goku_gateway_router %s ORDER BY priority DESC;" + rules := make([]string, 0, 1) + if enable != -1 { + rules = append(rules, fmt.Sprintf("enable = %d", enable)) + } + ruleStr := "" + if len(rules) > 0 { + ruleStr += "WHERE " + strings.Join(rules, " AND ") + } + rows, err := db.Query(fmt.Sprintf(sql, ruleStr)) + if err != nil { + return nil, err + } + defer rows.Close() + rs := make([]*config.Router, 0) + for rows.Next() { + var r config.Router + err = rows.Scan(&r.Rules, &r.Target) + if err != nil { + return nil, err + } + rs = append(rs, &r) + } + return rs, nil +} diff --git a/server/dao/console-sqlite3/dao-version-config/strategy.go b/server/dao/console-sqlite3/dao-version-config/strategy.go index b6508b437ef5884dd7f225a532841319b6fa8fe1..9e06564d87e4a5b4a706222e1b42ecf47db27504 100644 --- a/server/dao/console-sqlite3/dao-version-config/strategy.go +++ b/server/dao/console-sqlite3/dao-version-config/strategy.go @@ -3,7 +3,6 @@ package dao_version_config import ( "strconv" - "github.com/eolinker/goku-api-gateway/common/database" "github.com/eolinker/goku-api-gateway/config" ) @@ -15,15 +14,15 @@ var autoAuthNames = map[string]string{ } //GetAPIsOfStrategy 获取策略内接口数据 -func GetAPIsOfStrategy() (map[string][]*config.APIOfStrategy, error) { - db := database.GetConnection() +func (d *VersionConfigDao)GetAPIsOfStrategy() (map[string][]*config.APIOfStrategy, error) { + db := d.db sql := "SELECT goku_conn_strategy_api.apiID,IFNULL(goku_conn_strategy_api.target,''),goku_conn_strategy_api.strategyID FROM goku_conn_strategy_api;" rows, err := db.Query(sql) if err != nil { return nil, err } defer rows.Close() - apiPlugins, err := GetAPIPlugins() + apiPlugins, err := d.GetAPIPlugins() if err != nil { return nil, err } @@ -53,8 +52,8 @@ func GetAPIsOfStrategy() (map[string][]*config.APIOfStrategy, error) { } //GetStrategyConfig 获取策略配置 -func GetStrategyConfig() (string, []*config.StrategyConfig, error) { - db := database.GetConnection() +func (d *VersionConfigDao)GetStrategyConfig() (string, []*config.StrategyConfig, error) { + db := d.db sql := "SELECT strategyID,strategyName,enableStatus,strategyType FROM goku_gateway_strategy" rows, err := db.Query(sql) @@ -63,11 +62,11 @@ func GetStrategyConfig() (string, []*config.StrategyConfig, error) { } defer rows.Close() strategyConfigs := make([]*config.StrategyConfig, 0, 20) - strategyPlugins, authMaps, err := GetStrategyPlugins() + strategyPlugins, authMaps, err := d.GetStrategyPlugins() if err != nil { return "", nil, err } - apiOfStrategy, err := GetAPIsOfStrategy() + apiOfStrategy, err := d.GetAPIsOfStrategy() if err != nil { return "", nil, err } diff --git a/server/dao/console-sqlite3/gateway.go b/server/dao/console-sqlite3/gateway.go index 8c87ac9664d2f75d3782a54c214a38159d074c69..1b8b9d6a049c8fcaded4f8d72c1acb957895a736 100644 --- a/server/dao/console-sqlite3/gateway.go +++ b/server/dao/console-sqlite3/gateway.go @@ -1,12 +1,35 @@ package console_sqlite3 import ( - database2 "github.com/eolinker/goku-api-gateway/common/database" + "database/sql" + + "github.com/eolinker/goku-api-gateway/server/dao" + entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +//GatewayDao GatewayDao +type GatewayDao struct { + db *sql.DB +} + +//NewGatewayDao new GatewayDao +func NewGatewayDao() *GatewayDao { + return &GatewayDao{} +} + +//Create create +func (d *GatewayDao) Create(db *sql.DB) (interface{}, error) { + + d.db = db + + var i dao.GatewayDao = d + + return &i, nil +} + //GetGatewayConfig 获取网关配置 -func GetGatewayConfig() (map[string]interface{}, error) { - db := database2.GetConnection() +func (d *GatewayDao) GetGatewayConfig() (map[string]interface{}, error) { + db := d.db var successCode string var nodeUpdatePeriod, monitorUpdatePeriod, monitorTimeout int sql := `SELECT successCode,nodeUpdatePeriod,monitorUpdatePeriod,monitorTimeout FROM goku_gateway WHERE id = 1;` @@ -24,8 +47,8 @@ func GetGatewayConfig() (map[string]interface{}, error) { } //EditGatewayBaseConfig 编辑网关基本配置 -func EditGatewayBaseConfig(successCode string, nodeUpdatePeriod, monitorUpdatePeriod, monitorTimeout int) (bool, string, error) { - db := database2.GetConnection() +func (d *GatewayDao) EditGatewayBaseConfig(config entity.GatewayBasicConfig) (bool, string, error) { + db := d.db sql := "SELECT successCode FROM goku_gateway WHERE id = 1;" code := "" err := db.QueryRow(sql).Scan(&code) @@ -39,30 +62,7 @@ func EditGatewayBaseConfig(successCode string, nodeUpdatePeriod, monitorUpdatePe return false, "[ERROR]Illegal SQL Statement!", err } defer stmt.Close() - _, err = stmt.Exec(successCode, nodeUpdatePeriod, monitorUpdatePeriod, monitorTimeout) - if err != nil { - return false, "[ERROR]Fail to excute SQL Statement!", err - } - return true, "", nil -} - -//EditGatewayAlarmConfig 编辑网关告警配置 -func EditGatewayAlarmConfig(apiAlertInfo, sender, senderPassword, smtpAddress string, alertStatus, smtpPort, smtpProtocol int) (bool, string, error) { - db := database2.GetConnection() - sql := "SELECT successCode FROM goku_gateway WHERE id = 1;" - code := "" - err := db.QueryRow(sql).Scan(&code) - if err != nil { - sql = "INSERT INTO goku_gateway (id,apiAlertInfo,alertStatus,sender,senderPassword,smtpAddress,smtpPort,smtpProtocol) VALUES (1,?,?,?,?,?,?,?)" - } else { - sql = "UPDATE goku_gateway SET apiAlertInfo = ?,alertStatus = ?,sender = ?,senderPassword = ?,smtpAddress = ?,smtpPort = ?,smtpProtocol = ? WHERE id = 1;" - } - stmt, err := db.Prepare(sql) - if err != nil { - return false, "[ERROR]Illegal SQL Statement!", err - } - defer stmt.Close() - _, err = stmt.Exec(apiAlertInfo, alertStatus, sender, senderPassword, smtpAddress, smtpPort, smtpProtocol) + _, err = stmt.Exec(config.SuccessCode, config.NodeUpdatePeriod, config.MonitorUpdatePeriod, config.MonitorTimeout) if err != nil { return false, "[ERROR]Fail to excute SQL Statement!", err } @@ -70,8 +70,8 @@ func EditGatewayAlarmConfig(apiAlertInfo, sender, senderPassword, smtpAddress st } //GetGatewayInfo 获取网关信息 -func GetGatewayInfo() (nodeStartCount, nodeStopCount, projectCount, apiCount, strategyCount int, err error) { - db := database2.GetConnection() +func (d *GatewayDao) GetGatewayInfo() (nodeStartCount, nodeStopCount, projectCount, apiCount, strategyCount int, err error) { + db := d.db // 获取节点启动数量 err = db.QueryRow("SELECT COUNT(0) FROM goku_node_info WHERE nodeStatus = 1;").Scan(&nodeStartCount) diff --git a/server/dao/console-sqlite3/guest.go b/server/dao/console-sqlite3/guest.go index 55547a38d9d08f13f913665f11af1bcf439ce1a8..d70053d4fe705efa5c82a3e8a4dac5b68c733cda 100644 --- a/server/dao/console-sqlite3/guest.go +++ b/server/dao/console-sqlite3/guest.go @@ -3,13 +3,31 @@ package console_sqlite3 import ( SQL "database/sql" - "github.com/eolinker/goku-api-gateway/common/database" + "github.com/eolinker/goku-api-gateway/server/dao" + "github.com/eolinker/goku-api-gateway/utils" ) +//GuestDao GuestDao +type GuestDao struct { + db *SQL.DB +} + +//NewGuestDao new GuestDao +func NewGuestDao() *GuestDao { + return &GuestDao{} +} + +//Create create +func (d *GuestDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.GuestDao = d + return &i, nil +} + //Login 登录 -func Login(loginCall, loginPassword string) (bool, int) { - db := database.GetConnection() +func (d *GuestDao) Login(loginCall, loginPassword string) (bool, int) { + db := d.db var userID int err := db.QueryRow("SELECT userID FROM goku_admin WHERE loginCall = ? AND loginPassword = ?;", loginCall, loginPassword).Scan(&userID) if err != nil { @@ -19,8 +37,8 @@ func Login(loginCall, loginPassword string) (bool, int) { } //CheckLogin 检查用户是否登录 -func CheckLogin(userToken string, userID int) bool { - db := database.GetConnection() +func (d *GuestDao) CheckLogin(userToken string, userID int) bool { + db := d.db var loginPassword, loginCall string err := db.QueryRow("SELECT loginCall,loginPassword FROM goku_admin WHERE userID = ?;", userID).Scan(&loginCall, &loginPassword) if err != nil { @@ -33,8 +51,8 @@ func CheckLogin(userToken string, userID int) bool { } //Register 用户注册 -func Register(loginCall, loginPassword string) bool { - db := database.GetConnection() +func (d *GuestDao) Register(loginCall, loginPassword string) bool { + db := d.db sql := "SELECT userID,loginPassword FROM goku_admin WHERE loginCall = ?;" password := "" userID := 0 diff --git a/server/dao/console-sqlite3/import.go b/server/dao/console-sqlite3/import.go index 5bf1f9f53ef704ec986e098f981d875e6984fddf..a635dd5f693ed17f1f7659c8ef9053831b9236d1 100644 --- a/server/dao/console-sqlite3/import.go +++ b/server/dao/console-sqlite3/import.go @@ -7,16 +7,34 @@ import ( "strings" "time" + "github.com/eolinker/goku-api-gateway/server/dao" + log "github.com/eolinker/goku-api-gateway/goku-log" - database2 "github.com/eolinker/goku-api-gateway/common/database" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) var method = []string{"POST", "GET", "PUT", "DELETE", "HEAD", "OPTIONS", "PATCH"} +//ImportDao ImportDao +type ImportDao struct { + db *SQL.DB +} + +//NewImportDao ImportDao +func NewImportDao() *ImportDao { + return &ImportDao{} +} + +//Create create +func (d *ImportDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.ImportDao = d + return &i, nil +} + // 导入接口信息 -func importAPIInfo(Tx *SQL.Tx, api entity.AmsAPIInfo, projectID, groupID, userID int, now string) bool { +func (d *ImportDao) importAPIInfo(Tx *SQL.Tx, api entity.AmsAPIInfo, projectID, groupID, userID int, now string) bool { // 新增API requestURL := "" host := "" @@ -44,7 +62,7 @@ func importAPIInfo(Tx *SQL.Tx, api entity.AmsAPIInfo, projectID, groupID, userID return true } -func recursiveImportAPIGroupFromAms(Tx *SQL.Tx, projectID, userID int, groupInfo entity.AmsGroupInfo, groupDepth, parentGroupID int, groupPath, now string) (bool, string, error) { +func (d *ImportDao) recursiveImportAPIGroupFromAms(Tx *SQL.Tx, projectID, userID int, groupInfo entity.AmsGroupInfo, groupDepth, parentGroupID int, groupPath, now string) (bool, string, error) { // 插入分组信息 result, err := Tx.Exec("INSERT INTO goku_gateway_api_group (projectID,groupName,groupDepth,parentGroupID) VALUES (?,?,?,?);", projectID, groupInfo.GroupName, groupDepth, parentGroupID) if err != nil { @@ -72,19 +90,19 @@ func recursiveImportAPIGroupFromAms(Tx *SQL.Tx, projectID, userID int, groupInfo return false, err.Error(), err } for _, childGroup := range groupInfo.APIGroupChildList { - _, _, err := recursiveImportAPIGroupFromAms(Tx, projectID, userID, childGroup, groupDepth+1, int(groupID), groupPath, now) + _, _, err := d.recursiveImportAPIGroupFromAms(Tx, projectID, userID, childGroup, groupDepth+1, int(groupID), groupPath, now) if err != nil { continue } } for _, childGroup := range groupInfo.ChildGroupList { - _, _, err := recursiveImportAPIGroupFromAms(Tx, projectID, userID, childGroup, groupDepth+1, int(groupID), groupPath, now) + _, _, err := d.recursiveImportAPIGroupFromAms(Tx, projectID, userID, childGroup, groupDepth+1, int(groupID), groupPath, now) if err != nil { continue } } for _, api := range groupInfo.APIList { - flag := importAPIInfo(Tx, api, projectID, int(groupID), userID, now) + flag := d.importAPIInfo(Tx, api, projectID, int(groupID), userID, now) if !flag { continue } @@ -93,11 +111,11 @@ func recursiveImportAPIGroupFromAms(Tx *SQL.Tx, projectID, userID int, groupInfo } //ImportAPIGroupFromAms 导入分组 -func ImportAPIGroupFromAms(projectID, userID int, groupInfo entity.AmsGroupInfo) (bool, string, error) { - db := database2.GetConnection() +func (d *ImportDao) ImportAPIGroupFromAms(projectID, userID int, groupInfo entity.AmsGroupInfo) (bool, string, error) { + db := d.db Tx, _ := db.Begin() now := time.Now().Format("2006-01-02 15:04:05") - _, errInfo, err := recursiveImportAPIGroupFromAms(Tx, projectID, userID, groupInfo, 1, 0, "", now) + _, errInfo, err := d.recursiveImportAPIGroupFromAms(Tx, projectID, userID, groupInfo, 1, 0, "", now) if err != nil { Tx.Rollback() return false, errInfo, err @@ -113,8 +131,8 @@ func ImportAPIGroupFromAms(projectID, userID int, groupInfo entity.AmsGroupInfo) } //ImportProjectFromAms 导入项目 -func ImportProjectFromAms(userID int, projectInfo entity.AmsProject) (bool, string, error) { - db := database2.GetConnection() +func (d *ImportDao) ImportProjectFromAms(userID int, projectInfo entity.AmsProject) (bool, string, error) { + db := d.db Tx, _ := db.Begin() now := time.Now().Format("2006-01-02 15:04:05") // 插入项目信息 @@ -132,7 +150,7 @@ func ImportProjectFromAms(userID int, projectInfo entity.AmsProject) (bool, stri } id := int(projectID) for _, groupInfo := range projectInfo.APIGroupList { - _, _, err := recursiveImportAPIGroupFromAms(Tx, id, userID, groupInfo, 1, 0, "", now) + _, _, err := d.recursiveImportAPIGroupFromAms(Tx, id, userID, groupInfo, 1, 0, "", now) if err != nil { continue } @@ -142,12 +160,12 @@ func ImportProjectFromAms(userID int, projectInfo entity.AmsProject) (bool, stri } //ImportAPIFromAms 从ams中导入接口 -func ImportAPIFromAms(projectID, groupID, userID int, apiList []entity.AmsAPIInfo) (bool, string, error) { - db := database2.GetConnection() +func (d *ImportDao) ImportAPIFromAms(projectID, groupID, userID int, apiList []entity.AmsAPIInfo) (bool, string, error) { + db := d.db Tx, _ := db.Begin() now := time.Now().Format("2006-01-02 15:04:05") for _, a := range apiList { - flag := importAPIInfo(Tx, a, projectID, groupID, userID, now) + flag := d.importAPIInfo(Tx, a, projectID, groupID, userID, now) if !flag { continue } diff --git a/server/dao/console-sqlite3/internal/goku311/gokuMonitorModule.go b/server/dao/console-sqlite3/internal/goku311/gokuMonitorModule.go new file mode 100644 index 0000000000000000000000000000000000000000..dfef9608c0dfbd0d19ba6c75d3b8df6aeb3bd357 --- /dev/null +++ b/server/dao/console-sqlite3/internal/goku311/gokuMonitorModule.go @@ -0,0 +1,24 @@ +package goku311 + +import SQL "database/sql" + +const gokuMonitorModuleSQL = `DROP TABLE IF EXISTS goku_monitor_module; +CREATE TABLE "goku_monitor_module" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "name" TEXT NOT NULL, + "config" TEXT NOT NULL, + "moduleStatus" integer NOT NULL DEFAULT 0 +); + +CREATE UNIQUE INDEX "moduleName" +ON "goku_monitor_module" ( + "name" ASC +);` + +func createGokuMonitorModule(db *SQL.DB) error { + _, err := db.Exec(gokuMonitorModuleSQL) + if err != nil { + return err + } + return nil +} diff --git a/server/dao/console-sqlite3/internal/goku311/gokuNodeInfo.go b/server/dao/console-sqlite3/internal/goku311/gokuNodeInfo.go new file mode 100644 index 0000000000000000000000000000000000000000..f7835be4cb385fa4623cd54981f0a5adcf45f49d --- /dev/null +++ b/server/dao/console-sqlite3/internal/goku311/gokuNodeInfo.go @@ -0,0 +1,58 @@ +package goku311 + +import ( + SQL "database/sql" +) + +const gokuNodeInfoSQL = `DROP TABLE IF EXISTS goku_node_info_new; +CREATE TABLE "goku_node_info_new" ( + "nodeID" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "createTime" text, + "updateTime" text, + "groupID" integer(11) NOT NULL DEFAULT 0, + "nodeName" text(255) NOT NULL, + "nodeStatus" integer(11) NOT NULL, + "version" text(255), + "sshAddress" text(255) DEFAULT 22, + "sshUserName" text(255), + "sshPassword" text(255), + "gatewayPath" text(255), + "sshKey" text, + "authMethod" integer(4) NOT NULL DEFAULT 0, + "clusterID" integer(11) NOT NULL DEFAULT 0, + "listenAddress" text(22) NOT NULL DEFAULT '', + "adminAddress" text(22) NOT NULL DEFAULT '', + "nodeKey" TEXT(32) NOT NULL DEFAULT '' +); + +CREATE UNIQUE INDEX "nodeKey_new" +ON "goku_node_info_new" ( + "nodeKey" ASC +);` + +func createGokuNodeInfo(db *SQL.DB) error { + _, err := db.Exec(gokuNodeInfoSQL) + if err != nil { + return err + } + + sql := "INSERT INTO goku_node_info_new (`nodeID`,`createTime`,`updateTime`,`groupID`,`nodeName`,`nodeStatus`,`version`,`sshAddress`,`sshUserName`,`sshPassword`,`gatewayPath`,`sshKey`,`authMethod`,`clusterID`,`listenAddress`,`adminAddress`,`nodeKey`) SELECT `nodeID`,`createTime`,`updateTime`,`groupID`,`nodeName`,`nodeStatus`,`version`,`sshPort`,`userName`,`password`,`gatewayPath`,`key`,`authMethod`,`clusterID`,`nodeIP` || ':' || `nodePort`,`nodeIP` || ':' || `nodePort`,`nodeID` || `nodeIP` || ':' || `nodePort` FROM goku_node_info;" + _, err = db.Exec(sql) + if err != nil { + return err + } + _, err = db.Exec("DROP TABLE IF EXISTS goku_node_info") + if err != nil { + return err + } + _, err = db.Exec("ALTER TABLE goku_node_info_new RENAME TO goku_node_info") + if err != nil { + return err + } + _, err = db.Exec("DROP TABLE IF EXISTS goku_node_info_new") + if err != nil { + return err + } + + return nil +} diff --git a/server/dao/console-sqlite3/internal/goku311/gokuTableVersion.go b/server/dao/console-sqlite3/internal/goku311/gokuTableVersion.go new file mode 100644 index 0000000000000000000000000000000000000000..26f85dd5eeb5bd47e6f7673409ed26ee2904334a --- /dev/null +++ b/server/dao/console-sqlite3/internal/goku311/gokuTableVersion.go @@ -0,0 +1,23 @@ +package goku311 + +import SQL "database/sql" + +const gokuTableVersionSQL = `CREATE TABLE "goku_table_version" ( + "tableID" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "tableName" TEXT NOT NULL, + "version" TEXT NOT NULL +); + +CREATE UNIQUE INDEX "tableName" +ON "goku_table_version" ( + "tableName" +);` + +func createGokuTableVersion(db *SQL.DB) error { + _, err := db.Exec(gokuTableVersionSQL) + if err != nil { + return err + } + + return nil +} diff --git a/server/dao/console-sqlite3/internal/goku311/update.go b/server/dao/console-sqlite3/internal/goku311/update.go new file mode 100644 index 0000000000000000000000000000000000000000..7a1b988adf49fbbfa4bbf77c9cf72a34fa3c4a48 --- /dev/null +++ b/server/dao/console-sqlite3/internal/goku311/update.go @@ -0,0 +1,60 @@ +package goku311 + +import ( + "database/sql" + + "github.com/eolinker/goku-api-gateway/common/pdao" + "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/updater" +) + +//Version 版本号 +const Version = "3.1.1" + +//DBDriver dbDriver +const DBDriver = "sqlite3" + +//RegisterUpdate RegisterUpdate +func RegisterUpdate() { + pdao.RegisterDBBuilder(DBDriver, new(factory)) +} + +type factory struct { +} + +func (f *factory) Build(db *sql.DB) error { + return Exec(db) +} + +//Exec 执行goku_node_info +func Exec(db *sql.DB) error { + + updaterDao := updater.NewUpdaterDaoWidthDB(db) + + existed := updaterDao.IsTableExist("goku_table_version") + if !existed { + err := createGokuTableVersion(db) + if err != nil { + + return err + } + } + if version := updaterDao.GetTableVersion("goku_node_info"); version != Version { + err := createGokuNodeInfo(db) + if err != nil { + + return err + } + updaterDao.UpdateTableVersion("goku_node_info", Version) + } + if version := updaterDao.GetTableVersion("goku_monitor_module"); version != Version { + err := createGokuMonitorModule(db) + if err != nil { + return err + } + updaterDao.UpdateTableVersion("goku_monitor_module", Version) + } + + updaterDao.SetGokuVersion(Version) + + return nil +} diff --git a/server/dao/console-sqlite3/monitorModule.go b/server/dao/console-sqlite3/monitorModule.go index 3899e1ac8d23264e99e449e5b63a5f7dfde30982..cf832f6ff21548aeb6dc7f0ac14e3b25ea32da13 100644 --- a/server/dao/console-sqlite3/monitorModule.go +++ b/server/dao/console-sqlite3/monitorModule.go @@ -1,13 +1,32 @@ package console_sqlite3 import ( - "github.com/eolinker/goku-api-gateway/common/database" + SQL "database/sql" + + "github.com/eolinker/goku-api-gateway/server/dao" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +//MonitorModulesDao MonitorModulesDao +type MonitorModulesDao struct { + db *SQL.DB +} + +//NewMonitorModulesDao MonitorModulesDao +func NewMonitorModulesDao() *MonitorModulesDao { + return &MonitorModulesDao{} +} + +//Create create +func (d *MonitorModulesDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.MonitorModulesDao = d + return &i, nil +} + //GetMonitorModules 获取监控模块列表 -func GetMonitorModules() (map[string]*entity.MonitorModule, error) { - db := database.GetConnection() +func (d *MonitorModulesDao) GetMonitorModules() (map[string]*entity.MonitorModule, error) { + db := d.db sql := "SELECT `name`,IFNULL(`config`,'{}'),`moduleStatus` FROM goku_monitor_module;" rows, err := db.Query(sql) if err != nil { @@ -28,8 +47,8 @@ func GetMonitorModules() (map[string]*entity.MonitorModule, error) { } //SetMonitorModule 设置监控模块 -func SetMonitorModule(moduleName string, config string, moduleStatus int) error { - db := database.GetConnection() +func (d *MonitorModulesDao) SetMonitorModule(moduleName string, config string, moduleStatus int) error { + db := d.db sql := "REPLACE INTO goku_monitor_module (`name`,`config`,`moduleStatus`) VALUES (?,?,?)" _, err := db.Exec(sql, moduleName, config, moduleStatus) if err != nil { @@ -37,3 +56,15 @@ func SetMonitorModule(moduleName string, config string, moduleStatus int) error } return nil } + +//CheckModuleStatus 检查模块状态 +func (d *MonitorModulesDao) CheckModuleStatus(moduleName string) int { + db := d.db + status := 0 + sql := "SELECT moduleStatus FROM goku_monitor_module WHERE moduleName = ?" + err := db.QueryRow(sql, moduleName).Scan(&status) + if err != nil { + return status + } + return status +} diff --git a/server/dao/console-sqlite3/node.go b/server/dao/console-sqlite3/node.go index 11ebf8e69d217e6fb253c3f9fc3ad72542c1507e..fa1a3f0ffeb809208ee849a4500bb25c4b31a5c8 100644 --- a/server/dao/console-sqlite3/node.go +++ b/server/dao/console-sqlite3/node.go @@ -1,73 +1,91 @@ package console_sqlite3 import ( + SQL "database/sql" "fmt" "strconv" "strings" "time" - "github.com/eolinker/goku-api-gateway/common/database" v "github.com/eolinker/goku-api-gateway/common/version" + "github.com/eolinker/goku-api-gateway/server/dao" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +//NodeDao NodeDao +type NodeDao struct { + db *SQL.DB +} + +//NewNodeDao new NodeDao +func NewNodeDao() *NodeDao { + return &NodeDao{} +} + +//Create create +func (d *NodeDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.NodeDao = d + return &i, nil +} + //AddNode 新增节点信息 -func AddNode(clusterID int, nodeName, nodeKey, listenAddress, adminAddress, gatewayPath string, groupID int) (bool, map[string]interface{}, error) { - db := database.GetConnection() +func (d *NodeDao) AddNode(clusterID int, nodeName, nodeKey, listenAddress, adminAddress, gatewayPath string, groupID int) (int64, string, string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") sql := "INSERT INTO goku_node_info (`clusterID`,`nodeName`,`groupID`,`nodeKey`,`listenAddress`,`adminAddress`,`updateTime`,`createTime`,`version`, `gatewayPath`,`nodeStatus`) VALUES (?,?,?,?,?,?,?,?,?,?,0);" stmt, err := db.Prepare(sql) if err != nil { - return false, map[string]interface{}{"error": "[ERROR]Illegal SQL statement!"}, err + return 0, "", "[ERROR]Illegal SQL statement!", err } defer stmt.Close() res, err := stmt.Exec(clusterID, nodeName, groupID, nodeKey, listenAddress, adminAddress, now, now, v.Version, gatewayPath) if err != nil { - return false, map[string]interface{}{"error": "[ERROR]Failed to insert data!"}, err + return 0, "", "[ERROR]Failed to insert data!", err } nodeID, err := res.LastInsertId() if err != nil { - return false, map[string]interface{}{"error": "[ERROR]Failed to insert data!"}, err + return 0, "", "[ERROR]Failed to insert data!", err } - return true, map[string]interface{}{"nodeID": nodeID, "version": v.Version}, nil + return nodeID, v.Version, "", nil } //EditNode 修改节点信息 -func EditNode(nodeName, listenAddress, adminAddress, gatewayPath string, nodeID, groupID int) (bool, string, error) { - db := database.GetConnection() +func (d *NodeDao) EditNode(nodeName, listenAddress, adminAddress, gatewayPath string, nodeID, groupID int) (string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") sql := "UPDATE goku_node_info SET nodeName = ?,listenAddress = ?,adminAddress = ?,updateTime = ?,groupID = ?,gatewayPath = ? WHERE nodeID = ?;" stmt, err := db.Prepare(sql) if err != nil { - return false, "[ERROR]Illegal SQL statement!", err + return "[ERROR]Illegal SQL statement!", err } defer stmt.Close() _, err = stmt.Exec(nodeName, listenAddress, adminAddress, now, groupID, gatewayPath, nodeID) if err != nil { - return false, "[ERROR]Failed to update data!", err + return "[ERROR]Failed to update data!", err } - return true, "", nil + return "", nil } //DeleteNode 删除节点信息 -func DeleteNode(nodeID int) (bool, string, error) { - db := database.GetConnection() +func (d *NodeDao) DeleteNode(nodeID int) (string, error) { + db := d.db sql := "DELETE FROM goku_node_info WHERE nodeID = ?;" stmt, err := db.Prepare(sql) if err != nil { - return false, "[ERROR]Illegal SQL statement!", err + return "[ERROR]Illegal SQL statement!", err } defer stmt.Close() _, err = stmt.Exec(nodeID) if err != nil { - return false, "[ERROR]Failed to delete data!", err + return "[ERROR]Failed to delete data!", err } - return true, "", nil + return "", nil } // GetNodeList 获取节点列表 -func GetNodeList(clusterID, groupID int, keyword string) (bool, []*entity.Node, error) { - db := database.GetConnection() +func (d *NodeDao) GetNodeList(clusterID, groupID int, keyword string) ([]*entity.Node, error) { + rule := make([]string, 0, 2) rule = append(rule, fmt.Sprintf("A.clusterID = %d", clusterID)) @@ -81,77 +99,113 @@ func GetNodeList(clusterID, groupID int, keyword string) (bool, []*entity.Node, } ruleStr := "" if len(rule) > 0 { - ruleStr += "WHERE " + strings.Join(rule, " AND ") + ruleStr += " WHERE " + strings.Join(rule, " AND ") } - sql := fmt.Sprintf("SELECT A.nodeID,A.nodeName,A.nodeKey,A.listenAddress,A.adminAddress,A.updateTime,A.createTime,A.version,A.gatewayPath,A.groupID,IFNULL(G.groupName,'未分类') FROM goku_node_info A LEFT JOIN goku_node_group G ON A.groupID = G.groupID %s ORDER BY updateTime DESC;", ruleStr) - rows, err := db.Query(sql) - if err != nil { - return false, nil, err + sql := fmt.Sprint(nodeSQLAll, ruleStr, " ORDER BY updateTime DESC;") + + return d.getNodeInfo(sql) + + //rows, err := db.Query(sql) + //if err != nil { + // return nil, err + //} + ////延时关闭Rows + //defer rows.Close() + ////获取记录列 + //nodeList := make([]*entity.Node, 0) + //for rows.Next() { + // node := entity.Node{} + // err = rows.Scan(&node.NodeID, &node.NodeName, &node.NodeKey, &node.ListenAddress, &node.AdminAddress, &node.UpdateTime, &node.CreateTime, &node.Version, &node.GatewayPath, &node.GroupID, &node.GroupName) + // if err != nil { + // return nil, err + // } + // if node.Version == v.Version { + // // 判断节点版本号是否是最新 + // node.IsUpdate = true + // } + // nodeList = append(nodeList, &node) + //} + //return nodeList, nil +} + +const nodeSQLAll = "SELECT A.`nodeID` , A.`nodeName` , A.`listenAddress` , A.`adminAddress` , A.`nodeKey` , A.`updateTime` , A.`createTime` , A.`version` , A.`gatewayPath` , A.`groupID` , IFNULL(G.`groupName` , '未分类') , C.`name`As cluster , C.`title` As cluster_title FROM goku_node_info A LEFT JOIN goku_node_group G ON A.`groupID` = G.`groupID` LEFT JOIN `goku_cluster` C ON A.`clusterID`=C.`id`" +const nodeSQLID = nodeSQLAll + " WHERE A.`nodeID` = ? ;" +const nodeSQLInstance = nodeSQLAll + " WHERE A.`nodeKey` = ? ;" + +func (d *NodeDao) getNodeInfo(sql string, args ...interface{}) ([]*entity.Node, error) { + + db := d.db + + rows, e := db.Query(sql, args...) + if e != nil { + return nil, e } - //延时关闭Rows - defer rows.Close() - //获取记录列 - nodeList := make([]*entity.Node, 0) + nodes := make([]*entity.Node, 0, 10) for rows.Next() { - node := entity.Node{} - err = rows.Scan(&node.NodeID, &node.NodeName, &node.NodeKey, &node.ListenAddress, &node.AdminAddress, &node.UpdateTime, &node.CreateTime, &node.Version, &node.GatewayPath, &node.GroupID, &node.GroupName) + node := &entity.Node{} + err := rows.Scan(&node.NodeID, + &node.NodeName, + &node.ListenAddress, + &node.AdminAddress, + &node.NodeKey, + &node.UpdateTime, + &node.CreateTime, + &node.Version, + &node.GatewayPath, + &node.GroupID, + &node.GroupName, + &node.Cluster, + &node.ClusterTitle) if err != nil { - return false, nil, err - } - if node.Version == v.Version { - // 判断节点版本号是否是最新 - node.IsUpdate = true + return nil, err } - nodeList = append(nodeList, &node) + nodes = append(nodes, node) } - return true, nodeList, nil + return nodes, nil } -const nodeSQLID = "SELECT A.`nodeID`, A.`nodeName`,A.`listenAddress`,A.`adminAddress`, A.`nodeKey`, A.`updateTime`, A.`createTime`, A.`version`, A.`gatewayPath`, A.`groupID`, IFNULL(G.`groupName`,''), C.`name` As cluster, C.`title` As cluster_title FROM goku_node_info A LEFT JOIN goku_node_group G ON A.`groupID` = G.`groupID` LEFT JOIN `goku_cluster` C ON A.`clusterID` = C.`id` WHERE A.`nodeID` = ? ;" -const nodeSQLInstance = "SELECT A.`nodeID`, A.`nodeName`,A.`listenAddress`,A.`adminAddress`, A.`nodeKey`, A.`updateTime`, A.`createTime`, A.`version`, A.`gatewayPath`, A.`groupID`, IFNULL(G.`groupName`,'') , C.`name` As cluster, C.`title` As cluster_title FROM goku_node_info A LEFT JOIN goku_node_group G ON A.`groupID` = G.`groupID` LEFT JOIN `goku_cluster` C ON A.`clusterID` = C.`id` WHERE A.`nodeKey` = ? ;" - -func getNodeInfo(sql string, args ...interface{}) (*entity.Node, error) { +//GetNodeInfoAll get all node +func (d *NodeDao) GetNodeInfoAll() ([]*entity.Node, error) { + nodes, e := d.getNodeInfo(nodeSQLAll) + if e != nil { + return nil, e + } - db := database.GetConnection() + return nodes, nil - node := &entity.Node{} - err := db.QueryRow(sql, args...).Scan(&node.NodeID, - &node.NodeName, - &node.ListenAddress, - &node.AdminAddress, - &node.NodeKey, - &node.UpdateTime, - &node.CreateTime, - &node.Version, - &node.GatewayPath, - &node.GroupID, - &node.GroupName, - &node.Cluster, - &node.ClusterTitle) - if err != nil { - return nil, err - } - return node, err } //GetNodeInfo 获取节点信息 -func GetNodeInfo(nodeID int) (*entity.Node, error) { - - return getNodeInfo(nodeSQLID, nodeID) +func (d *NodeDao) GetNodeInfo(nodeID int) (*entity.Node, error) { + nodes, e := d.getNodeInfo(nodeSQLID, nodeID) + if e != nil { + return nil, e + } + if len(nodes) > 0 { + return nodes[0], nil + } + return nil, fmt.Errorf("not exit node width noddID:%d", nodeID) } //GetNodeByKey 通过Key查询节点信息 -func GetNodeByKey(nodeKey string) (*entity.Node, error) { - return getNodeInfo(nodeSQLInstance, nodeKey) +func (d *NodeDao) GetNodeByKey(nodeKey string) (*entity.Node, error) { + nodes, e := d.getNodeInfo(nodeSQLInstance, nodeKey) + if e != nil { + return nil, e + } + if len(nodes) > 0 { + return nodes[0], nil + } + return nil, fmt.Errorf("not exit node width nodeKey:%s", nodeKey) } //GetAvaliableNodeListFromNodeList 从待操作节点中获取关闭节点列表 -func GetAvaliableNodeListFromNodeList(nodeIDList string, nodeStatus int) (bool, string, error) { - db := database.GetConnection() +func (d *NodeDao) GetAvaliableNodeListFromNodeList(nodeIDList string, nodeStatus int) (string, error) { + db := d.db sql := "SELECT nodeID FROM goku_node_info WHERE nodeID IN (" + nodeIDList + ") AND nodeStatus = ?" rows, err := db.Query(sql, nodeStatus) if err != nil { - return false, "[ERROR]Fail to excute SQL statement!", err + return "[ERROR]Fail to excute SQL statement!", err } defer rows.Close() idList := make([]string, 0) @@ -159,45 +213,45 @@ func GetAvaliableNodeListFromNodeList(nodeIDList string, nodeStatus int) (bool, var nodeID int err = rows.Scan(&nodeID) if err != nil { - return false, err.Error(), err + return err.Error(), err } idList = append(idList, strconv.Itoa(nodeID)) } - return true, strings.Join(idList, ","), nil + return strings.Join(idList, ","), nil } //BatchEditNodeGroup 批量修改节点分组 -func BatchEditNodeGroup(nodeIDList string, groupID int) (bool, string, error) { - db := database.GetConnection() +func (d *NodeDao) BatchEditNodeGroup(nodeIDList string, groupID int) (string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") Tx, _ := db.Begin() sql := "UPDATE goku_node_info SET groupID = ?,updateTime = ? WHERE nodeID IN (" + nodeIDList + ");" _, err := Tx.Exec(sql, groupID, now) if err != nil { Tx.Rollback() - return false, "[ERROR]Fail to excute SQL statement!", err + return "[ERROR]Fail to excute SQL statement!", err } Tx.Commit() - return true, "", nil + return "", nil } //BatchDeleteNode 批量修改接口分组 -func BatchDeleteNode(nodeIDList string) (bool, string, error) { - db := database.GetConnection() +func (d *NodeDao) BatchDeleteNode(nodeIDList string) (string, error) { + db := d.db Tx, _ := db.Begin() sql := "DELETE FROM goku_node_info WHERE nodeID IN (" + nodeIDList + ");" _, err := Tx.Exec(sql) if err != nil { Tx.Rollback() - return false, "[ERROR]Fail to excute SQL statement!", err + return "[ERROR]Fail to excute SQL statement!", err } Tx.Commit() - return true, "", nil + return "", nil } //UpdateAllNodeClusterID 更新节点集群ID -func UpdateAllNodeClusterID(clusterID int) { - db := database.GetConnection() +func (d *NodeDao) UpdateAllNodeClusterID(clusterID int) { + db := d.db Tx, _ := db.Begin() sql := "UPDATE goku_node_info SET clusterID = ?;" _, err := Tx.Exec(sql, clusterID) @@ -213,3 +267,33 @@ func UpdateAllNodeClusterID(clusterID int) { } Tx.Commit() } + +//GetHeartBeatTime 获取节点心跳时间 +func (d *NodeDao) GetHeartBeatTime(nodeKey string) (time.Time, error) { + db := d.db + heartBeat := "" + + sql := "SELECT heartBeatTime FROM goku_node_info WHERE nodeKey = ?" + err := db.QueryRow(sql, nodeKey).Scan(&heartBeat) + if err != nil { + return time.Time{}, err + } + heartBeatTime, err := time.ParseInLocation("2006-01-02 15:04:05", heartBeat, time.Local) + if err != nil { + return time.Time{}, err + } + return heartBeatTime, nil +} + +//SetHeartBeatTime 设置节点心跳时间 +func (d *NodeDao) SetHeartBeatTime(nodeKey string, heartBeatTime time.Time) error { + db := d.db + heartBeat := heartBeatTime.Format("2006-01-02 15:04:05") + + sql := "UPDATE goku_node_info SET heartBeatTime = ? WHERE nodeKey = ?" + _, err := db.Exec(sql, heartBeat, nodeKey) + if err != nil { + return err + } + return nil +} diff --git a/server/dao/console-sqlite3/nodeGroup.go b/server/dao/console-sqlite3/nodeGroup.go index bb79d220e0212bebe3254a623beb434f62de5170..f25362667d25ece8df1c12474dae26b4d3f08701 100644 --- a/server/dao/console-sqlite3/nodeGroup.go +++ b/server/dao/console-sqlite3/nodeGroup.go @@ -1,12 +1,31 @@ package console_sqlite3 import ( - database2 "github.com/eolinker/goku-api-gateway/common/database" + SQL "database/sql" + + "github.com/eolinker/goku-api-gateway/server/dao" ) +//NodeGroupDao NodeGroupDao +type NodeGroupDao struct { + db *SQL.DB +} + +//NewNodeGroupDao new NodeGroupDao +func NewNodeGroupDao() *NodeGroupDao { + return &NodeGroupDao{} +} + +//Create create +func (d *NodeGroupDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.NodeGroupDao = d + return &i, nil +} + //AddNodeGroup 新建节点分组 -func AddNodeGroup(groupName string, clusterID int) (bool, interface{}, error) { - db := database2.GetConnection() +func (d *NodeGroupDao) AddNodeGroup(groupName string, clusterID int) (bool, interface{}, error) { + db := d.db sql := "INSERT INTO goku_node_group (`groupName`,`clusterID`) VALUES (?,?);" stmt, err := db.Prepare(sql) if err != nil { @@ -22,8 +41,8 @@ func AddNodeGroup(groupName string, clusterID int) (bool, interface{}, error) { } //EditNodeGroup 修改节点分组信息 -func EditNodeGroup(groupName string, groupID int) (bool, string, error) { - db := database2.GetConnection() +func (d *NodeGroupDao) EditNodeGroup(groupName string, groupID int) (bool, string, error) { + db := d.db sql := "UPDATE goku_node_group SET groupName = ? WHERE groupID = ?;" stmt, err := db.Prepare(sql) if err != nil { @@ -38,8 +57,8 @@ func EditNodeGroup(groupName string, groupID int) (bool, string, error) { } //DeleteNodeGroup 删除节点分组 -func DeleteNodeGroup(groupID int) (bool, string, error) { - db := database2.GetConnection() +func (d *NodeGroupDao) DeleteNodeGroup(groupID int) (bool, string, error) { + db := d.db Tx, _ := db.Begin() sql := "DELETE FROM goku_node_group WHERE groupID = ?;" _, err := Tx.Exec(sql, groupID) @@ -58,8 +77,8 @@ func DeleteNodeGroup(groupID int) (bool, string, error) { } //GetNodeGroupInfo 获取节点分组信息 -func GetNodeGroupInfo(groupID int) (bool, map[string]interface{}, error) { - db := database2.GetConnection() +func (d *NodeGroupDao) GetNodeGroupInfo(groupID int) (bool, map[string]interface{}, error) { + db := d.db sql := "SELECT G.`groupName`,C.`name` FROM goku_node_group G left join `goku_cluster` C ON C.`id` = G.`clusterID` WHERE G.`groupID` = ?;" var groupName string @@ -77,8 +96,8 @@ func GetNodeGroupInfo(groupID int) (bool, map[string]interface{}, error) { } //GetNodeGroupList 获取节点分组列表 -func GetNodeGroupList(clusterID int) (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *NodeGroupDao) GetNodeGroupList(clusterID int) (bool, []map[string]interface{}, error) { + db := d.db sql := "SELECT G.`groupID`, G.groupName,C.`name` as cluster FROM goku_node_group G left join `goku_cluster` C ON C.`id` = G.`clusterID` where G.`clusterID`=?;" rows, err := db.Query(sql, clusterID) if err != nil { @@ -108,8 +127,8 @@ func GetNodeGroupList(clusterID int) (bool, []map[string]interface{}, error) { } //CheckNodeGroupIsExist 检查节点分组是否存在 -func CheckNodeGroupIsExist(groupID int) (bool, error) { - db := database2.GetConnection() +func (d *NodeGroupDao) CheckNodeGroupIsExist(groupID int) (bool, error) { + db := d.db var id int sql := "SELECT groupID FROM goku_node_group WHERE groupID = ?;" err := db.QueryRow(sql, groupID).Scan(&id) @@ -120,8 +139,8 @@ func CheckNodeGroupIsExist(groupID int) (bool, error) { } //GetRunningNodeCount 获取分组内启动节点数量 -func GetRunningNodeCount(groupID int) (bool, interface{}, error) { - db := database2.GetConnection() +func (d *NodeGroupDao) GetRunningNodeCount(groupID int) (bool, interface{}, error) { + db := d.db var count int sql := "SELECT COUNT(0) FROM goku_node_info WHERE groupID = ? AND nodeStatus = 1" err := db.QueryRow(sql, groupID).Scan(&count) diff --git a/server/dao/console-sqlite3/plugin.go b/server/dao/console-sqlite3/plugin.go index 43df4dc782ef0b08e91c5fb5009551e97c93e660..f66beac063ee1c8de8988ed311163202d0c9da97 100644 --- a/server/dao/console-sqlite3/plugin.go +++ b/server/dao/console-sqlite3/plugin.go @@ -6,15 +6,33 @@ import ( "fmt" "strings" + "github.com/eolinker/goku-api-gateway/server/dao" + log "github.com/eolinker/goku-api-gateway/goku-log" - database2 "github.com/eolinker/goku-api-gateway/common/database" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +//PluginDao PluginDao +type PluginDao struct { + db *SQL.DB +} + +//NewPluginDao new PluginDao +func NewPluginDao() *PluginDao { + return &PluginDao{} +} + +//Create create +func (d *PluginDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.PluginDao = d + return &i, nil +} + //GetPluginInfo 获取插件配置信息 -func GetPluginInfo(pluginName string) (bool, *entity.Plugin, error) { - db := database2.GetConnection() +func (d *PluginDao) GetPluginInfo(pluginName string) (bool, *entity.Plugin, error) { + db := d.db sql := `SELECT pluginID,pluginName,pluginStatus,IFNULL(pluginConfig,""),pluginPriority,isStop,IFNULL(pluginDesc,""),IFNULL(version,""),pluginType FROM goku_plugin WHERE pluginName = ?;` plugin := &entity.Plugin{} err := db.QueryRow(sql, pluginName).Scan(&plugin.PluginID, &plugin.PluginName, &plugin.PluginStatus, &plugin.PluginConfig, &plugin.PluginIndex, &plugin.IsStop, &plugin.PluginDesc, &plugin.Version, &plugin.PluginType) @@ -25,8 +43,8 @@ func GetPluginInfo(pluginName string) (bool, *entity.Plugin, error) { } // GetPluginList 获取插件列表 -func GetPluginList(keyword string, condition int) (bool, []*entity.Plugin, error) { - db := database2.GetConnection() +func (d *PluginDao) GetPluginList(keyword string, condition int) (bool, []*entity.Plugin, error) { + db := d.db rule := make([]string, 0, 2) if keyword != "" { @@ -64,10 +82,10 @@ func GetPluginList(keyword string, condition int) (bool, []*entity.Plugin, error } // GetPluginCount 获取插件数量 -func GetPluginCount() int { +func (d *PluginDao) GetPluginCount() int { var count int sql := "SELECT COUNT(*) FROM goku_plugin;" - err := database2.GetConnection().QueryRow(sql).Scan(&count) + err := d.db.QueryRow(sql).Scan(&count) if err != nil { return 0 } @@ -75,8 +93,8 @@ func GetPluginCount() int { } // AddPlugin 新增插件信息 -func AddPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPriority, isStop, pluginType int) (bool, string, error) { - db := database2.GetConnection() +func (d *PluginDao) AddPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPriority, isStop, pluginType int) (bool, string, error) { + db := d.db stmt, err := db.Prepare(`INSERT INTO goku_plugin (pluginName,pluginConfig,pluginDesc,version,pluginStatus,pluginPriority,isStop,official,pluginType,isCheck) VALUES (?,?,?,?,?,?,?,?,?,0);`) if err != nil { return false, "[ERROR]Illegal SQL statement!", err @@ -90,8 +108,8 @@ func AddPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPrior } // EditPlugin 修改插件信息 -func EditPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPriority, isStop, pluginType int) (bool, string, error) { - db := database2.GetConnection() +func (d *PluginDao) EditPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPriority, isStop, pluginType int) (bool, string, error) { + db := d.db // 查询插件是否是官方插件 var sql string sql = "SELECT pluginType,official FROM goku_plugin WHERE pluginName = ?;" @@ -115,19 +133,14 @@ func EditPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPrio Tx.Rollback() return false, "[ERROR]Failed to update data!", err } - flag, err := EditPluginCache(pluginName, oldPluginType, pluginType, Tx) - if !flag { - Tx.Rollback() - return false, "[ERROR]Failed to update plugin cache!", err - } Tx.Commit() return true, "", nil } // DeletePlugin 删除插件信息 -func DeletePlugin(pluginName string) (bool, string, error) { - db := database2.GetConnection() +func (d *PluginDao) DeletePlugin(pluginName string) (bool, string, error) { + db := d.db var sql string sql = "SELECT pluginType,official FROM goku_plugin WHERE pluginName = ?;" var official string @@ -145,19 +158,14 @@ func DeletePlugin(pluginName string) (bool, string, error) { Tx.Rollback() return false, "[ERROR]Failed to delete data!", err } - flag, err := EditPluginCache(pluginName, pluginType, 5, Tx) - if !flag { - Tx.Rollback() - return false, "[ERROR]Failed to update plugin cache!", err - } Tx.Commit() return true, "", nil } //CheckIndexIsExist 判断插件ID是否存在 -func CheckIndexIsExist(pluginName string, pluginPriority int) (bool, error) { - db := database2.GetConnection() +func (d *PluginDao) CheckIndexIsExist(pluginName string, pluginPriority int) (bool, error) { + db := d.db sql := "SELECT pluginName FROM goku_plugin WHERE pluginPriority = ?;" var p string err := db.QueryRow(sql, pluginPriority).Scan(&p) @@ -171,8 +179,8 @@ func CheckIndexIsExist(pluginName string, pluginPriority int) (bool, error) { } //GetPluginConfig 获取插件配置及插件信息 -func GetPluginConfig(pluginName string) (bool, string, error) { - db := database2.GetConnection() +func (d *PluginDao) GetPluginConfig(pluginName string) (bool, string, error) { + db := d.db sql := `SELECT IFNULL(pluginConfig,"") FROM goku_plugin WHERE pluginName = ?` var pluginConfig string err := db.QueryRow(sql, pluginName).Scan(&pluginConfig) @@ -183,8 +191,8 @@ func GetPluginConfig(pluginName string) (bool, string, error) { } //CheckNameIsExist 检查插件名称是否存在 -func CheckNameIsExist(pluginName string) (bool, error) { - db := database2.GetConnection() +func (d *PluginDao) CheckNameIsExist(pluginName string) (bool, error) { + db := d.db sql := "SELECT pluginName FROM goku_plugin WHERE pluginName = ?;" var p string err := db.QueryRow(sql, pluginName).Scan(&p) @@ -195,8 +203,8 @@ func CheckNameIsExist(pluginName string) (bool, error) { } //EditPluginStatus 修改插件开启状态 -func EditPluginStatus(pluginName string, pluginStatus int) (bool, error) { - db := database2.GetConnection() +func (d *PluginDao) EditPluginStatus(pluginName string, pluginStatus int) (bool, error) { + db := d.db Tx, _ := db.Begin() isCheck := 1 @@ -218,8 +226,8 @@ func EditPluginStatus(pluginName string, pluginStatus int) (bool, error) { } //GetPluginListByPluginType 获取不同类型的插件列表 -func GetPluginListByPluginType(pluginType int) (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *PluginDao) GetPluginListByPluginType(pluginType int) (bool, []map[string]interface{}, error) { + db := d.db sql := `SELECT pluginID,pluginName,pluginDesc FROM goku_plugin WHERE pluginType = ? AND pluginStatus = 1;` rows, err := db.Query(sql, pluginType) if err != nil { @@ -250,8 +258,8 @@ func GetPluginListByPluginType(pluginType int) (bool, []map[string]interface{}, } //BatchStopPlugin 批量关闭插件 -func BatchStopPlugin(pluginNameList string) (bool, string, error) { - db := database2.GetConnection() +func (d *PluginDao) BatchStopPlugin(pluginNameList string) (bool, string, error) { + db := d.db Tx, _ := db.Begin() plugin := strings.Split(pluginNameList, ",") code := "" @@ -274,8 +282,8 @@ func BatchStopPlugin(pluginNameList string) (bool, string, error) { } //BatchStartPlugin 批量关闭插件 -func BatchStartPlugin(pluginNameList string) (bool, string, error) { - db := database2.GetConnection() +func (d *PluginDao) BatchStartPlugin(pluginNameList string) (bool, string, error) { + db := d.db Tx, _ := db.Begin() plugin := strings.Split(pluginNameList, ",") code := "" @@ -297,79 +305,9 @@ func BatchStartPlugin(pluginNameList string) (bool, string, error) { return true, "", nil } -//EditPluginCache 将插件配置写进缓存表中 -func EditPluginCache(pluginName string, oldPluginType, pluginType int, Tx *SQL.Tx) (bool, error) { - if oldPluginType == 1 { - // 获取策略ID列表 - sql := "SELECT strategyID FROM goku_conn_plugin_strategy WHERE pluginName = ?;" - strategyIDList := make([]string, 0) - rows, err := Tx.Query(sql, pluginName) - if err != nil { - return false, err - } - //延时关闭Rows - defer rows.Close() - //获取记录列 - - for rows.Next() { - var strategyID string - err = rows.Scan(&strategyID) - if err != nil { - return false, err - } - strategyIDList = append(strategyIDList, strategyID) - } - if len(strategyIDList) > 0 { - if oldPluginType != pluginType { - // 删除策略组插件 - _, err = Tx.Exec("DELETE FROM goku_conn_plugin_strategy WHERE strategyID AND pluginName = ?;", pluginName) - if err != nil { - return false, err - } - } - } - return true, nil - } else if oldPluginType == 2 { - // 获取策略ID列表 - sql := "SELECT strategyID,apiID FROM goku_conn_plugin_api WHERE pluginName = ?;" - connList := make([]map[string]interface{}, 0) - rows, err := Tx.Query(sql, pluginName) - if err != nil { - return false, err - } - //延时关闭Rows - defer rows.Close() - //获取记录列 - - for rows.Next() { - var strategyID string - var apiID int - err = rows.Scan(&strategyID, &apiID) - if err != nil { - return false, err - } - connList = append(connList, map[string]interface{}{ - "strategyID": strategyID, - "apiID": apiID, - }) - } - if len(connList) > 0 { - if oldPluginType != pluginType { - // 删除接口插件 - _, err = Tx.Exec("DELETE FROM goku_conn_plugin_api WHERE pluginName = ?;", pluginName) - if err != nil { - return false, err - } - } - } - return true, nil - } - return true, nil -} - //EditPluginCheckStatus 更新插件检测状态 -func EditPluginCheckStatus(pluginName string, isCheck int) (bool, string, error) { - db := database2.GetConnection() +func (d *PluginDao) EditPluginCheckStatus(pluginName string, isCheck int) (bool, string, error) { + db := d.db sql := "UPDATE goku_plugin SET isCheck = ? WHERE pluginName = ?;" _, err := db.Exec(sql, isCheck, pluginName) if err != nil { diff --git a/server/dao/console-sqlite3/project.go b/server/dao/console-sqlite3/project.go index 622e382204959ba98035fc5091a0499dfc585170..aee9551a9d3cd583b01b7ba5770ee975ef333078 100644 --- a/server/dao/console-sqlite3/project.go +++ b/server/dao/console-sqlite3/project.go @@ -1,20 +1,39 @@ package console_sqlite3 import ( + SQL "database/sql" "fmt" + "strconv" "strings" "time" - database2 "github.com/eolinker/goku-api-gateway/common/database" log "github.com/eolinker/goku-api-gateway/goku-log" + "github.com/eolinker/goku-api-gateway/server/dao" entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" ) +//ProjectDao ProjectDao +type ProjectDao struct { + db *SQL.DB +} + +//NewProjectDao new ProjectDao +func NewProjectDao() *ProjectDao { + return &ProjectDao{} +} + +//Create create +func (d *ProjectDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.ProjectDao = d + return &i, nil +} + //AddProject 新建项目 -func AddProject(projectName string) (bool, interface{}, error) { +func (d *ProjectDao) AddProject(projectName string) (bool, interface{}, error) { now := time.Now().Format("2006-01-02 15:04:05") - db := database2.GetConnection() + db := d.db sql := "INSERT INTO goku_gateway_project (projectName,createTime,updateTime) VALUES (?,?,?);" stmt, err := db.Prepare(sql) if err != nil { @@ -30,9 +49,9 @@ func AddProject(projectName string) (bool, interface{}, error) { } //EditProject 修改项目信息 -func EditProject(projectName string, projectID int) (bool, string, error) { +func (d *ProjectDao) EditProject(projectName string, projectID int) (bool, string, error) { now := time.Now().Format("2006-01-02 15:04:05") - db := database2.GetConnection() + db := d.db sql := "UPDATE goku_gateway_project SET projectName = ?,updateTime = ? WHERE projectID = ?;" stmt, err := db.Prepare(sql) if err != nil { @@ -47,8 +66,8 @@ func EditProject(projectName string, projectID int) (bool, string, error) { } //DeleteProject 修改项目信息 -func DeleteProject(projectID int) (bool, string, error) { - db := database2.GetConnection() +func (d *ProjectDao) DeleteProject(projectID int) (bool, string, error) { + db := d.db Tx, _ := db.Begin() // 获取项目分组列表 sql := "SELECT groupID FROM goku_gateway_api_group WHERE projectID = ?;" @@ -68,6 +87,7 @@ func DeleteProject(projectID int) (bool, string, error) { if err != nil { Tx.Rollback() log.Info(err.Error()) + return false, "", err } groupIDList += strconv.Itoa(groupID) + "," } @@ -144,8 +164,8 @@ func DeleteProject(projectID int) (bool, string, error) { } //BatchDeleteProject 批量删除项目 -func BatchDeleteProject(projectIDList string) (bool, string, error) { - db := database2.GetConnection() +func (d *ProjectDao) BatchDeleteProject(projectIDList string) (bool, string, error) { + db := d.db Tx, _ := db.Begin() // 获取项目分组列表 sql := "SELECT groupID FROM goku_gateway_api_group WHERE projectID IN (" + projectIDList + ");" @@ -167,6 +187,7 @@ func BatchDeleteProject(projectIDList string) (bool, string, error) { err = rows.Scan(&groupID) if err != nil { Tx.Rollback() + return false, "", err } groupIDList += strconv.Itoa(groupID) + "," } @@ -237,8 +258,8 @@ func BatchDeleteProject(projectIDList string) (bool, string, error) { } //GetProjectInfo 获取项目信息 -func GetProjectInfo(projectID int) (bool, entity.Project, error) { - db := database2.GetConnection() +func (d *ProjectDao) GetProjectInfo(projectID int) (bool, entity.Project, error) { + db := d.db var project entity.Project sql := "SELECT projectID,projectName,createTime,updateTime FROM goku_gateway_project WHERE projectID = ?;" err := db.QueryRow(sql, projectID).Scan(&project.ProjectID, &project.ProjectName, &project.CreateTime, &project.UpdateTime) @@ -249,7 +270,7 @@ func GetProjectInfo(projectID int) (bool, entity.Project, error) { } //GetProjectList 获取项目列表 -func GetProjectList(keyword string) (bool, []*entity.Project, error) { +func (d *ProjectDao) GetProjectList(keyword string) (bool, []*entity.Project, error) { sql := "SELECT `projectID`,`projectName`,`updateTime` FROM `goku_gateway_project` %s ORDER BY `updateTime` DESC;" keywordValue := strings.Trim(keyword, "%") @@ -264,7 +285,7 @@ func GetProjectList(keyword string) (bool, []*entity.Project, error) { } } sql = fmt.Sprintf(sql, where) - db := database2.GetConnection() + db := d.db rows, err := db.Query(sql, arg...) if err != nil { return false, nil, err @@ -286,8 +307,8 @@ func GetProjectList(keyword string) (bool, []*entity.Project, error) { } //CheckProjectIsExist 检查项目是否存在 -func CheckProjectIsExist(projectID int) (bool, error) { - db := database2.GetConnection() +func (d *ProjectDao) CheckProjectIsExist(projectID int) (bool, error) { + db := d.db sql := "SELECT projectID FROM goku_gateway_project WHERE projectID = ?;" var id int err := db.QueryRow(sql, projectID).Scan(&id) @@ -298,8 +319,8 @@ func CheckProjectIsExist(projectID int) (bool, error) { } //GetAPIListFromProjectNotInStrategy 获取项目列表中没有被策略组绑定的接口 -func GetAPIListFromProjectNotInStrategy() (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *ProjectDao) GetAPIListFromProjectNotInStrategy() (bool, []map[string]interface{}, error) { + db := d.db sql := "SELECT projectID,projectName FROM goku_gateway_project;" projectRows, err := db.Query(sql) if err != nil { diff --git a/server/dao/console-sqlite3/register.go b/server/dao/console-sqlite3/register.go new file mode 100644 index 0000000000000000000000000000000000000000..21ee9451ad51830624d4f353d041e9b9b271be9f --- /dev/null +++ b/server/dao/console-sqlite3/register.go @@ -0,0 +1,77 @@ +package console_sqlite3 + +import ( + "database/sql" + "io/ioutil" + "log" + "strings" + + "github.com/eolinker/goku-api-gateway/common/pdao" + config_log "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/config-log" + dao_balance "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-balance" + dao_balance_update "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-balance-update" + dao_service "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-service" + dao_version_config "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/dao-version-config" + "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/internal/goku311" + "github.com/eolinker/goku-api-gateway/server/dao/console-sqlite3/updater" +) + +//DBDriver db驱动类型 +const DBDriver = "sqlite3" + +//DoRegister 注册数据库 +func DoRegister() { + + pdao.RegisterDBBuilder(DBDriver, new(TableBuilder)) + goku311.RegisterUpdate() + + pdao.RegisterDao(DBDriver, NewAPIDao(), NewAPIGroupDao(), NewAPIPluginDao(), NewAPIStrategyDao()) + pdao.RegisterDao(DBDriver, NewAuthDao()) + pdao.RegisterDao(DBDriver, NewClusterDao()) + pdao.RegisterDao(DBDriver, NewGatewayDao()) + pdao.RegisterDao(DBDriver, NewGuestDao()) + pdao.RegisterDao(DBDriver, NewImportDao()) + pdao.RegisterDao(DBDriver, NewMonitorModulesDao()) + pdao.RegisterDao(DBDriver, NewNodeDao(), NewNodeGroupDao()) + pdao.RegisterDao(DBDriver, NewPluginDao()) + pdao.RegisterDao(DBDriver, NewProjectDao()) + pdao.RegisterDao(DBDriver, NewStrategyDao(), NewStrategyGroupDao(), NewStrategyPluginDao()) + pdao.RegisterDao(DBDriver, NewUserDao()) + pdao.RegisterDao(DBDriver, NewVersionDao()) + + pdao.RegisterDao(DBDriver, config_log.NewConfigLogDao()) + pdao.RegisterDao(DBDriver, dao_balance.NewBalanceDao()) + pdao.RegisterDao(DBDriver, dao_balance_update.NewBalanceUpdateDao()) + pdao.RegisterDao(DBDriver, dao_service.NewServiceDao()) + pdao.RegisterDao(DBDriver, dao_version_config.NewVersionConfigDao()) + pdao.RegisterDao(DBDriver, updater.NewUpdaterDao()) +} + +//TableBuilder tableBuilder +type TableBuilder struct { +} + +//Build build +func (t *TableBuilder) Build(db *sql.DB) error { + + userDao := NewUserDao() + userDao.db = db + + _, err := userDao.CheckSuperAdminCount() + if err != nil { + content, err := ioutil.ReadFile("sql/goku_ce.sql") + sqls := strings.Split(string(content), ";") + Tx, _ := db.Begin() + for _, sql := range sqls { + _, err = Tx.Exec(sql) + if err != nil { + Tx.Rollback() + log.Panic("InitTable error:", err, "\t sql:", sql) + return err + } + } + Tx.Commit() + } + + return nil +} diff --git a/server/dao/console-sqlite3/strategy.go b/server/dao/console-sqlite3/strategy.go index e16b0fff2263d07306a22cfa57f8e6095b573dca..8855cb0bc76aae1be301880bdb51611aa6ac8be3 100644 --- a/server/dao/console-sqlite3/strategy.go +++ b/server/dao/console-sqlite3/strategy.go @@ -1,18 +1,38 @@ package console_sqlite3 import ( + "database/sql" "fmt" "strings" "time" - database2 "github.com/eolinker/goku-api-gateway/common/database" + "github.com/eolinker/goku-api-gateway/server/dao" + entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" "github.com/eolinker/goku-api-gateway/utils" ) -//AddStrategy 新增策略组 -func AddStrategy(strategyName string, groupID int) (bool, string, error) { - db := database2.GetConnection() +//StrategyDao StrategyDao +type StrategyDao struct { + db *sql.DB +} + +//NewStrategyDao new StrategyDao +func NewStrategyDao() *StrategyDao { + return &StrategyDao{} +} + +//Create create +func (d *StrategyDao) Create(db *sql.DB) (interface{}, error) { + d.db = db + var i dao.StrategyDao = d + + return &i, nil +} + +//AddStrategy 新增策略组 +func (d *StrategyDao) AddStrategy(strategyName string, groupID, userID int) (bool, string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") // 随机生成字符串 sqlCode := "SELECT strategyID FROM goku_gateway_strategy WHERE strategyID = ?" @@ -29,8 +49,8 @@ func AddStrategy(strategyName string, groupID int) (bool, string, error) { if strategyID == "" { return false, "[ERROR]Empty strategy id !", nil } - stmt, err := db.Prepare(`INSERT INTO goku_gateway_strategy (strategyID,strategyName,updateTime,createTime,groupID) VALUES (?,?,?,?,?);`) - defer stmt.Close() + stmt, err := db.Prepare(`INSERT INTO goku_gateway_strategy (strategyID,strategyName,updateTime,createTime,groupID) VALUES (?,?,?,?,?)`) + if err != nil { return false, "[ERROR]Illegal SQL statement!", err } @@ -43,10 +63,10 @@ func AddStrategy(strategyName string, groupID int) (bool, string, error) { } //EditStrategy 修改策略组信息 -func EditStrategy(strategyID, strategyName string, groupID int) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyDao) EditStrategy(strategyID, strategyName string, groupID, userID int) (bool, string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") - stmt, err := db.Prepare(`UPDATE goku_gateway_strategy SET strategyName = ?,groupID = ?,updateTime = ? WHERE strategyID = ?;`) + stmt, err := db.Prepare(`UPDATE goku_gateway_strategy SET strategyName = ?,groupID = ?,updateTime = ? WHERE strategyID = ?`) if err != nil { return false, "[ERROR]Illegal SQL statement!", err } @@ -59,8 +79,8 @@ func EditStrategy(strategyID, strategyName string, groupID int) (bool, string, e } //DeleteStrategy 删除策略组 -func DeleteStrategy(strategyID string) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyDao) DeleteStrategy(strategyID string) (bool, string, error) { + db := d.db Tx, _ := db.Begin() _, err := Tx.Exec(`DELETE FROM goku_gateway_strategy WHERE strategyID = ?;`, strategyID) if err != nil { @@ -96,9 +116,7 @@ func DeleteStrategy(strategyID string) (bool, string, error) { } // GetStrategyList 获取策略组列表 -func GetStrategyList(groupID int, keyword string, condition int) (bool, []*entity.Strategy, error) { - db := database2.GetConnection() - +func (d *StrategyDao) GetStrategyList(groupID int, keyword string, condition, page, pageSize int) (bool, []*entity.Strategy, int, error) { rule := make([]string, 0, 2) rule = append(rule, "A.strategyType != 1") @@ -118,10 +136,11 @@ func GetStrategyList(groupID int, keyword string, condition int) (bool, []*entit if len(rule) > 0 { ruleStr += "WHERE " + strings.Join(rule, " AND ") } - sql := fmt.Sprintf("SELECT A.strategyID,A.strategyName,IFNULL(A.updateTime,''),IFNULL(A.createTime,''),A.enableStatus,A.groupID,IFNULL(B.groupName,'未分组') FROM goku_gateway_strategy A LEFT JOIN goku_gateway_strategy_group B ON A.groupID = B.groupID %s ORDER BY A.updateTime DESC;", ruleStr) - rows, err := db.Query(sql) + sql := fmt.Sprintf("SELECT A.strategyID,A.strategyName,IFNULL(A.updateTime,''),IFNULL(A.createTime,''),A.enableStatus,A.groupID,IFNULL(B.groupName,'未分组') FROM goku_gateway_strategy A LEFT JOIN goku_gateway_strategy_group B ON A.groupID = B.groupID %s", ruleStr) + count := getCountSQL(d.db, sql) + rows, err := getPageSQL(d.db, sql, "A.updateTime", "DESC", page, pageSize) if err != nil { - return false, nil, err + return false, make([]*entity.Strategy, 0), 0, err } //延时关闭Rows defer rows.Close() @@ -131,17 +150,17 @@ func GetStrategyList(groupID int, keyword string, condition int) (bool, []*entit var strategy entity.Strategy err = rows.Scan(&strategy.StrategyID, &strategy.StrategyName, &strategy.UpdateTime, &strategy.CreateTime, &strategy.EnableStatus, &strategy.GroupID, &strategy.GroupName) if err != nil { - return false, nil, err + return false, make([]*entity.Strategy, 0), 0, err } strategyList = append(strategyList, &strategy) } - return true, strategyList, nil + return true, strategyList, count, nil } // GetOpenStrategy 获取策略组列表 -func GetOpenStrategy() (bool, *entity.Strategy, error) { +func (d *StrategyDao) GetOpenStrategy() (bool, *entity.Strategy, error) { var openStrategy entity.Strategy - db := database2.GetConnection() + db := d.db sql := `SELECT strategyID,strategyName,IFNULL(updateTime,""),IFNULL(createTime,""),enableStatus,strategyType FROM goku_gateway_strategy WHERE strategyType = 1 ORDER BY updateTime DESC;` err := db.QueryRow(sql).Scan(&openStrategy.StrategyID, &openStrategy.StrategyName, &openStrategy.UpdateTime, &openStrategy.CreateTime, &openStrategy.EnableStatus, &openStrategy.StrategyType) if err != nil { @@ -152,8 +171,8 @@ func GetOpenStrategy() (bool, *entity.Strategy, error) { } //GetStrategyInfo 获取策略组信息 -func GetStrategyInfo(strategyID string) (bool, *entity.Strategy, error) { - db := database2.GetConnection() +func (d *StrategyDao) GetStrategyInfo(strategyID string) (bool, *entity.Strategy, error) { + db := d.db sql := `SELECT strategyID,strategyName,IFNULL(updateTime,''),strategyType,enableStatus FROM goku_gateway_strategy WHERE strategyID = ?;` strategy := new(entity.Strategy) err := db.QueryRow(sql, strategyID).Scan(&strategy.StrategyID, &strategy.StrategyName, &strategy.UpdateTime, &strategy.StrategyType, &strategy.EnableStatus) @@ -164,8 +183,8 @@ func GetStrategyInfo(strategyID string) (bool, *entity.Strategy, error) { } //CheckStrategyIsExist 检查策略组ID是否存在 -func CheckStrategyIsExist(strategyID string) (bool, error) { - db := database2.GetConnection() +func (d *StrategyDao) CheckStrategyIsExist(strategyID string) (bool, error) { + db := d.db sql := "SELECT strategyID FROM goku_gateway_strategy WHERE strategyID = ?;" var id string err := db.QueryRow(sql, strategyID).Scan(&id) @@ -176,8 +195,8 @@ func CheckStrategyIsExist(strategyID string) (bool, error) { } //BatchEditStrategyGroup 批量修改策略组分组 -func BatchEditStrategyGroup(strategyIDList string, groupID int) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyDao) BatchEditStrategyGroup(strategyIDList string, groupID int) (bool, string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") Tx, _ := db.Begin() strategy := strings.Split(strategyIDList, ",") @@ -199,8 +218,8 @@ func BatchEditStrategyGroup(strategyIDList string, groupID int) (bool, string, e } //BatchDeleteStrategy 批量修改策略组 -func BatchDeleteStrategy(strategyIDList string) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyDao) BatchDeleteStrategy(strategyIDList string) (bool, string, error) { + db := d.db Tx, _ := db.Begin() strategy := strings.Split(strategyIDList, ",") code := "" @@ -247,8 +266,8 @@ func BatchDeleteStrategy(strategyIDList string) (bool, string, error) { } //CheckIsOpenStrategy 判断是否是开放策略 -func CheckIsOpenStrategy(strategyID string) bool { - db := database2.GetConnection() +func (d *StrategyDao) CheckIsOpenStrategy(strategyID string) bool { + db := d.db var strategyType int sql := "SELECT strategyType FROM goku_gateway_strategy WHERE strategyID = ?;" err := db.QueryRow(sql, strategyID).Scan(&strategyType) @@ -262,8 +281,8 @@ func CheckIsOpenStrategy(strategyID string) bool { } //BatchUpdateStrategyEnableStatus 更新策略启动状态 -func BatchUpdateStrategyEnableStatus(strategyIDList string, enableStatus int) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyDao) BatchUpdateStrategyEnableStatus(strategyIDList string, enableStatus int) (bool, string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") strategy := strings.Split(strategyIDList, ",") code := "" @@ -290,8 +309,8 @@ func BatchUpdateStrategyEnableStatus(strategyIDList string, enableStatus int) (b } // GetBalanceListInStrategy 获取在策略中的负载列表 -func GetBalanceListInStrategy(strategyID string, balanceType int) (bool, []string, error) { - db := database2.GetConnection() +func (d *StrategyDao) GetBalanceListInStrategy(strategyID string, balanceType int) (bool, []string, error) { + db := d.db sql := "SELECT DISTINCT(IFNULL(A.balanceName,'')) FROM goku_gateway_api A INNER JOIN goku_conn_strategy_api B ON A.apiID = B.apiID WHERE B.strategyID = ?;" if balanceType == 1 { @@ -320,8 +339,8 @@ func GetBalanceListInStrategy(strategyID string, balanceType int) (bool, []strin } // CopyStrategy 复制策略 -func CopyStrategy(strategyID string, newStrategyID string, userID int) (string, error) { - db := database2.GetConnection() +func (d *StrategyDao) CopyStrategy(strategyID string, newStrategyID string, userID int) (string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") sql := "INSERT INTO goku_conn_strategy_api (strategyID,apiID,apiMonitorStatus,strategyMonitorStatus,target,updateTime) SELECT ?,apiID,apiMonitorStatus,strategyMonitorStatus,target,? FROM goku_conn_strategy_api WHERE strategyID = ?" _, err := db.Exec(sql, newStrategyID, now, strategyID) @@ -342,21 +361,9 @@ func CopyStrategy(strategyID string, newStrategyID string, userID int) (string, return newStrategyID, nil } -//GetOpenStrategyCount 获取开放策略数量 -func GetOpenStrategyCount() int { - db := database2.GetConnection() - var count int - sql := "SELECT COUNT(*) FROM goku_gateway_strategy WHERE strategyType = 1" - err := db.QueryRow(sql).Scan(&count) - if err != nil { - return 0 - } - return count -} - //GetStrategyIDList 获取策略ID列表 -func GetStrategyIDList(groupID int, keyword string, condition int) (bool, []string, error) { - db := database2.GetConnection() +func (d *StrategyDao) GetStrategyIDList(groupID int, keyword string, condition int) (bool, []string, error) { + db := d.db rule := make([]string, 0, 2) rule = append(rule, fmt.Sprintf("A.strategyType != 1")) diff --git a/server/dao/console-sqlite3/strategyGroup.go b/server/dao/console-sqlite3/strategyGroup.go index 3964b49e973eca8d79c7999c89a736602a8cad36..d693bfdf018895279417220a7e856f9d05dc715b 100644 --- a/server/dao/console-sqlite3/strategyGroup.go +++ b/server/dao/console-sqlite3/strategyGroup.go @@ -1,12 +1,32 @@ package console_sqlite3 import ( - database2 "github.com/eolinker/goku-api-gateway/common/database" + "database/sql" + + "github.com/eolinker/goku-api-gateway/server/dao" ) +//StrategyGroupDao StrategyGroupDao +type StrategyGroupDao struct { + db *sql.DB +} + +//NewStrategyGroupDao new StrategyGroupDao +func NewStrategyGroupDao() *StrategyGroupDao { + return &StrategyGroupDao{} +} + +//Create create +func (d *StrategyGroupDao) Create(db *sql.DB) (interface{}, error) { + d.db = db + var i dao.StrategyGroupDao = d + + return &i, nil +} + //AddStrategyGroup 新建策略组分组 -func AddStrategyGroup(groupName string) (bool, interface{}, error) { - db := database2.GetConnection() +func (d *StrategyGroupDao) AddStrategyGroup(groupName string) (bool, interface{}, error) { + db := d.db sql := "INSERT INTO goku_gateway_strategy_group (groupName) VALUES (?);" stmt, err := db.Prepare(sql) if err != nil { @@ -25,8 +45,8 @@ func AddStrategyGroup(groupName string) (bool, interface{}, error) { } //EditStrategyGroup 修改策略组分组 -func EditStrategyGroup(groupName string, groupID int) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyGroupDao) EditStrategyGroup(groupName string, groupID int) (bool, string, error) { + db := d.db sql := "UPDATE goku_gateway_strategy_group SET groupName = ? WHERE groupID = ?;" stmt, err := db.Prepare(sql) if err != nil { @@ -41,8 +61,8 @@ func EditStrategyGroup(groupName string, groupID int) (bool, string, error) { } //DeleteStrategyGroup 删除策略组分组 -func DeleteStrategyGroup(groupID int) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyGroupDao) DeleteStrategyGroup(groupID int) (bool, string, error) { + db := d.db // 查询该分组下所有策略组ID sql := "SELECT strategyID FROM goku_gateway_strategy WHERE groupID = ?;" rows, err := db.Query(sql, groupID) @@ -108,8 +128,8 @@ func DeleteStrategyGroup(groupID int) (bool, string, error) { } //GetStrategyGroupList 获取策略组分组列表 -func GetStrategyGroupList() (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *StrategyGroupDao) GetStrategyGroupList() (bool, []map[string]interface{}, error) { + db := d.db sql := "SELECT groupID,groupName,groupType FROM goku_gateway_strategy_group WHERE groupType = 0;" rows, err := db.Query(sql) if err != nil { @@ -137,8 +157,8 @@ func GetStrategyGroupList() (bool, []map[string]interface{}, error) { } //CheckIsOpenGroup 判断是否是开放分组 -func CheckIsOpenGroup(groupID int) bool { - db := database2.GetConnection() +func (d *StrategyGroupDao) CheckIsOpenGroup(groupID int) bool { + db := d.db var groupType int sql := "SELECT groupType FROM goku_gateway_strategy_group WHERE groupID = ?;" err := db.QueryRow(sql, groupID).Scan(&groupType) diff --git a/server/dao/console-sqlite3/strategyPlugin.go b/server/dao/console-sqlite3/strategyPlugin.go index 1cae721a6258f9c25e70f2c882bed5232bba840a..6605d22131fdff5e73818cc00da7cb1047f67d20 100644 --- a/server/dao/console-sqlite3/strategyPlugin.go +++ b/server/dao/console-sqlite3/strategyPlugin.go @@ -7,14 +7,30 @@ import ( "strings" "time" - database2 "github.com/eolinker/goku-api-gateway/common/database" + "github.com/eolinker/goku-api-gateway/server/dao" ) -var strategyPlugins = []string{"goku-oauth2_auth", "goku-rate_limiting", "goku-replay_attack_defender"} +//StrategyPluginDao StrategyPluginDao +type StrategyPluginDao struct { + db *SQL.DB +} + +//NewStrategyPluginDao new StrategyPluginDao +func NewStrategyPluginDao() *StrategyPluginDao { + return &StrategyPluginDao{} +} + +//Create create +func (d *StrategyPluginDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.StrategyPluginDao = d + + return &i, nil +} //AddPluginToStrategy 新增策略组插件 -func AddPluginToStrategy(pluginName, config, strategyID string) (bool, interface{}, error) { - db := database2.GetConnection() +func (d *StrategyPluginDao) AddPluginToStrategy(pluginName, config, strategyID string) (bool, interface{}, error) { + db := d.db // 查询接口是否添加该插件 sql := "SELECT strategyID FROM goku_conn_plugin_strategy WHERE strategyID = ? AND pluginName = ?;" var id string @@ -47,8 +63,8 @@ func AddPluginToStrategy(pluginName, config, strategyID string) (bool, interface } //EditStrategyPluginConfig 新增策略组插件配置 -func EditStrategyPluginConfig(pluginName, config, strategyID string) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyPluginDao) EditStrategyPluginConfig(pluginName, config, strategyID string) (bool, string, error) { + db := d.db // 查询策略组是否添加该插件 t := time.Now() now := t.Format("2006-01-02 15:04:05") @@ -77,8 +93,8 @@ func EditStrategyPluginConfig(pluginName, config, strategyID string) (bool, stri } // GetStrategyPluginList 获取策略插件列表 -func GetStrategyPluginList(strategyID, keyword string, condition int) (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *StrategyPluginDao) GetStrategyPluginList(strategyID, keyword string, condition int) (bool, []map[string]interface{}, error) { + db := d.db rule := make([]string, 0, 3) @@ -125,8 +141,8 @@ func GetStrategyPluginList(strategyID, keyword string, condition int) (bool, []m } //GetStrategyPluginConfig 通过策略组ID获取配置信息 -func GetStrategyPluginConfig(strategyID, pluginName string) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyPluginDao) GetStrategyPluginConfig(strategyID, pluginName string) (bool, string, error) { + db := d.db sql := "SELECT pluginConfig FROM goku_conn_plugin_strategy WHERE strategyID = ? AND pluginName = ?;" var p string err := db.QueryRow(sql, strategyID, pluginName).Scan(&p) @@ -141,8 +157,8 @@ func GetStrategyPluginConfig(strategyID, pluginName string) (bool, string, error } //CheckPluginIsExistInStrategy 检查策略组是否绑定插件 -func CheckPluginIsExistInStrategy(strategyID, pluginName string) (bool, error) { - db := database2.GetConnection() +func (d *StrategyPluginDao) CheckPluginIsExistInStrategy(strategyID, pluginName string) (bool, error) { + db := d.db sql := "SELECT strategyID FROM goku_conn_plugin_strategy WHERE strategyID = ? AND pluginName = ?;" var id string err := db.QueryRow(sql, strategyID, pluginName).Scan(&id) @@ -153,8 +169,8 @@ func CheckPluginIsExistInStrategy(strategyID, pluginName string) (bool, error) { } //GetStrategyPluginStatus 检查策略组插件是否开启 -func GetStrategyPluginStatus(strategyID, pluginName string) (bool, error) { - db := database2.GetConnection() +func (d *StrategyPluginDao) GetStrategyPluginStatus(strategyID, pluginName string) (bool, error) { + db := d.db sql := "SELECT pluginStatus FROM goku_conn_plugin_strategy WHERE strategyID = ? AND pluginName = ?;" var pluginStatus int err := db.QueryRow(sql, strategyID, pluginName).Scan(&pluginStatus) @@ -168,8 +184,8 @@ func GetStrategyPluginStatus(strategyID, pluginName string) (bool, error) { } //GetConnIDFromStrategyPlugin 获取Connid -func GetConnIDFromStrategyPlugin(pluginName, strategyID string) (bool, int, error) { - db := database2.GetConnection() +func (d *StrategyPluginDao) GetConnIDFromStrategyPlugin(pluginName, strategyID string) (bool, int, error) { + db := d.db sql := "SELECT connID FROM goku_conn_plugin_strategy WHERE strategyID = ? AND pluginName = ?;" var connID int err := db.QueryRow(sql, strategyID, pluginName).Scan(&connID) @@ -180,8 +196,8 @@ func GetConnIDFromStrategyPlugin(pluginName, strategyID string) (bool, int, erro } //BatchEditStrategyPluginStatus 批量修改策略组插件状态 -func BatchEditStrategyPluginStatus(connIDList, strategyID string, pluginStatus int) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyPluginDao) BatchEditStrategyPluginStatus(connIDList, strategyID string, pluginStatus int) (bool, string, error) { + db := d.db t := time.Now() now := t.Format("2006-01-02 15:04:05") updateTag := t.Format("20060102150405") @@ -204,8 +220,8 @@ func BatchEditStrategyPluginStatus(connIDList, strategyID string, pluginStatus i } //BatchDeleteStrategyPlugin 批量删除策略组插件 -func BatchDeleteStrategyPlugin(connIDList, strategyID string) (bool, string, error) { - db := database2.GetConnection() +func (d *StrategyPluginDao) BatchDeleteStrategyPlugin(connIDList, strategyID string) (bool, string, error) { + db := d.db now := time.Now().Format("2006-01-02 15:04:05") Tx, _ := db.Begin() sql := "DELETE FROM goku_conn_plugin_strategy WHERE connID IN (" + connIDList + ");" @@ -226,8 +242,8 @@ func BatchDeleteStrategyPlugin(connIDList, strategyID string) (bool, string, err } //CheckStrategyPluginIsExistByConnIDList 通过connIDList判断插件是否存在 -func CheckStrategyPluginIsExistByConnIDList(connIDList, pluginName string) (bool, error) { - db := database2.GetConnection() +func (d *StrategyPluginDao) CheckStrategyPluginIsExistByConnIDList(connIDList, pluginName string) (bool, error) { + db := d.db sql := "SELECT pluginStatus FROM goku_conn_plugin_strategy WHERE connID IN (" + connIDList + ") AND pluginName = ?;" var pluginStatus int err := db.QueryRow(sql, pluginName).Scan(&pluginStatus) diff --git a/server/dao/console-sqlite3/updater/check.go b/server/dao/console-sqlite3/updater/check.go index e1b20ceb92cd582c1fefd9e915f53c1a1408dc86..f09997f69dad4b034d285770e3554630052299f8 100644 --- a/server/dao/console-sqlite3/updater/check.go +++ b/server/dao/console-sqlite3/updater/check.go @@ -3,13 +3,11 @@ package updater import ( SQL "database/sql" "fmt" - - "github.com/eolinker/goku-api-gateway/common/database" ) //IsTableExist 检查table是否存在 -func IsTableExist(name string) bool { - db := database.GetConnection() +func (d *Dao)IsTableExist(name string) bool { + db := d.db selectType := "" sql := "SELECT type FROM sqlite_master WHERE `type` = 'table' AND `name` = ?" err := db.QueryRow(sql, name).Scan(&selectType) @@ -20,8 +18,8 @@ func IsTableExist(name string) bool { } //IsColumnExist 检查列是否存在 -func IsColumnExist(name string, column string) bool { - db := database.GetConnection() +func (d *Dao)IsColumnExist(name string, column string) bool { + db := d.db sql := fmt.Sprintf("PRAGMA table_info(%s)", name) rows, err := db.Query(sql) if err != nil { diff --git a/server/dao/console-sqlite3/updater/dao.go b/server/dao/console-sqlite3/updater/dao.go new file mode 100644 index 0000000000000000000000000000000000000000..d3e96ce2ddea1430a76920b97122d60ce26a79bc --- /dev/null +++ b/server/dao/console-sqlite3/updater/dao.go @@ -0,0 +1,30 @@ +package updater + +import ( + "database/sql" + + "github.com/eolinker/goku-api-gateway/server/dao" +) + +//Dao Dao +type Dao struct { + db *sql.DB +} + +//NewUpdaterDaoWidthDB NewUpdaterDaoWidthDB +func NewUpdaterDaoWidthDB(db *sql.DB) *Dao { + return &Dao{db: db} +} + +//NewUpdaterDao NewUpdaterDao +func NewUpdaterDao() *Dao { + return &Dao{} +} + +//Create create +func (d *Dao) Create(db *sql.DB) (interface{}, error) { + d.db = db + + i := dao.UpdaterDao(d) + return &i, nil +} diff --git a/server/dao/console-sqlite3/updater/get.go b/server/dao/console-sqlite3/updater/get.go index 5e3a060e7b3ccbe5abc4f86d97766d54f9d6e3a8..a0dd6c1ba9cf47686d0279038aa1db6e6a3c011a 100644 --- a/server/dao/console-sqlite3/updater/get.go +++ b/server/dao/console-sqlite3/updater/get.go @@ -1,10 +1,8 @@ package updater -import "github.com/eolinker/goku-api-gateway/common/database" - //GetTableVersion 获取当前表版本号 -func GetTableVersion(name string) string { - db := database.GetConnection() +func (d *Dao)GetTableVersion(name string) string { + db := d.db version := "" sql := "SELECT version FROM goku_table_version WHERE tableName = ?" err := db.QueryRow(sql, name).Scan(&version) @@ -15,8 +13,8 @@ func GetTableVersion(name string) string { } //UpdateTableVersion 更新表版本号 -func UpdateTableVersion(name, version string) error { - db := database.GetConnection() +func (d *Dao)UpdateTableVersion(name, version string) error { + db := d.db sql := "REPLACE INTO goku_table_version (tableName,version) VALUES (?,?);" _, err := db.Exec(sql, name, version) if err != nil { @@ -26,8 +24,8 @@ func UpdateTableVersion(name, version string) error { } //GetGokuVersion 获取goku当前版本号 -func GetGokuVersion() string { - db := database.GetConnection() +func (d *Dao)GetGokuVersion() string { + db := d.db version := "" sql := "SELECT version FROM goku_version;" err := db.QueryRow(sql).Scan(&version) @@ -38,8 +36,8 @@ func GetGokuVersion() string { } //SetGokuVersion 设置goku版本号 -func SetGokuVersion(version string) error { - db := database.GetConnection() +func (d *Dao)SetGokuVersion(version string) error { + db := d.db sql := "REPLACE INTO goku_version (sol,version) VALUES (?,?);" _, err := db.Exec(sql, 1, version) if err != nil { diff --git a/server/dao/console-sqlite3/user.go b/server/dao/console-sqlite3/user.go index 463e064b2e86dbd5541de13dee84dbd2174b3575..c3cd057d0f9e65a16d9a6899679ba55ba0ae66e6 100644 --- a/server/dao/console-sqlite3/user.go +++ b/server/dao/console-sqlite3/user.go @@ -1,18 +1,38 @@ package console_sqlite3 import ( + "database/sql" "encoding/json" "errors" - database2 "github.com/eolinker/goku-api-gateway/common/database" + "github.com/eolinker/goku-api-gateway/server/dao" + "github.com/eolinker/goku-api-gateway/utils" ) -type permissionsJSON map[string]bool +type permissionsJSON = map[string]bool + +//UserDao UserDao +type UserDao struct { + db *sql.DB +} + +//NewUserDao new UserDao +func NewUserDao() *UserDao { + return &UserDao{} +} + +//Create create +func (d *UserDao) Create(db *sql.DB) (interface{}, error) { + d.db = db + var i dao.UserDao = d + + return &i, nil +} //EditPassword 修改账户信息 -func EditPassword(oldPassword, newPassword string, userID int) (bool, string, error) { - db := database2.GetConnection() +func (d *UserDao) EditPassword(oldPassword, newPassword string, userID int) (bool, string, error) { + db := d.db // 查询旧密码是否存在 var loginCall, password string oldPassword = utils.Md5(oldPassword) @@ -41,8 +61,8 @@ func EditPassword(oldPassword, newPassword string, userID int) (bool, string, er } //GetUserInfo 获取账户信息 -func GetUserInfo(userID int) (bool, interface{}, error) { - db := database2.GetConnection() +func (d *UserDao) GetUserInfo(userID int) (bool, interface{}, error) { + db := d.db sql := `SELECT loginCall,IFNULL(remark,""),IFNULL(permissions,""),userType FROM goku_admin WHERE userID = ?;` var loginCall, remark, permissions string var userType int @@ -69,8 +89,8 @@ func GetUserInfo(userID int) (bool, interface{}, error) { } //GetUserType 获取用户类型 -func GetUserType(userID int) (bool, interface{}, error) { - db := database2.GetConnection() +func (d *UserDao) GetUserType(userID int) (bool, interface{}, error) { + db := d.db sql := "SELECT userType FROM goku_admin WHERE userID = ?;" var userType int err := db.QueryRow(sql, userID).Scan(&userType) @@ -81,8 +101,8 @@ func GetUserType(userID int) (bool, interface{}, error) { } //CheckUserIsAdmin 判断是否是管理员 -func CheckUserIsAdmin(userID int) (bool, string, error) { - db := database2.GetConnection() +func (d *UserDao) CheckUserIsAdmin(userID int) (bool, string, error) { + db := d.db sql := "SELECT userType FROM goku_admin WHERE userID = ? AND (userType = 0 OR userType = 1);" var userType int err := db.QueryRow(sql, userID).Scan(&userType) @@ -93,8 +113,8 @@ func CheckUserIsAdmin(userID int) (bool, string, error) { } //CheckUserIsSuperAdmin 判断是否是超级管理员 -func CheckUserIsSuperAdmin(userID int) (bool, string, error) { - db := database2.GetConnection() +func (d *UserDao) CheckUserIsSuperAdmin(userID int) (bool, string, error) { + db := d.db sql := "SELECT userType FROM goku_admin WHERE userID = ? AND userType = 0;" var userType int err := db.QueryRow(sql, userID).Scan(&userType) @@ -105,8 +125,8 @@ func CheckUserIsSuperAdmin(userID int) (bool, string, error) { } //CheckSuperAdminCount 获取超级管理员数量 -func CheckSuperAdminCount() (int, error) { - db := database2.GetConnection() +func (d *UserDao) CheckSuperAdminCount() (int, error) { + db := d.db sql := "SELECT count(*) FROM goku_admin WHERE userType = 0;" count := 0 err := db.QueryRow(sql).Scan(&count) @@ -117,44 +137,9 @@ func CheckSuperAdminCount() (int, error) { return count, nil } -//CheckUserPermission 检查用户权限 -func CheckUserPermission(operationType, operation string, userID int) (bool, string, error) { - db := database2.GetConnection() - var permissions string - var userType int - sql := `SELECT userType,IFNULL(permissions,"") FROM goku_admin WHERE userID = ?;` - err := db.QueryRow(sql, userID).Scan(&userType, &permissions) - if err != nil { - return false, "[ERROR]This user does not exist!", err - } - if userType == 0 || userType == 1 { - return true, "", nil - } - if permissions == "" { - return false, "[ERROR]This user does not assigned permission", nil - } - permissionsMap := make(map[string]permissionsJSON) - err = json.Unmarshal([]byte(permissions), &permissionsMap) - if err != nil { - return false, "[ERROR]Fail to parse json!!", err - } - value, ok := permissionsMap[operationType] - if !ok { - return false, "[ERROR]Operation type does not exist!", nil - } - v, temp := value[operation] - if !temp { - return false, "[ERROR]Operation does not exist!!", nil - } - if !v { - return false, "[ERROR]No permissions!", nil - } - return true, "", nil -} - //GetUserListWithPermission 获取具有编辑权限的用户列表 -func GetUserListWithPermission(operationType, operation string) (bool, []map[string]interface{}, error) { - db := database2.GetConnection() +func (d *UserDao) GetUserListWithPermission(operationType, operation string) (bool, []map[string]interface{}, error) { + db := d.db sql := `SELECT userID,IF(remark IS NULL OR remark = "",loginCall,remark) as userName,userType,IFNULL(permissions,"") FROM goku_admin ORDER BY userType ASC;` rows, err := db.Query(sql) if err != nil { diff --git a/server/dao/console-sqlite3/utils.go b/server/dao/console-sqlite3/utils.go index 36e29ec62e448b507b6f91979899a2c3a83fcd05..fcf61d63211d3c7fc56dbc110c7b17f7d6d0f150 100644 --- a/server/dao/console-sqlite3/utils.go +++ b/server/dao/console-sqlite3/utils.go @@ -3,22 +3,20 @@ package console_sqlite3 import ( SQL "database/sql" "fmt" - - "github.com/eolinker/goku-api-gateway/common/database" ) -func getCountSQL(sql string, args ...interface{}) int { +func getCountSQL(db *SQL.DB,sql string, args ...interface{}) int { var count int countSQL := fmt.Sprintf("SELECT COUNT(*) FROM (%s) A", sql) - err := database.GetConnection().QueryRow(countSQL, args...).Scan(&count) + err := db.QueryRow(countSQL, args...).Scan(&count) if err != nil { return 0 } return count } -func getPageSQL(sql string, orderBy, orderType string, page, pageSize int, args ...interface{}) (*SQL.Rows, error) { +func getPageSQL(db *SQL.DB,sql string, orderBy, orderType string, page, pageSize int, args ...interface{}) (*SQL.Rows, error) { pageSQL := fmt.Sprintf("%s ORDER BY %s %s LIMIT ?,?", sql, orderBy, orderType) args = append(args, (page-1)*pageSize, pageSize) - return database.GetConnection().Query(pageSQL, args...) + return db.Query(pageSQL, args...) } diff --git a/server/dao/console-sqlite3/version.go b/server/dao/console-sqlite3/version.go index ce1b4ebaa1637e36eb4fba4b84ceb6c338a0c6e6..558a16a308a0fde62898157e494f26b8374a4a4f 100644 --- a/server/dao/console-sqlite3/version.go +++ b/server/dao/console-sqlite3/version.go @@ -1,19 +1,38 @@ package console_sqlite3 import ( + SQL "database/sql" "encoding/json" "fmt" "strconv" "strings" - "github.com/eolinker/goku-api-gateway/common/database" + "github.com/eolinker/goku-api-gateway/server/dao" "github.com/eolinker/goku-api-gateway/config" ) +//VersionDao VersionDao +type VersionDao struct { + db *SQL.DB +} + +//NewVersionDao new VersionDao +func NewVersionDao() *VersionDao { + return &VersionDao{} +} + +//Create create +func (d *VersionDao) Create(db *SQL.DB) (interface{}, error) { + d.db = db + var i dao.VersionDao = d + + return &i, nil +} + //GetVersionList 获取版本列表 -func GetVersionList(keyword string) ([]config.VersionConfig, error) { - db := database.GetConnection() +func (d *VersionDao) GetVersionList(keyword string) ([]config.VersionConfig, error) { + db := d.db rule := make([]string, 0, 2) if keyword != "" { rule = append(rule, "V.name LIKE '%"+keyword+"%' OR V.version LIKE '%"+keyword+"%' OR V.remark LIKE '%"+keyword+"%'") @@ -36,16 +55,17 @@ func GetVersionList(keyword string) ([]config.VersionConfig, error) { if err != nil { return configList, err } + configList = append(configList, config) } return configList, nil } //AddVersionConfig 新增版本配置 -func AddVersionConfig(name, version, remark, config, balanceConfig, discoverConfig, now string) (int, error) { - db := database.GetConnection() - sql := "INSERT INTO goku_gateway_version_config (`name`,`version`,`remark`,`createTime`,`publishTime`,`config`,`balanceConfig`,`discoverConfig`) VALUES (?,?,?,?,?,?,?,?)" - result, err := db.Exec(sql, name, version, remark, now, now, config, balanceConfig, discoverConfig) +func (d *VersionDao) AddVersionConfig(name, version, remark, config, balanceConfig, discoverConfig, now string, userID int) (int, error) { + db := d.db + sql := "INSERT INTO goku_gateway_version_config (`name`,`version`,`remark`,`createTime`,`updateTime`,`publishTime`,`config`,`balanceConfig`,`discoverConfig`) VALUES (?,?,?,?,?,?,?,?,?)" + result, err := db.Exec(sql, name, version, remark, now, now, now, config, balanceConfig, discoverConfig) if err != nil { return 0, err } @@ -56,9 +76,21 @@ func AddVersionConfig(name, version, remark, config, balanceConfig, discoverConf return int(lastID), nil } +//EditVersionBasicConfig 修改版本基本配置 +func (d *VersionDao) EditVersionBasicConfig(name, version, remark string, userID, versionID int) error { + db := d.db + sql := "UPDATE goku_gateway_version_config SET `name` = ?,`version` = ?,`remark` = ?,`updaterID` = ? WHERE versionID = ?" + _, err := db.Exec(sql, name, version, remark, userID, versionID) + if err != nil { + return err + } + + return nil +} + //BatchDeleteVersionConfig 批量删除版本配置 -func BatchDeleteVersionConfig(ids []int, publishID int) error { - db := database.GetConnection() +func (d *VersionDao) BatchDeleteVersionConfig(ids []int, publishID int) error { + db := d.db s := "" idCount := len(ids) for i, id := range ids { @@ -79,8 +111,8 @@ func BatchDeleteVersionConfig(ids []int, publishID int) error { } //PublishVersion 发布版本 -func PublishVersion(id int, now string) error { - db := database.GetConnection() +func (d *VersionDao) PublishVersion(id, userID int, now string) error { + db := d.db sql := "UPDATE goku_gateway SET versionID = ?" _, err := db.Exec(sql, id) if err != nil { @@ -95,8 +127,8 @@ func PublishVersion(id int, now string) error { } //GetVersionConfigCount 获取版本配置数量 -func GetVersionConfigCount() int { - db := database.GetConnection() +func (d *VersionDao) GetVersionConfigCount() int { + db := d.db sql := "SELECT COUNT(*) FROM goku_gateway_version_config" var count int err := db.QueryRow(sql).Scan(&count) @@ -107,8 +139,8 @@ func GetVersionConfigCount() int { } //GetPublishVersionID 获取发布版本ID -func GetPublishVersionID() int { - db := database.GetConnection() +func (d *VersionDao) GetPublishVersionID() int { + db := d.db sql := "SELECT versionID FROM goku_gateway" var id int err := db.QueryRow(sql).Scan(&id) @@ -119,8 +151,8 @@ func GetPublishVersionID() int { } //GetVersionConfig 获取当前版本配置 -func GetVersionConfig() (*config.GokuConfig, map[string]map[string]*config.BalanceConfig, map[string]map[string]*config.DiscoverConfig, error) { - db := database.GetConnection() +func (d *VersionDao) GetVersionConfig() (*config.GokuConfig, map[string]map[string]*config.BalanceConfig, map[string]map[string]*config.DiscoverConfig, error) { + db := d.db sql := "SELECT IFNULL(goku_gateway_version_config.config,'{}'),IFNULL(goku_gateway_version_config.balanceConfig,'{}'),IFNULL(goku_gateway_version_config.discoverConfig,'{}') FROM goku_gateway_version_config INNER JOIN goku_gateway ON goku_gateway.versionID = goku_gateway_version_config.versionID" var cf, bf, df string @@ -129,8 +161,8 @@ func GetVersionConfig() (*config.GokuConfig, map[string]map[string]*config.Balan return nil, nil, nil, err } var c config.GokuConfig - b := make(map[string]map[string]*config.BalanceConfig) - d := make(map[string]map[string]*config.DiscoverConfig) + bc := make(map[string]map[string]*config.BalanceConfig) + dc := make(map[string]map[string]*config.DiscoverConfig) err = json.Unmarshal([]byte(cf), &c) if cf != "" { if err != nil { @@ -138,18 +170,18 @@ func GetVersionConfig() (*config.GokuConfig, map[string]map[string]*config.Balan } } if bf != "" { - err = json.Unmarshal([]byte(bf), &b) + err = json.Unmarshal([]byte(bf), &bc) if err != nil { return nil, nil, nil, err } } if df != "" { - err = json.Unmarshal([]byte(df), &d) + err = json.Unmarshal([]byte(df), &dc) if err != nil { return nil, nil, nil, err } } - return &c, b, d, nil + return &c, bc, dc, nil } diff --git a/server/dao/dao-balance.go b/server/dao/dao-balance.go new file mode 100644 index 0000000000000000000000000000000000000000..a8fafe4540721d36108dc74d150e3365d478d8f6 --- /dev/null +++ b/server/dao/dao-balance.go @@ -0,0 +1,41 @@ +package dao + +import ( + entity "github.com/eolinker/goku-api-gateway/server/entity/balance-entity-service" +) + +//BalanceDao balanceDao +type BalanceDao interface { + //RegisterDao add + //Add(name, serviceName, desc, appName, static, staticCluster, now string) (string, error) + + //AddStatic 新增静态负载 + AddStatic(name, serviceName, static, staticCluster, desc, now string) (string, error) + //SaveStatic 保存静态负载信息 + SaveStatic(name, serviceName, static, staticCluster, desc string, now string) (string, error) + + //SaveDiscover 保存服务发现信息 + SaveDiscover(name, serviceName, appName, desc string, now string) (string, error) + //AddDiscovery 新增服务发现 + AddDiscovery(name, serviceName, appName, desc, now string) (string, error) + //Save save + //Save(name, desc, static, staticCluster, now string) (string, error) + + //Delete 删除负载 + Delete(name string) (string, error) + + //BatchDelete 批量删除负载 + BatchDelete(balanceNames []string) (string, error) + //GetBalanceNames 获取负载名称列表 + GetBalanceNames() (bool, []string, error) + //Get 根据负载名获取负载配置 + Get(name string) (*entity.Balance, error) + + //GetAll 获取所有负载配置 + GetAll() ([]*entity.Balance, error) + + //Search 关键字获取负载列表 + Search(keyword string) ([]*entity.Balance, error) + + GetUseBalanceNames() (map[string]int, error) +} diff --git a/server/dao/daos.go b/server/dao/daos.go new file mode 100644 index 0000000000000000000000000000000000000000..c9cd53bb513e006d70a0e5ce29e6d359602d46fe --- /dev/null +++ b/server/dao/daos.go @@ -0,0 +1,458 @@ +package dao + +import ( + "time" + + "github.com/eolinker/goku-api-gateway/config" + balanceentity "github.com/eolinker/goku-api-gateway/server/entity/balance-entity" + configLogEntry "github.com/eolinker/goku-api-gateway/server/entity/config-log" + entity "github.com/eolinker/goku-api-gateway/server/entity/console-entity" +) + +//APIDao apiDao +type APIDao interface { + // AddAPI 新增接口 + AddAPI(apiName, alias, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkAPIs, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, managerID, userID, apiType int) (bool, int, error) + // EditAPI 修改接口 + EditAPI(apiName, alias, requestURL, targetURL, requestMethod, targetMethod, isFollow, linkAPIs, staticResponse, responseDataType, balanceName, protocol string, projectID, groupID, timeout, retryCount, alertValve, apiID, managerID, userID int) (bool, error) + // GetAPIInfo 获取接口信息 + GetAPIInfo(apiID int) (bool, *entity.API, error) + //GetAPIListByGroupList 通过分组列表获取接口列表 + GetAPIListByGroupList(projectID int, groupIDList string) (bool, []map[string]interface{}, error) + + // GetAPIIDList 获取接口ID列表 + GetAPIIDList(projectID int, groupID int, keyword string, condition int, ids []int) (bool, []int, error) + // GetAPIList 获取所有接口列表 + GetAPIList(projectID int, groupID int, keyword string, condition, page, pageSize int, ids []int) (bool, []map[string]interface{}, int, error) + //CheckURLIsExist 接口路径是否存在 + CheckURLIsExist(requestURL, requestMethod string, projectID, apiID int) bool + //CheckAPIIsExist 检查接口是否存在 + CheckAPIIsExist(apiID int) (bool, error) + //CheckAliasIsExist 检查别名是否存在 + CheckAliasIsExist(apiID int, alias string) bool + //BatchEditAPIBalance 批量修改接口负载 + BatchEditAPIBalance(apiIDList []string, balance string) (string, error) + //BatchEditAPIGroup 批量修改接口分组 + BatchEditAPIGroup(apiIDList []string, groupID int) (string, error) + //BatchDeleteAPI 批量修改接口 + BatchDeleteAPI(apiIDList string) (bool, string, error) +} + +//APIGroupDao apiGroupDao +type APIGroupDao interface { + //AddAPIGroup 新建接口分组 + AddAPIGroup(groupName string, projectID, parentGroupID int) (bool, interface{}, error) + //EditAPIGroup 修改接口分组 + EditAPIGroup(groupName string, groupID, projectID int) (bool, string, error) + //DeleteAPIGroup 删除接口分组 + DeleteAPIGroup(projectID, groupID int) (bool, string, error) + //GetAPIGroupList 获取接口分组列表 + GetAPIGroupList(projectID int) (bool, []map[string]interface{}, error) +} + +//APIPluginDao apiPlugin.go +type APIPluginDao interface { + //AddPluginToAPI 新增接口插件 + AddPluginToAPI(pluginName, config, strategyID string, apiID, userID int) (bool, interface{}, error) + //EditAPIPluginConfig 修改接口插件配置 + EditAPIPluginConfig(pluginName, config, strategyID string, apiID, userID int) (bool, interface{}, error) + //GetAPIPluginList 获取接口插件列表 + GetAPIPluginList(apiID int, strategyID string) (bool, []map[string]interface{}, error) + //GetPluginIndex 获取插件优先级 + GetPluginIndex(pluginName string) (bool, int, error) + //GetAPIPluginConfig 通过APIID获取配置信息 + GetAPIPluginConfig(apiID int, strategyID, pluginName string) (bool, map[string]string, error) + //CheckPluginIsExistInAPI 检查策略组是否绑定插件 + CheckPluginIsExistInAPI(strategyID, pluginName string, apiID int) (bool, error) + // GetAPIPluginInStrategyByAPIID 通过接口ID获取策略组中接口插件列表 + GetAPIPluginInStrategyByAPIID(strategyID string, apiID int, keyword string, condition int) (bool, []map[string]interface{}, map[string]interface{}, error) + //GetAllAPIPluginInStrategy 获取策略组中所有接口插件列表 + GetAllAPIPluginInStrategy(strategyID string) (bool, []map[string]interface{}, error) + //BatchEditAPIPluginStatus 批量修改策略组插件状态 + BatchEditAPIPluginStatus(connIDList, strategyID string, pluginStatus, userID int) (bool, string, error) + //BatchDeleteAPIPlugin 批量删除策略组插件 + BatchDeleteAPIPlugin(connIDList, strategyID string) (bool, string, error) + //GetAPIPluginName 通过connID获取插件名称 + GetAPIPluginName(connID int) (bool, string, error) + //CheckAPIPluginIsExistByConnIDList 通过connIDList判断插件是否存在 + CheckAPIPluginIsExistByConnIDList(connIDList, pluginName string) (bool, []int, error) + //GetAPIPluginListWithNotAssignAPIList 获取没有绑定嵌套插件列表 + GetAPIPluginListWithNotAssignAPIList(strategyID string) (bool, []map[string]interface{}, error) +} + +//APIStrategyDao apiStrategy.go +type APIStrategyDao interface { + //AddAPIToStrategy 将接口加入策略组 + AddAPIToStrategy(apiList []string, strategyID string) (bool, string, error) + // SetAPITargetOfStrategy 重定向接口负载 + SetAPITargetOfStrategy(apiID int, strategyID string, target string) (bool, string, error) + // BatchSetAPITargetOfStrategy 批量重定向接口负载 + BatchSetAPITargetOfStrategy(apiIds []int, strategyID string, target string) (bool, string, error) + // GetAPIIDListFromStrategy 获取策略组接口列表 + GetAPIIDListFromStrategy(strategyID, keyword string, condition int, ids []int, balanceNames []string) (bool, []int, error) + // GetAPIListFromStrategy 获取策略组接口列表 + GetAPIListFromStrategy(strategyID, keyword string, condition, page, pageSize int, ids []int, balanceNames []string) (bool, []map[string]interface{}, int, error) + // CheckIsExistAPIInStrategy 检查插件是否添加进策略组 + CheckIsExistAPIInStrategy(apiID int, strategyID string) (bool, string, error) + + // GetAPIIDListNotInStrategy 获取未被该策略组绑定的接口ID列表(通过项目) + GetAPIIDListNotInStrategy(strategyID string, projectID, groupID int, keyword string) (bool, []int, error) + // GetAPIListNotInStrategy 获取未被该策略组绑定的接口列表(通过项目) + GetAPIListNotInStrategy(strategyID string, projectID, groupID, page, pageSize int, keyword string) (bool, []map[string]interface{}, int, error) + //BatchDeleteAPIInStrategy 批量删除策略组接口 + BatchDeleteAPIInStrategy(apiIDList, strategyID string) (bool, string, error) +} + +//AuthDao auth.go +type AuthDao interface { + //GetAuthStatus 获取认证状态 + GetAuthStatus(strategyID string) (bool, map[string]interface{}, error) + //GetAuthInfo 获取认证信息 + GetAuthInfo(strategyID string) (bool, map[string]interface{}, error) + //EditAuthInfo 编辑认证信息 + EditAuthInfo(strategyID, strategyName, basicAuthList, apikeyList, jwtCredentialList, oauth2CredentialList string, delClientIDList []string) (bool, error) +} + +//ClusterDao cluster.go +type ClusterDao interface { + //AddCluster 新增集群 + AddCluster(name, title, note string) error + //EditCluster 修改集群信息 + EditCluster(name, title, note string) error + //DeleteCluster 删除集群 + DeleteCluster(name string) error + //GetClusterCount 获取集群数量 + GetClusterCount() int + //GetClusterNodeCount 获取集群节点数量 + GetClusterNodeCount(name string) int + //GetClusterIDByName 通过集群名称获取集群ID + GetClusterIDByName(name string) int + //GetClusters 获取集群列表 + GetClusters() ([]*entity.Cluster, error) + //GetCluster 获取集群信息 + GetCluster(name string) (*entity.Cluster, error) + GetClusterByID(id int) (*entity.Cluster, error) + //CheckClusterNameIsExist 判断集群名称是否存在 + CheckClusterNameIsExist(name string) bool +} + +//ConfigLogDao config-log +type ConfigLogDao interface { + //Get get + Get(name string) (*configLogEntry.LogConfig, error) + //Set set + Set(ent *configLogEntry.LogConfig) error +} + +//BalanceUpdateDao dao-balance-update +type BalanceUpdateDao interface { + //GetAllOldVerSion 获取所有旧负载配置 + GetAllOldVerSion() ([]*balanceentity.BalanceInfoEntity, error) + //GetDefaultServiceStatic 获取默认静态负载 + GetDefaultServiceStatic() string +} + +//ServiceDao dao-service +type ServiceDao interface { + //RegisterDao 新增服务 + Add(name, driver, desc, config, clusterConfig string, isDefault, healthCheck bool, healthCheckPath string, healthCheckCode string, healthCheckPeriod, healthCheckTimeOut int) error + //SetDefault 设置默认服务 + SetDefault(name string) error + //Delete 删除服务发现 + Delete(names []string) error + //Get 获取服务发现信息 + Get(name string) (*entity.Service, error) + //List 获取服务发现列表 + List(keyword string) ([]*entity.Service, error) + //Save 存储服务发现信息 + Save(name, desc, config, clusterConfig string, healthCheck bool, healthCheckPath string, healthCheckCode string, healthCheckPeriod, healthCheckTimeOut int) error +} + +//VersionConfigDao dao-version-config +type VersionConfigDao interface { + //GetAPIContent 获取接口信息 + GetAPIContent() ([]*config.APIContent, error) + //GetBalances 获取balance信息 + GetDiscoverConfig(clusters []*entity.Cluster) (map[string]map[string]*config.DiscoverConfig, error) + //GetDiscoverConfig 获取服务发现信息 + GetBalances(clusters []*entity.Cluster) (map[string]map[string]*config.BalanceConfig, error) + //GetGlobalPlugin 获取全局插件 + GetGlobalPlugin() (*config.GatewayPluginConfig, error) + //GetAPIPlugins 获取接口插件 + GetAPIPlugins() (map[string][]*config.PluginConfig, error) + //GetStrategyPlugins 获取策略插件 + GetStrategyPlugins() (map[string][]*config.PluginConfig, map[string]map[string]string, error) + //GetAPIsOfStrategy 获取策略内接口数据 + GetAPIsOfStrategy() (map[string][]*config.APIOfStrategy, error) + //GetStrategyConfig 获取策略配置 + GetStrategyConfig() (string, []*config.StrategyConfig, error) + //GetLogInfo 获取日志信息 + GetLogInfo() (*config.LogConfig, *config.AccessLogConfig, error) + //GetMonitorModules 获取监控模块信息 + GetMonitorModules(status int, isAll bool) (map[string]string, error) + + GetRouterRules(enable int) ([]*config.Router, error) + + GetGatewayBasicConfig() (*config.Gateway, error) +} + +//GatewayDao gateway.go +type GatewayDao interface { + //GetGatewayConfig 获取网关配置 + GetGatewayConfig() (map[string]interface{}, error) + //EditGatewayBaseConfig 编辑网关基本配置 + EditGatewayBaseConfig(config entity.GatewayBasicConfig) (bool, string, error) + //GetGatewayInfo 获取网关信息 + GetGatewayInfo() (nodeStartCount, nodeStopCount, projectCount, apiCount, strategyCount int, err error) +} + +//GuestDao guest.go +type GuestDao interface { + //Login 登录 + Login(loginCall, loginPassword string) (bool, int) + //CheckLogin 检查用户是否登录 + CheckLogin(userToken string, userID int) bool + //Register 用户注册 + Register(loginCall, loginPassword string) bool +} + +//ImportDao import.go +type ImportDao interface { + //ImportAPIGroupFromAms 导入分组 + ImportAPIGroupFromAms(projectID, userID int, groupInfo entity.AmsGroupInfo) (bool, string, error) + //ImportProjectFromAms 导入项目 + ImportProjectFromAms(userID int, projectInfo entity.AmsProject) (bool, string, error) + //ImportAPIFromAms 从ams中导入接口 + ImportAPIFromAms(projectID, groupID, userID int, apiList []entity.AmsAPIInfo) (bool, string, error) +} + +//MonitorModulesDao monitorModule.go +type MonitorModulesDao interface { + //GetMonitorModules 获取监控模块列表 + GetMonitorModules() (map[string]*entity.MonitorModule, error) + //SetMonitorModule 设置监控模块 + SetMonitorModule(moduleName string, config string, moduleStatus int) error + + CheckModuleStatus(moduleName string) int +} + +//NodeDao node.go +type NodeDao interface { + //AddNode 新增节点信息 + AddNode(clusterID int, nodeName, nodeKey, listenAddress, adminAddress, gatewayPath string, groupID int) (int64, string, string, error) + //EditNode 修改节点信息 + EditNode(nodeName, listenAddress, adminAddress, gatewayPath string, nodeID, groupID int) (string, error) + //DeleteNode 删除节点信息 + DeleteNode(nodeID int) (string, error) + // GetNodeList 获取节点列表 + GetNodeList(clusterID, groupID int, keyword string) ([]*entity.Node, error) + //GetNodeInfo 获取节点信息 + GetNodeInfo(nodeID int) (*entity.Node, error) + //GetNodeByKey 通过Key查询节点信息 + GetNodeByKey(nodeKey string) (*entity.Node, error) + //GetAvaliableNodeListFromNodeList 从待操作节点中获取关闭节点列表 + GetAvaliableNodeListFromNodeList(nodeIDList string, nodeStatus int) (string, error) + //BatchEditNodeGroup 批量修改节点分组 + BatchEditNodeGroup(nodeIDList string, groupID int) (string, error) + //BatchDeleteNode 批量修改接口分组 + BatchDeleteNode(nodeIDList string) (string, error) + //UpdateAllNodeClusterID 更新节点集群ID + UpdateAllNodeClusterID(clusterID int) + //GetNodeInfoAll get all node + GetNodeInfoAll() ([]*entity.Node, error) + + GetHeartBeatTime(nodeKey string) (time.Time, error) + + SetHeartBeatTime(nodeKey string, heartBeatTime time.Time) error +} + +//NodeGroupDao nodeGroup.go +type NodeGroupDao interface { + //AddNodeGroup 新建节点分组 + AddNodeGroup(groupName string, clusterID int) (bool, interface{}, error) + //EditNodeGroup 修改节点分组信息 + EditNodeGroup(groupName string, groupID int) (bool, string, error) + //DeleteNodeGroup 删除节点分组 + DeleteNodeGroup(groupID int) (bool, string, error) + //GetNodeGroupInfo 获取节点分组信息 + GetNodeGroupInfo(groupID int) (bool, map[string]interface{}, error) + //GetNodeGroupList 获取节点分组列表 + GetNodeGroupList(clusterID int) (bool, []map[string]interface{}, error) + //CheckNodeGroupIsExist 检查节点分组是否存在 + CheckNodeGroupIsExist(groupID int) (bool, error) + //GetRunningNodeCount 获取分组内启动节点数量 + GetRunningNodeCount(groupID int) (bool, interface{}, error) +} + +//PluginDao plugin.go +type PluginDao interface { + //GetPluginInfo 获取插件配置信息 + GetPluginInfo(pluginName string) (bool, *entity.Plugin, error) + // GetPluginList 获取插件列表 + GetPluginList(keyword string, condition int) (bool, []*entity.Plugin, error) + // GetPluginCount 获取插件数量 + GetPluginCount() int + // AddPlugin 新增插件信息 + AddPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPriority, isStop, pluginType int) (bool, string, error) + // EditPlugin 修改插件信息 + EditPlugin(pluginName, pluginConfig, pluginDesc, version string, pluginPriority, isStop, pluginType int) (bool, string, error) + // DeletePlugin 删除插件信息 + DeletePlugin(pluginName string) (bool, string, error) + //CheckIndexIsExist 判断插件ID是否存在 + CheckIndexIsExist(pluginName string, pluginPriority int) (bool, error) + //GetPluginConfig 获取插件配置及插件信息 + GetPluginConfig(pluginName string) (bool, string, error) + //CheckNameIsExist 检查插件名称是否存在 + CheckNameIsExist(pluginName string) (bool, error) + //EditPluginStatus 修改插件开启状态 + EditPluginStatus(pluginName string, pluginStatus int) (bool, error) + //GetPluginListByPluginType 获取不同类型的插件列表 + GetPluginListByPluginType(pluginType int) (bool, []map[string]interface{}, error) + //BatchStopPlugin 批量关闭插件 + BatchStopPlugin(pluginNameList string) (bool, string, error) + //BatchStartPlugin 批量关闭插件 + BatchStartPlugin(pluginNameList string) (bool, string, error) + //EditPluginCheckStatus 更新插件检测状态 + EditPluginCheckStatus(pluginName string, isCheck int) (bool, string, error) +} + +//ProjectDao project.go +type ProjectDao interface { + //AddProject 新建项目 + AddProject(projectName string) (bool, interface{}, error) + //EditProject 修改项目信息 + EditProject(projectName string, projectID int) (bool, string, error) + //DeleteProject 修改项目信息 + DeleteProject(projectID int) (bool, string, error) + //BatchDeleteProject 批量删除项目 + BatchDeleteProject(projectIDList string) (bool, string, error) + //GetProjectInfo 获取项目信息 + GetProjectInfo(projectID int) (bool, entity.Project, error) + //GetProjectList 获取项目列表 + GetProjectList(keyword string) (bool, []*entity.Project, error) + //CheckProjectIsExist 检查项目是否存在 + CheckProjectIsExist(projectID int) (bool, error) + //GetAPIListFromProjectNotInStrategy 获取项目列表中没有被策略组绑定的接口 + GetAPIListFromProjectNotInStrategy() (bool, []map[string]interface{}, error) +} + +//StrategyDao strategy.go +type StrategyDao interface { + //AddStrategy 新增策略组 + AddStrategy(strategyName string, groupID, userID int) (bool, string, error) + //EditStrategy 修改策略组信息 + EditStrategy(strategyID, strategyName string, groupID, userID int) (bool, string, error) + //DeleteStrategy 删除策略组 + DeleteStrategy(strategyID string) (bool, string, error) + // GetStrategyList 获取策略组列表 + GetStrategyList(groupID int, keyword string, condition, page, pageSize int) (bool, []*entity.Strategy, int, error) + // GetOpenStrategy 获取策略组列表 + GetOpenStrategy() (bool, *entity.Strategy, error) + //GetStrategyInfo 获取策略组信息 + GetStrategyInfo(strategyID string) (bool, *entity.Strategy, error) + //CheckStrategyIsExist 检查策略组ID是否存在 + CheckStrategyIsExist(strategyID string) (bool, error) + //BatchEditStrategyGroup 批量修改策略组分组 + BatchEditStrategyGroup(strategyIDList string, groupID int) (bool, string, error) + //BatchDeleteStrategy 批量修改策略组 + BatchDeleteStrategy(strategyIDList string) (bool, string, error) + //CheckIsOpenStrategy 判断是否是开放策略 + CheckIsOpenStrategy(strategyID string) bool + //BatchUpdateStrategyEnableStatus 更新策略启动状态 + BatchUpdateStrategyEnableStatus(strategyIDList string, enableStatus int) (bool, string, error) + // GetBalanceListInStrategy 获取在策略中的负载列表 + GetBalanceListInStrategy(strategyID string, balanceType int) (bool, []string, error) + // CopyStrategy 复制策略 + CopyStrategy(strategyID string, newStrategyID string, userID int) (string, error) + //GetStrategyIDList 获取策略ID列表 + GetStrategyIDList(groupID int, keyword string, condition int) (bool, []string, error) +} + +//StrategyGroupDao strategyGroup.go +type StrategyGroupDao interface { + //AddStrategyGroup 新建策略组分组 + AddStrategyGroup(groupName string) (bool, interface{}, error) + //EditStrategyGroup 修改策略组分组 + EditStrategyGroup(groupName string, groupID int) (bool, string, error) + //DeleteStrategyGroup 删除策略组分组 + DeleteStrategyGroup(groupID int) (bool, string, error) + //GetStrategyGroupList 获取策略组分组列表 + GetStrategyGroupList() (bool, []map[string]interface{}, error) + //CheckIsOpenGroup 判断是否是开放分组 + CheckIsOpenGroup(groupID int) bool +} + +//StrategyPluginDao strategyPlugin.go +type StrategyPluginDao interface { + //AddPluginToStrategy 新增策略组插件 + AddPluginToStrategy(pluginName, config, strategyID string) (bool, interface{}, error) + //EditStrategyPluginConfig 新增策略组插件配置 + EditStrategyPluginConfig(pluginName, config, strategyID string) (bool, string, error) + // GetStrategyPluginList 获取策略插件列表 + GetStrategyPluginList(strategyID, keyword string, condition int) (bool, []map[string]interface{}, error) + //GetStrategyPluginConfig 通过策略组ID获取配置信息 + GetStrategyPluginConfig(strategyID, pluginName string) (bool, string, error) + //CheckPluginIsExistInStrategy 检查策略组是否绑定插件 + CheckPluginIsExistInStrategy(strategyID, pluginName string) (bool, error) + //GetStrategyPluginStatus 检查策略组插件是否开启 + GetStrategyPluginStatus(strategyID, pluginName string) (bool, error) + //GetConnIDFromStrategyPlugin 获取Connid + GetConnIDFromStrategyPlugin(pluginName, strategyID string) (bool, int, error) + //BatchEditStrategyPluginStatus 批量修改策略组插件状态 + BatchEditStrategyPluginStatus(connIDList, strategyID string, pluginStatus int) (bool, string, error) + //BatchDeleteStrategyPlugin 批量删除策略组插件 + BatchDeleteStrategyPlugin(connIDList, strategyID string) (bool, string, error) + //CheckStrategyPluginIsExistByConnIDList 通过connIDList判断插件是否存在 + CheckStrategyPluginIsExistByConnIDList(connIDList, pluginName string) (bool, error) +} + +//UpdaterDao updater +type UpdaterDao interface { + //IsTableExist 检查table是否存在 + IsTableExist(name string) bool + //IsColumnExist 检查列是否存在 + IsColumnExist(name string, column string) bool + //GetTableVersion 获取当前表版本号 + GetTableVersion(name string) string + //UpdateTableVersion 更新表版本号 + UpdateTableVersion(name, version string) error + //GetGokuVersion 获取goku当前版本号 + GetGokuVersion() string + //SetGokuVersion 设置goku版本号 + SetGokuVersion(version string) error +} + +//UserDao user.go +type UserDao interface { + //EditPassword 修改账户信息 + EditPassword(oldPassword, newPassword string, userID int) (bool, string, error) + //GetUserInfo 获取账户信息 + GetUserInfo(userID int) (bool, interface{}, error) + //GetUserType 获取用户类型 + GetUserType(userID int) (bool, interface{}, error) + //CheckUserIsAdmin 判断是否是管理员 + CheckUserIsAdmin(userID int) (bool, string, error) + //CheckUserIsSuperAdmin 判断是否是超级管理员 + CheckUserIsSuperAdmin(userID int) (bool, string, error) + //CheckSuperAdminCount 获取超级管理员数量 + CheckSuperAdminCount() (int, error) +} + +//VersionDao version.go +type VersionDao interface { + //GetVersionList 获取版本列表 + GetVersionList(keyword string) ([]config.VersionConfig, error) + //AddVersionConfig 新增版本配置 + AddVersionConfig(name, version, remark, config, balanceConfig, discoverConfig, now string, userID int) (int, error) + EditVersionBasicConfig(name, version, remark string, userID, versionID int) error + //BatchDeleteVersionConfig 批量删除版本配置 + BatchDeleteVersionConfig(ids []int, publishID int) error + //PublishVersion 发布版本 + PublishVersion(id, userID int, now string) error + //GetVersionConfigCount 获取版本配置数量 + GetVersionConfigCount() int + //GetPublishVersionID 获取发布版本ID + GetPublishVersionID() int + //GetVersionConfig 获取当前版本配置 + GetVersionConfig() (*config.GokuConfig, map[string]map[string]*config.BalanceConfig, map[string]map[string]*config.DiscoverConfig, error) +} diff --git a/server/entity/balance-entity-service/balance.go b/server/entity/balance-entity-service/balance.go index 21953fe5087a5e99c495bd5bc007ef297a28685f..70bc1c71641ec5b95fd46ca40c8f1c850735e2c4 100644 --- a/server/entity/balance-entity-service/balance.go +++ b/server/entity/balance-entity-service/balance.go @@ -14,6 +14,7 @@ type Balance struct { Desc string CreateTime string UpdateTime string + CanDelete int } //Type 获取负载类型 diff --git a/server/entity/balance-entity/balance.go b/server/entity/balance-entity/balance.go index c6f621e8cb343959e9daab30da1ee4db54334f38..c4facb68cd6d963f1f973e4c76825d5e5f5b9a81 100644 --- a/server/entity/balance-entity/balance.go +++ b/server/entity/balance-entity/balance.go @@ -53,7 +53,7 @@ type _OldVersionBalanceInfo struct { } // -//func (info *BalanceInfo) Encode() *BalanceInfoEntity { +//func (info *BalanceInfo) Write() *BalanceInfoEntity { // // ent := new(BalanceInfoEntity) // ent.Name = info.Name diff --git a/server/entity/cluster.go b/server/entity/cluster.go index e79d25d1be76f66a718e59283527276c79fd6afc..a25f2b5ba14e262fb8648bdc3ee4784aa553d85a 100644 --- a/server/entity/cluster.go +++ b/server/entity/cluster.go @@ -1,23 +1,8 @@ package entity -import "fmt" - -//Cluster 集群配置 -type Cluster struct { - ID int `json:"-" yaml:"-"` - Name string `json:"name" yaml:"name"` - Title string `json:"title" yaml:"title"` -} - -//ClusterInfo 集群信息 -type ClusterInfo struct { - ID int `json:"-" yaml:"-"` - Name string `json:"name" yaml:"name"` - Title string `json:"title" yaml:"title"` - Note string `json:"note" yaml:"note"` - DB ClusterDB `json:"db" yaml:"db"` - Redis CLusterRedis `json:"redis" yaml:"redis"` -} +import ( + "fmt" +) //ClusterDB 集群DB配置 type ClusterDB struct { @@ -30,15 +15,6 @@ type ClusterDB struct { Path string `json:"path" yaml:"path"` } -//CLusterRedis 集群redis配置 -type CLusterRedis struct { - Mode string `json:"mode" yaml:"mode"` - Addrs string `json:"addrs" yaml:"addrs"` - DbIndex int `json:"dbIndex" yaml:"dbIndex"` - Masters string `json:"masters" yaml:"masters"` - Password string `json:"password" yaml:"password"` -} - //GetDriver 获取驱动名称 func (c *ClusterDB) GetDriver() string { return c.Driver @@ -48,13 +24,3 @@ func (c *ClusterDB) GetDriver() string { func (c *ClusterDB) GetSource() string { return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8", c.UserName, c.Password, c.Host, c.Port, c.Database) } - -//Cluster 获取集群 -func (c *ClusterInfo) Cluster() *Cluster { - return &Cluster{ - ID: c.ID, - Name: c.Name, - Title: c.Title, - } - -} diff --git a/server/entity/console-entity/ams_import.go b/server/entity/console-entity/ams_import.go index f4c98122f0b13d1abd604c4d05726da090758827..9a9986e2d31769c71d152783ada7336053e7e3be 100644 --- a/server/entity/console-entity/ams_import.go +++ b/server/entity/console-entity/ams_import.go @@ -29,4 +29,5 @@ type AmsAPI struct { APIName string `json:"apiName"` APIURI string `json:"apiURI"` APIRequestType int `json:"apiRequestType"` + APIProtocol int `json:"apiProtocol"` } diff --git a/server/entity/console-entity/api.go b/server/entity/console-entity/api.go index 1f341cdecd5338d8e679217b4cf444c4224d0f8f..8dd1e98b7e8cef04dce838ea2f8df311c523b8e2 100644 --- a/server/entity/console-entity/api.go +++ b/server/entity/console-entity/api.go @@ -6,6 +6,7 @@ import "github.com/eolinker/goku-api-gateway/config" type API struct { APIID int `json:"apiID"` APIName string `json:"apiName"` + Alias string `json:"alias"` GroupID int `json:"groupID,omitempty"` ProjectID int `json:"projectID,omitempty"` RequestURL string `json:"requestURL"` diff --git a/server/entity/console-entity/cluster.go b/server/entity/console-entity/cluster.go index 7dd4f54d477f69c9a1bbb7f2e698cbaf334a184c..5aca2fe6b60f803f4b24e05e2af40d5f7d9fc554 100644 --- a/server/entity/console-entity/cluster.go +++ b/server/entity/console-entity/cluster.go @@ -1,10 +1,47 @@ package entity +import "strings" + //Cluster 集群配置 type Cluster struct { - ID int `json:"id"` - Name string `json:"name"` - Title string `json:"title"` - Note string `json:"note"` - NodeCount int `json:"nodeCount"` + ID int `json:"id"` + Name string `json:"name"` + Title string `json:"title"` + Note string `json:"note"` + NodeCount int `json:"nodeCount"` + Redis *ClusterRedis `json:"redis"` +} + +//ClusterRedis 集群redis配置 +type ClusterRedis struct { + Mode string `json:"mode" yaml:"mode"` + Addrs string `json:"addrs" yaml:"addrs"` + DbIndex int `json:"dbIndex" yaml:"dbIndex"` + Masters string `json:"masters" yaml:"masters"` + Password string `json:"password" yaml:"password"` +} + +//GetMode 获取redis模式 +func (c ClusterRedis) GetMode() string { + return c.Mode +} + +//GetAddrs 获取地址 +func (c ClusterRedis) GetAddrs() []string { + return strings.Split(c.Addrs, ",") +} + +//GetMasters 或者masters +func (c ClusterRedis) GetMasters() []string { + return strings.Split(c.Masters, ",") +} + +//GetDbIndex 获取所有 +func (c ClusterRedis) GetDbIndex() int { + return c.DbIndex +} + +//GetPassword 获取密码 +func (c ClusterRedis) GetPassword() string { + return c.Password } diff --git a/server/entity/console-entity/gateway.go b/server/entity/console-entity/gateway.go new file mode 100644 index 0000000000000000000000000000000000000000..e0b4308a02b4b2e3435c5f5815211b8077e4ffa8 --- /dev/null +++ b/server/entity/console-entity/gateway.go @@ -0,0 +1,10 @@ +package entity + +//GatewayBasicConfig 网关基础配置 +type GatewayBasicConfig struct { + SuccessCode string `json:"successCode"` + NodeUpdatePeriod int `json:"nodeUpdatePeriod"` + MonitorUpdatePeriod int `json:"monitorUpdatePeriod"` + MonitorTimeout int `json:"monitorTimeout"` + SkipCertificate int `json:"skipCertificate"` +} diff --git a/server/entity/console-entity/node.go b/server/entity/console-entity/node.go index af1493c9b1703cf781c5213e9ab36f71a23edb10..d3c1ed1653fb7a331c4e080de098240243c47458 100644 --- a/server/entity/console-entity/node.go +++ b/server/entity/console-entity/node.go @@ -18,14 +18,15 @@ type Node struct { CreateTime string `json:"createTime"` UpdateTime string `json:"updateTime"` UpdatePeriod int `json:"updatePeriod,omitempty"` - //*SSHInfo + *SSHInfo } -//type SSHInfo struct { -// SSHPort string `json:"sshPort"` -// UserName string `json:"userName"` -// Password string `json:"password"` -// -// Key string `json:"key"` -// AuthMethod int `json:"authMethod"` -//} +//SSHInfo sshInfo +type SSHInfo struct { + SSHAddress string `json:"sshAddress"` + UserName string `json:"sshUserName"` + Password string `json:"sshPassword"` + Key string `json:"sshKey"` + AuthMethod int `json:"authMethod"` + IsSave int `json:"isSave"` +} diff --git a/server/entity/console-entity/redis.go b/server/entity/console-entity/redis.go index dfc7959f7ffb2473e0707799af98f22e3fb3be21..be3767f032ca563b9a76be86248d2586cb538b09 100644 --- a/server/entity/console-entity/redis.go +++ b/server/entity/console-entity/redis.go @@ -2,6 +2,7 @@ package entity //RedisNode redis节点 type RedisNode struct { + ID int Server string Password string ClusterID int diff --git a/server/entity/console-entity/strategy.go b/server/entity/console-entity/strategy.go index 7e2ee8ed47baa34845092add5dfeb661950aee38..3aef1bf200be5ac10d3c9fabefec9ba61eb95c8d 100644 --- a/server/entity/console-entity/strategy.go +++ b/server/entity/console-entity/strategy.go @@ -11,4 +11,6 @@ type Strategy struct { GroupName string `json:"groupName,omitempty"` EnableStatus int `json:"enableStatus"` StrategyType int `json:"strategyType"` + Updater string `json:"updater"` + Creater string `json:"creater"` } diff --git a/server/entity/redis_config.go b/server/entity/redis_config.go index cf8388be32637a27ffe41fb8d4969817f9b162b7..9356433d1faedcd1c84613a99a86c0872b0a190a 100644 --- a/server/entity/redis_config.go +++ b/server/entity/redis_config.go @@ -1,30 +1 @@ package entity - -import ( - "strings" -) - -//GetMode 获取redis使用模式 -func (c CLusterRedis) GetMode() string { - return c.Mode -} - -//GetAddrs 获取地址 -func (c CLusterRedis) GetAddrs() []string { - return strings.Split(c.Addrs, ",") -} - -//GetMasters 获取master -func (c CLusterRedis) GetMasters() []string { - return strings.Split(c.Masters, ",") -} - -//GetDbIndex 获取数据库序号 -func (c CLusterRedis) GetDbIndex() int { - return c.DbIndex -} - -//GetPassword 获取密码 -func (c CLusterRedis) GetPassword() string { - return c.Password -} diff --git a/server/entity/smtp.go b/server/entity/smtp.go new file mode 100644 index 0000000000000000000000000000000000000000..ce6e27d289b6146168f699e9a3320f7a0ec6652a --- /dev/null +++ b/server/entity/smtp.go @@ -0,0 +1,11 @@ +package entity + +//SMTPInfo SMTP信息 +type SMTPInfo struct { + Address string `json:"address"` + Port int `json:"port"` + Protocol int `json:"protocol"` + Sender string `json:"sender"` + Account string `json:"account"` + Password string `json:"password"` +} diff --git a/utils/function.go b/utils/function.go index 37b6d4a9af220adcecfb14e609c1ed6742a3dbcf..3e429a0b210a71381241fdc7226ee7cf35d277b1 100644 --- a/utils/function.go +++ b/utils/function.go @@ -14,6 +14,35 @@ import ( "time" ) +//ConvertIntArrayToString 转换整型数组 +func ConvertIntArrayToString(ids []int) string { + idLen := len(ids) + if idLen < 1 { + return "" + } + idStr := "" + for i, id := range ids { + idStr += strconv.Itoa(id) + if i < idLen-1 { + idStr += "," + } + } + return idStr +} + +//ConvertArray 将[]string转为[]int +func ConvertArray(arr []string) (bool, []int) { + result := make([]int, 0) + for _, i := range arr { + res, err := strconv.Atoi(i) + if err != nil { + return false, result + } + result = append(result, res) + } + return true, result +} + //ValidateRemoteAddr 判断ip端口是否合法 func ValidateRemoteAddr(ip string) bool { match, err := regexp.MatchString(`^(?:(?:1[0-9][0-9]\.)|(?:2[0-4][0-9]\.)|(?:25[0-5]\.)|(?:[1-9][0-9]\.)|(?:[0-9]\.)){3}(?:(?:1[0-9][0-9])|(?:2[0-4][0-9])|(?:25[0-5])|(?:[1-9][0-9])|(?:[0-9]))\:(([0-9])|([1-9][0-9]{1,3})|([1-6][0-9]{0,4}))$`, ip) @@ -23,16 +52,28 @@ func ValidateRemoteAddr(ip string) bool { return match } -//InterceptIP 获取IP -func InterceptIP(str, substr string) string { +//ValidateURL 判断ip端口是否合法 +func ValidateURL(url string) bool { + match, err := regexp.MatchString(`^/(([a-zA-Z][0-9a-zA-Z+\-\.]*:)?/{0,2}[0-9a-zA-Z;/?:@&=+$\.\-_!~*'()%]+)?(#[0-9a-zA-Z;/?:@&=+$\.\-_!~*'()%]+)?$`, url) + if err != nil { + return false + } + return match +} + +//Intercept 获取IP +func Intercept(str, substr string) (string, string) { result := strings.Index(str, substr) var rs string + var bs string if result != -1 { rs = str[:result] + bs = str[result+1:] } else { rs = str + bs = str } - return rs + return rs, bs } //Md5 md5加密 diff --git a/utils/json.go b/utils/json.go new file mode 100644 index 0000000000000000000000000000000000000000..3ae10fd1679e2c4b7eaeba02723e2d42d8756beb --- /dev/null +++ b/utils/json.go @@ -0,0 +1,20 @@ +package utils + +import ( + "fmt" + + "github.com/robertkrimen/otto" +) + +//JSObjectToJSON 将js对象转为json +func JSObjectToJSON(s string) ([]byte, error) { + vm := otto.New() + v, err := vm.Run(fmt.Sprintf(` + cs = %s + JSON.stringify(cs) +`, s)) + if err != nil { + return nil, err + } + return []byte(v.String()), nil +} diff --git a/utils/mail.go b/utils/mail.go index 05ae12f5c92a69fcf12dc3a18c65887d29eda8f0..6adda598c5c2418fa41facc429e7ad2bba761cad 100644 --- a/utils/mail.go +++ b/utils/mail.go @@ -2,118 +2,134 @@ package utils import ( "crypto/tls" - "net" - "net/smtp" - "strings" + "fmt" - log "github.com/eolinker/goku-api-gateway/goku-log" + "github.com/eolinker/goku-api-gateway/server/entity" + + "gopkg.in/gomail.v2" ) -//SendToMail 发送邮件 -func SendToMail(user, password, host, to, subject, body, mailtype, smtpProtocol string) error { - hp := strings.Split(host, ":") - auth := smtp.PlainAuth("", user, password, hp[0]) - sendTO := strings.Split(to, ",") - if len(sendTO) < 2 { - if sendTO[0] == "" { - return nil - } - } - log.Debug(user, password, auth) - var contentType string - if mailtype == "html" { - contentType = "Content-Type: text/" + mailtype + "; charset=UTF-8" - } else { - contentType = "Content-Type: text/plain" + "; charset=UTF-8" - } - var err error - msg := []byte("To: " + to + "\r\nFrom: " + user + ">\r\nSubject: " + subject + "\r\n" + contentType + "\r\n\r\n" + body) - log.Debug("SendToMail", msg) - if smtpProtocol != "0" { - err = SendMailUsingTLS( - host, - auth, - user, - sendTO, - msg, - ) - if err != nil { +//SendMails 发送邮件 +func SendMails(smtpInfo entity.SMTPInfo, mailTo []string, subject string, body string) error { - err = SendMailUsingTLS( - host, - nil, - user, - sendTO, - msg, - ) + m := gomail.NewMessage() + m.SetHeader("From", fmt.Sprintf("%s<%s>", smtpInfo.Sender, smtpInfo.Account)) + m.SetHeader("To", mailTo...) + m.SetHeader("Subject", subject) + m.SetBody("text/html", body) - } - } else { - err = smtp.SendMail(host, auth, user, sendTO, msg) - if err != nil { - err = smtp.SendMail(host, nil, user, sendTO, msg) - } - } + d := gomail.NewDialer(smtpInfo.Address, smtpInfo.Port, smtpInfo.Account, smtpInfo.Password) + d.TLSConfig = &tls.Config{InsecureSkipVerify: true} + var err error + err = d.DialAndSend(m) return err } -//Dial return a smtp client -func Dial(addr string) (*smtp.Client, error) { - conn, err := tls.Dial("tcp", addr, nil) - if err != nil { - return nil, err - } - //分解主机端口字符串 - host, _, _ := net.SplitHostPort(addr) - return smtp.NewClient(conn, host) -} - -//SendMailUsingTLS 参考net/smtp的func SendMail() -//使用net.Dial连接tls(ssl)端口时,smtp.NewClient()会卡住且不提示err -//len(to)>1时,to[1]开始提示是密送 -func SendMailUsingTLS(addr string, auth smtp.Auth, from string, - to []string, msg []byte) (err error) { - - //create smtp client - c, err := Dial(addr) - if err != nil { - log.Error("Create smpt client error:", err) - return err - } - defer c.Close() - - if auth != nil { - if ok, _ := c.Extension("AUTH"); ok { - if err = c.Auth(auth); err != nil { - log.Error("Error during AUTH", err) - return err - } - } - } - - if err = c.Mail(from); err != nil { - return err - } - - for _, addr := range to { - if err = c.Rcpt(addr); err != nil { - return err - } - } - - w, err := c.Data() - if err != nil { - return err - } - - _, err = w.Write(msg) - if err != nil { - return err - } - - err = w.Close() - if err != nil { - return err - } - return c.Quit() -} +////SendToMail 发送邮件 +//func SendToMail(user, password, host, to, subject, body, mailtype, smtpProtocol string) error { +// hp := strings.Split(host, ":") +// auth := smtp.PlainAuth("", user, password, hp[0]) +// sendTO := strings.Split(to, ",") +// if len(sendTO) < 2 { +// if sendTO[0] == "" { +// return nil +// } +// } +// log.Debug(user, password, auth) +// var contentType string +// if mailtype == "html" { +// contentType = "Content-Type: text/" + mailtype + "; charset=UTF-8" +// } else { +// contentType = "Content-Type: text/plain" + "; charset=UTF-8" +// } +// var err error +// msg := []byte("To: " + to + "\r\nFrom: " + user + ">\r\nSubject: " + subject + "\r\n" + contentType + "\r\n\r\n" + body) +// log.Debug("SendToMail", msg) +// if smtpProtocol != "0" { +// err = SendMailUsingTLS( +// host, +// auth, +// user, +// sendTO, +// msg, +// ) +// if err != nil { +// +// err = SendMailUsingTLS( +// host, +// nil, +// user, +// sendTO, +// msg, +// ) +// +// } +// } else { +// err = smtp.SendMail(host, auth, user, sendTO, msg) +// if err != nil { +// err = smtp.SendMail(host, nil, user, sendTO, msg) +// } +// } +// return err +//} +// +////Dial return a smtp client +//func Dial(addr string) (*smtp.Client, error) { +// conn, err := tls.Dial("tcp", addr, nil) +// if err != nil { +// return nil, err +// } +// //分解主机端口字符串 +// host, _, _ := net.SplitHostPort(addr) +// return smtp.NewClient(conn, host) +//} +// +////SendMailUsingTLS 参考net/smtp的func SendMail() +////使用net.Dial连接tls(ssl)端口时,smtp.NewClient()会卡住且不提示err +////len(to)>1时,to[1]开始提示是密送 +//func SendMailUsingTLS(addr string, auth smtp.Auth, from string, +// to []string, msg []byte) (err error) { +// +// //create smtp client +// c, err := Dial(addr) +// if err != nil { +// log.Error("Create smpt client error:", err) +// return err +// } +// defer c.Close() +// +// if auth != nil { +// if ok, _ := c.Extension("AUTH"); ok { +// if err = c.Auth(auth); err != nil { +// log.Error("Error during AUTH", err) +// return err +// } +// } +// } +// +// if err = c.Mail(from); err != nil { +// return err +// } +// +// for _, addr := range to { +// if err = c.Rcpt(addr); err != nil { +// return err +// } +// } +// +// w, err := c.Data() +// if err != nil { +// return err +// } +// +// _, err = w.Write(msg) +// if err != nil { +// return err +// } +// +// err = w.Close() +// if err != nil { +// return err +// } +// return c.Quit() +//} diff --git a/utils/sftp.go b/utils/sftp.go new file mode 100644 index 0000000000000000000000000000000000000000..801de4fe9d902692d59d4d3f034151ddba8938a5 --- /dev/null +++ b/utils/sftp.go @@ -0,0 +1,128 @@ +package utils + +import ( + "fmt" + "os" + "path" + + "github.com/pkg/sftp" + + "golang.org/x/crypto/ssh" +) + +//SftpClient sftp客户端 +type SftpClient struct { + client *sftp.Client + passSize int64 + totalSize int64 + finish chan error +} + +//NewSftpClient new sftp客户端 +func NewSftpClient(client *ssh.Client) (*SftpClient, error) { + sc, err := SftpConnect(client) + if err != nil { + return nil, err + } + return &SftpClient{ + client: sc, + passSize: 0, + totalSize: 0, + finish: make(chan error), + }, nil +} + +//ScpCopy scp复制 +func (s *SftpClient) ScpCopy(localFilePath, remoteDir string) error { + var ( + err error + ) + + srcFile, err := os.Open(localFilePath) + if err != nil { + s.finish <- err + return err + } + defer srcFile.Close() + fInfo, err := srcFile.Stat() + if err != nil { + s.finish <- err + return err + } + s.totalSize = fInfo.Size() + + var remoteFileName = path.Base(localFilePath) + tmpFile := path.Join(remoteDir, fmt.Sprintf("%s%s", remoteFileName, ".tmp")) + + dstFile, err := s.client.Create(tmpFile) + if err != nil { + s.finish <- err + return err + } + defer dstFile.Close() + fmt.Println(dstFile.ReadFrom(srcFile)) + + _, err = dstFile.ReadFrom(srcFile) + if err != nil { + s.finish <- err + return err + } + s.client.Rename(tmpFile, path.Join(remoteDir, remoteFileName)) + s.finish <- nil + + return nil +} + +//GetProcess GetProcess +func (s *SftpClient) GetProcess() string { + if s.totalSize == 0 { + return "0.00" + } + return fmt.Sprintf("%.2f", float64(s.passSize)*100/float64(s.totalSize)) +} + +//CheckPathIsExisted CheckPathIsExisted +func (s *SftpClient) CheckPathIsExisted(path string) error { + _, err := s.client.Stat(path) + return err +} + +//Finish Finish +func (s *SftpClient) Finish() error { + //period := time.Duration(5) * time.Second + //t := time.NewTicker(period) + //for { + // select { + // case <-t.C: + // { + // fmt.Println(s.GetProcess()) + // } + // case err := <-s.finish: + // { + // fmt.Println("100.00") + // return err + // } + // } + //} + return <-s.finish +} + +//Close Close +func (s *SftpClient) Close() error { + close(s.finish) + return s.client.Close() +} + +//SftpConnect SftpConnect +func SftpConnect(client *ssh.Client) (*sftp.Client, error) { + var ( + sftpClient *sftp.Client + err error + ) + // create sftp client + if sftpClient, err = sftp.NewClient(client); err != nil { + return nil, err + } + + return sftpClient, nil +} diff --git a/utils/ssh.go b/utils/ssh.go index 09a463bad31d5122ae9d4d3e70a54f733958e005..28a85772b67d2a92d2706ac1d1a6e55e0b047b29 100644 --- a/utils/ssh.go +++ b/utils/ssh.go @@ -9,15 +9,14 @@ import ( // "io/ioutil" ) -//Connect SSH连接 -func Connect(user, password, host, key string, port int, cipherList []string) (*ssh.Session, error) { +//SSHClient SSHClient +func SSHClient(user, password, host, key string, port int, cipherList []string) (*ssh.Client, error) { var ( auth []ssh.AuthMethod addr string clientConfig *ssh.ClientConfig client *ssh.Client config ssh.Config - session *ssh.Session err error ) // get auth method @@ -65,7 +64,15 @@ func Connect(user, password, host, key string, port int, cipherList []string) (* if client, err = ssh.Dial("tcp", addr, clientConfig); err != nil { return nil, err } + return client, nil +} +//SessionConnect SessionConnect +func SessionConnect(client *ssh.Client) (*ssh.Session, error) { + var ( + session *ssh.Session + err error + ) // create session if session, err = client.NewSession(); err != nil { return nil, err