From 6b1b9d8c6a1793abb2257cd488db32d26717be41 Mon Sep 17 00:00:00 2001 From: Star <> Date: Mon, 27 May 2024 16:54:59 +0800 Subject: [PATCH] remove discover add dao many updates --- db/dao.js | 1 - discover/discover.go | 132 ---------------------------------- go.mod | 15 ++-- http/http.go | 106 +++++++++++++++------------ tests/discover_test.go | 52 -------------- tests/go.mod | 20 +++--- tests/http_test.go | 2 +- tests/http_tests/get_test.js | 2 +- tests/http_tests/jump_test.js | 2 +- tests/http_tests/post_test.js | 2 +- 10 files changed, 82 insertions(+), 252 deletions(-) delete mode 100644 discover/discover.go delete mode 100644 tests/discover_test.go diff --git a/db/dao.js b/db/dao.js index 6aa07a9..fe28d5d 100644 --- a/db/dao.js +++ b/db/dao.js @@ -1,7 +1,6 @@ import db from "apigo.cloud/git/apigo/plugins/db" import redis from "apigo.cloud/git/apigo/plugins/redis" import logger from "logger" -import console from "console"; /*{{$dao := . -}}*/ class DBConnector { diff --git a/discover/discover.go b/discover/discover.go deleted file mode 100644 index fc2a6e9..0000000 --- a/discover/discover.go +++ /dev/null @@ -1,132 +0,0 @@ -package discover - -import ( - "apigo.cloud/git/apigo/plugin" - "github.com/ssgo/discover" - "github.com/ssgo/httpclient" - "github.com/ssgo/log" - "github.com/ssgo/u" - "net/http" - "strings" -) - -type DiscoverApp struct { - app string - token string - caller *discover.Caller - logger *log.Logger - globalHeaders map[string]string -} - -func init() { - plugin.Register(plugin.Plugin{ - Id: "apigo.cloud/git/apigo/plugins/discover", - Name: "服务发现", - Objects: map[string]interface{}{ - "fetch": GetDiscoverApp, - }, - }) -} - -// GetDiscoverApp 获得一个服务发现的客户端,如果在配置(server>calls)中指定了AccessToken、超时时间或者HTTP协议(如:iZg753bnsBxTOqHjaeEdt2szvov95eLq34G6jiHBoeE=:1:s:60s)会自动在获得的客户端中设置好 -// GetDiscoverApp app 需要访问的服务名称 -// GetDiscoverApp return 服务发现客户端对象,支持的方法:get、post、put、delete、head、setGlobalHeaders -func GetDiscoverApp(app string, ctx *plugin.Context) *DiscoverApp { - logger := ctx.GetInject("*log.Logger").(*log.Logger) - var request *http.Request - if request1, ok := ctx.GetInject("*http.Request").(*http.Request); ok { - request = request1 - } - return &DiscoverApp{ - app: app, - logger: logger, - caller: discover.NewCaller(request, logger), - globalHeaders: map[string]string{}, - } -} - -// SetGlobalHeaders 设置固定的HTTP头部信息,在每个请求中都加入这些HTTP头 -// * SetGlobalHeaders 传入一个Key-Value对象的HTTP头信息 -func (dApp *DiscoverApp) SetGlobalHeaders(headers map[string]string) { - dApp.globalHeaders = headers -} - -// Get 发送GET请求 -// * path /开头的请求路径,调用时会自动加上负载均衡到的目标节点的URL前缀发送HTTP请求 -// * headers 传入一个Key-Value对象的HTTP头信息,如果不指定头信息这个参数可以省略不传 -// * return 返回结果对象,如果返回值是JSON格式,将自动转化为对象否则将字符串放在.result中,如发生错误将抛出异常,返回的对象中还包括:headers、statusCode、statusMessage -func (dApp *DiscoverApp) Get(path string, headers *map[string]string) (map[string]interface{}, error) { - return makeResult(dApp.logger, dApp.caller.Get(dApp.app, fixHTTPPath(path), dApp.makeHeaderArray(headers)...)) -} - -// Post 发送POST请求 -// * data 可以传入任意类型,如果不是字符串或二进制数组时会自动添加application/json头,数据将以json格式发送 -func (dApp *DiscoverApp) Post(path string, data *map[string]interface{}, headers *map[string]string) (map[string]interface{}, error) { - return makeResult(dApp.logger, dApp.caller.Post(dApp.app, fixHTTPPath(path), data, dApp.makeHeaderArray(headers)...)) -} - -// Put 发送PUT请求 -func (dApp *DiscoverApp) Put(path string, data *map[string]interface{}, headers *map[string]string) (map[string]interface{}, error) { - return makeResult(dApp.logger, dApp.caller.Put(dApp.app, fixHTTPPath(path), data, dApp.makeHeaderArray(headers)...)) -} - -// Delete 发送DELETE请求 -func (dApp *DiscoverApp) Delete(path string, data *map[string]interface{}, headers *map[string]string) (map[string]interface{}, error) { - return makeResult(dApp.logger, dApp.caller.Delete(dApp.app, fixHTTPPath(path), data, dApp.makeHeaderArray(headers)...)) -} - -// Head 发送HEAD请求 -func (dApp *DiscoverApp) Head(path string, headers *map[string]string) (map[string]interface{}, error) { - return makeResult(dApp.logger, dApp.caller.Head(dApp.app, fixHTTPPath(path), dApp.makeHeaderArray(headers)...)) -} - -func (dApp *DiscoverApp) makeHeaderArray(in *map[string]string) []string { - out := make([]string, 0) - if dApp.globalHeaders != nil { - for k, v := range dApp.globalHeaders { - out = append(out, k, v) - } - } - if in != nil { - for k, v := range *in { - out = append(out, k, v) - } - } - return out -} - -func fixHTTPPath(path string) string { - if !strings.HasPrefix(path, "/") { - return "/" + path - } - return path -} - -func makeResult(logger *log.Logger, result *httpclient.Result) (map[string]interface{}, error) { - r := map[string]interface{}{} - if result.Error != nil { - logger.Error(result.Error.Error()) - return nil, result.Error - } - - if result.Response != nil { - headers := map[string]string{} - for k, v := range result.Response.Header { - if len(v) == 1 { - headers[k] = v[0] - } else { - headers[k] = strings.Join(v, " ") - } - } - r["headers"] = headers - r["statusCode"] = result.Response.StatusCode - r["statusMessage"] = result.Response.Status - - if strings.Contains(result.Response.Header.Get("Content-Type"), "application/json") { - u.UnJson(result.String(), &r) - } else { - r["result"] = result.String() - } - } - return r, nil -} diff --git a/go.mod b/go.mod index cc55939..4cfa26c 100644 --- a/go.mod +++ b/go.mod @@ -8,12 +8,11 @@ require ( github.com/emmansun/gmsm v0.21.1 github.com/gorilla/websocket v1.5.1 github.com/obscuren/ecies v0.0.0-20150213224233-7c0f4a9b18d9 - github.com/ssgo/db v1.7.3 - github.com/ssgo/discover v1.7.3 - github.com/ssgo/httpclient v1.7.3 - github.com/ssgo/log v1.7.3 - github.com/ssgo/redis v1.7.3 - github.com/ssgo/u v1.7.3 + github.com/ssgo/db v1.7.5 + github.com/ssgo/httpclient v1.7.5 + github.com/ssgo/log v1.7.5 + github.com/ssgo/redis v1.7.5 + github.com/ssgo/u v1.7.5 github.com/tdewolff/parse/v2 v2.7.12 gopkg.in/yaml.v3 v3.0.1 ) @@ -22,8 +21,8 @@ require ( github.com/go-sql-driver/mysql v1.5.0 // indirect github.com/gomodule/redigo v1.8.8 // indirect github.com/mitchellh/mapstructure v1.4.1 // indirect - github.com/ssgo/config v1.7.3 // indirect - github.com/ssgo/standard v1.7.3 // indirect + github.com/ssgo/config v1.7.5 // indirect + github.com/ssgo/standard v1.7.5 // indirect github.com/stretchr/testify v1.8.1 // indirect golang.org/x/crypto v0.14.0 // indirect golang.org/x/net v0.17.0 // indirect diff --git a/http/http.go b/http/http.go index a1beda5..74b1cad 100644 --- a/http/http.go +++ b/http/http.go @@ -2,6 +2,7 @@ package http import ( "apigo.cloud/git/apigo/plugin" + "errors" "github.com/gorilla/websocket" "github.com/ssgo/httpclient" "github.com/ssgo/log" @@ -62,55 +63,51 @@ func (c *Client) SetGlobalHeaders(headers map[string]string) { // * url 以http://或https://开头的URL地址,如果设置了baseURL可以只提供path部分 // * headers 传入一个Key-Value对象的HTTP头信息,如果不指定头信息这个参数可以省略不传 // * return 返回结果对象,如果返回值是JSON格式,将自动转化为对象否则将字符串放在.result中,如发生错误将抛出异常,返回的对象中还包括:headers、statusCode、statusMessage -func (c *Client) Get(ctx *plugin.Context, url string, headers *map[string]string) (map[string]interface{}, error) { +func (c *Client) Get(ctx *plugin.Context, url string, headers *map[string]string) (*Result, error) { logger := ctx.GetInject("*log.Logger").(*log.Logger) return makeResult(logger, c.pool.Get(c.makeURL(url), c.makeHeaderArray(headers)...)) } // Post 发送POST请求 // * body 可以传入任意类型,如果不是字符串或二进制数组时会自动添加application/json头,数据将以json格式发送 -func (c *Client) Post(ctx *plugin.Context, url string, body interface{}, headers *map[string]string) (map[string]interface{}, error) { +func (c *Client) Post(ctx *plugin.Context, url string, body interface{}, headers *map[string]string) (*Result, error) { logger := ctx.GetInject("*log.Logger").(*log.Logger) return makeResult(logger, c.pool.Post(c.makeURL(url), body, c.makeHeaderArray(headers)...)) } // Put 发送PUT请求 -func (c *Client) Put(ctx *plugin.Context, url string, body interface{}, headers *map[string]string) (map[string]interface{}, error) { +func (c *Client) Put(ctx *plugin.Context, url string, body interface{}, headers *map[string]string) (*Result, error) { logger := ctx.GetInject("*log.Logger").(*log.Logger) return makeResult(logger, c.pool.Put(c.makeURL(url), body, c.makeHeaderArray(headers)...)) } // Delete 发送DELETE请求 -func (c *Client) Delete(ctx *plugin.Context, url string, body interface{}, headers *map[string]string) (map[string]interface{}, error) { +func (c *Client) Delete(ctx *plugin.Context, url string, body interface{}, headers *map[string]string) (*Result, error) { logger := ctx.GetInject("*log.Logger").(*log.Logger) return makeResult(logger, c.pool.Delete(c.makeURL(url), body, c.makeHeaderArray(headers)...)) } // Head 发送HEAD请求 -func (c *Client) Head(ctx *plugin.Context, url string, headers *map[string]string) (map[string]interface{}, error) { +func (c *Client) Head(ctx *plugin.Context, url string, headers *map[string]string) (*Result, error) { logger := ctx.GetInject("*log.Logger").(*log.Logger) return makeResult(logger, c.pool.Head(c.makeURL(url), c.makeHeaderArray(headers)...)) } // Do 发送请求 // * method 请求方法,GET、POST等 -func (c *Client) Do(ctx *plugin.Context, method string, url string, body interface{}, headers *map[string]string) (map[string]interface{}, error) { +func (c *Client) Do(ctx *plugin.Context, method string, url string, body interface{}, headers *map[string]string) (*Result, error) { logger := ctx.GetInject("*log.Logger").(*log.Logger) return makeResult(logger, c.pool.Do(method, c.makeURL(url), body, c.makeHeaderArray(headers)...)) } // ManualDo 手动处理请求,需要自行从返回结果中读取数据,可实现SSE客户端 // ManualDo return 应答的对象(需手动读取数据并关闭请求) -func (c *Client) ManualDo(ctx *plugin.Context, method string, url string, body interface{}, headers *map[string]string) (*Reader, error) { +func (c *Client) ManualDo(ctx *plugin.Context, method string, url string, body interface{}, headers *map[string]string) (*ManualResult, error) { logger := ctx.GetInject("*log.Logger").(*log.Logger) result := c.pool.ManualDo(method, url, body, c.makeHeaderArray(headers)...) - err, outHeaders, statusCode, _ := _makeResult(logger, result) - return &Reader{ - Error: err, - Headers: outHeaders, - StatusCode: statusCode, - response: result.Response, - logger: logger, + r1, _ := makeResult(logger, result) + return &ManualResult{ + Result: *r1, }, result.Error } @@ -132,23 +129,15 @@ func (c *Client) Open(ctx *plugin.Context, url string, headers *map[string]strin } } -func makeResult(logger *log.Logger, result *httpclient.Result) (map[string]interface{}, error) { +func makeResult(logger *log.Logger, result *httpclient.Result) (*Result, error) { err, headers, statusCode, output := _makeResult(logger, result) - if v, ok := output.(map[string]interface{}); ok { - if err != "" { - v["error"] = err - } - v["headers"] = headers - v["statusCode"] = statusCode - return v, result.Error - } else { - return map[string]interface{}{ - "error": err, - "headers": headers, - "statusCode": statusCode, - "result": output, - }, result.Error - } + return &Result{ + result: result, + Error: err, + StatusCode: statusCode, + Headers: headers, + Data: output, + }, result.Error } func _makeResult(logger *log.Logger, result *httpclient.Result) (err string, headers map[string]string, statusCode int, output interface{}) { @@ -169,8 +158,7 @@ func _makeResult(logger *log.Logger, result *httpclient.Result) (err string, hea statusCode = result.Response.StatusCode if strings.Contains(result.Response.Header.Get("Content-Type"), "application/json") { - output = map[string]interface{}{} - u.UnJson(result.String(), &output) + output = u.UnJson(result.String(), nil) } else { output = result.String() } @@ -348,29 +336,57 @@ func (ws *WS) EnableCompression() { ws.conn.EnableWriteCompression(true) } -type Reader struct { +type Result struct { + result *httpclient.Result Error string - Headers map[string]string StatusCode int - response *http.Response - closed bool - logger *log.Logger + Headers map[string]string + Data interface{} } -func (hr *Reader) Read(n int) (string, error) { +func (r *Result) String() string { + return r.result.String() +} + +func (r *Result) Bytes() []byte { + return r.result.Bytes() +} + +type ManualResult struct { + Result + closed bool +} + +func (r *ManualResult) Save(filename string) error { + if r.closed { + return errors.New("http client reader closed") + } + r.closed = true + return r.result.Save(filename) +} + +func (r *ManualResult) Read(n int) (string, error) { + if r.closed { + return "", errors.New("http client reader closed") + } buf := make([]byte, n) - n1, err := hr.response.Body.Read(buf) + n1, err := r.result.Response.Body.Read(buf) return string(buf[0:n1]), err } -func (hr *Reader) ReadBytes(n int) ([]byte, error) { + +func (r *ManualResult) ReadBytes(n int) ([]byte, error) { + if r.closed { + return nil, errors.New("http client reader closed") + } buf := make([]byte, n) - n1, err := hr.response.Body.Read(buf) + n1, err := r.result.Response.Body.Read(buf) return buf[0:n1], err } -func (hr *Reader) Close() error { - if hr.closed { + +func (r *ManualResult) Close() error { + if r.closed { return nil } - hr.closed = true - return hr.response.Body.Close() + r.closed = true + return r.result.Response.Body.Close() } diff --git a/tests/discover_test.go b/tests/discover_test.go deleted file mode 100644 index 9642697..0000000 --- a/tests/discover_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package tests - -import ( - "apigo.cloud/git/apigo/gojs" - _ "apigo.cloud/git/apigo/plugins/discover" - "github.com/ssgo/discover" - "github.com/ssgo/redis" - "github.com/ssgo/s" - "testing" -) - -func TestDiscover(t *testing.T) { - rdServer := StartRedis("16378") - defer rdServer.Close() - rd := redis.GetRedis("redis://localhost:16378", nil) - rd.HSET("echo", "localhost:11223", 100) - rd.SET("echo_localhost:11223", "1") - - s.Register(0, "/echo", func(in map[string]interface{}) map[string]interface{} { - return in - }, "") - s.Config.Listen = "11223,h2c" - discover.Config.Registry = "redis://localhost:16378" - discover.Config.Calls = map[string]string{"echo": ""} - as := s.AsyncStart() - defer as.Stop() - // discover.Start("") // if not use ssgo/s, manual start discover - - rt := gojs.New(nil) - defer rt.Close() - - err := rt.Exec(` - import discover from 'apigo.cloud/git/apigo/plugins/discover' - let echoSrv = discover.fetch('echo') -`) - Test(t, "fetch", err == nil, err) - - r, err := rt.Run(` - let r = echoSrv.get('/echo?aaa=111') - if(r.aaa !== '111') throw new Error('aaa is '+r.aaa+' not 111') - return true -`) - Test(t, "get", r == true && err == nil, r, err) - - r, err = rt.Run(` - let r = echoSrv.post('/echo', {aaa:111}) - if(r.aaa !== 111) throw new Error('aaa is '+r.aaa+' not 111') - return true -`) - Test(t, "post", r == true && err == nil, r, err) - -} diff --git a/tests/go.mod b/tests/go.mod index fade9c5..298fbf1 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -5,14 +5,12 @@ go 1.22 toolchain go1.22.1 require ( - apigo.cloud/git/apigo/gojs v0.0.6 + apigo.cloud/git/apigo/gojs v0.0.8 apigo.cloud/git/apigo/plugin v1.0.1 apigo.cloud/git/apigo/plugins v0.0.0 github.com/mattn/go-sqlite3 v1.14.18 - github.com/ssgo/discover v1.7.3 - github.com/ssgo/redis v1.7.3 - github.com/ssgo/s v1.7.3 - github.com/ssgo/u v1.7.3 + github.com/ssgo/s v1.7.5 + github.com/ssgo/u v1.7.5 github.com/tidwall/redcon v1.6.2 ) @@ -29,11 +27,13 @@ require ( github.com/obscuren/ecies v0.0.0-20150213224233-7c0f4a9b18d9 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/shirou/gopsutil/v3 v3.22.10 // indirect - github.com/ssgo/config v1.7.3 // indirect - github.com/ssgo/db v1.7.3 // indirect - github.com/ssgo/httpclient v1.7.3 // indirect - github.com/ssgo/log v1.7.3 // indirect - github.com/ssgo/standard v1.7.3 // indirect + github.com/ssgo/config v1.7.5 // indirect + github.com/ssgo/db v1.7.5 // indirect + github.com/ssgo/discover v1.7.5 // indirect + github.com/ssgo/httpclient v1.7.5 // indirect + github.com/ssgo/log v1.7.5 // indirect + github.com/ssgo/redis v1.7.5 // indirect + github.com/ssgo/standard v1.7.5 // indirect github.com/tdewolff/parse/v2 v2.7.12 // indirect github.com/tidwall/btree v1.1.0 // indirect github.com/tidwall/match v1.1.1 // indirect diff --git a/tests/http_test.go b/tests/http_test.go index b133c28..051c738 100644 --- a/tests/http_test.go +++ b/tests/http_test.go @@ -60,7 +60,7 @@ func TestH2C(t *testing.T) { import http from "apigo.cloud/git/apigo/plugins/http" let c = http.newH2C(10) r = c.post('http://'+server+'/echo', {aaa:111}) - if(r.aaa != 111) throw new Error('aaa is '+r.aaa+' not 111') + if(r.data.aaa != 111) throw new Error('aaa is '+r.data.aaa+' not 111') return true `) Test(t, "post for h2c", r == true && err == nil, r, err) diff --git a/tests/http_tests/get_test.js b/tests/http_tests/get_test.js index f1fd1cc..47cf99a 100644 --- a/tests/http_tests/get_test.js +++ b/tests/http_tests/get_test.js @@ -3,6 +3,6 @@ import http from "apigo.cloud/git/apigo/plugins/http" let serv = startTestServer('10803') let r = http.get('http://127.0.0.1:10803/echo?aaa=111') serv.stop() -if(r.aaa !== '111') throw new Error('aaa is '+r.aaa+' not 111') +if(r.data.aaa !== '111') throw new Error('aaa is '+r.data.aaa+' not 111') return true diff --git a/tests/http_tests/jump_test.js b/tests/http_tests/jump_test.js index 1c549b2..8b903b2 100644 --- a/tests/http_tests/jump_test.js +++ b/tests/http_tests/jump_test.js @@ -3,6 +3,6 @@ import http from "apigo.cloud/git/apigo/plugins/http" let serv = startTestServer('10803') let r = http.get('http://127.0.0.1:10803/jump') serv.stop() -if(r.aaa !== '222') throw new Error('aaa is '+r.aaa+' not 222') +if(r.data.aaa !== '222') throw new Error('aaa is '+r.data.aaa+' not 222') return true diff --git a/tests/http_tests/post_test.js b/tests/http_tests/post_test.js index 1ef0c19..c7b7d12 100644 --- a/tests/http_tests/post_test.js +++ b/tests/http_tests/post_test.js @@ -3,6 +3,6 @@ import http from "apigo.cloud/git/apigo/plugins/http" let serv = startTestServer('10803') let r = http.post('http://127.0.0.1:10803/echo', {aaa:111}) serv.stop() -if(r.aaa !== 111) throw new Error('aaa is '+r.aaa+' not 111') +if(r.data.aaa !== 111) throw new Error('aaa is '+r.data.aaa+' not 111') return true