Skip to content

Commit 03e220e

Browse files
committed
feat(resolv): make the Context more supportive of functional-style operations on streams of elements
BREAKING CHANGE: removed the `Query` related methods of the `Context` interface and added the `PosSet` interface. The `Query` related methods of the `Context` interface has been removed as follows: Methods of deletion to Context: ```go type Context interface { ... QueryByKeyWords(kw KeyWords) Pos QueryAllByKeyWords(kw KeyWords) []Pos ... } ``` Methods of addition to Context Interface: ```go type Context interface { ... ChildrenPosSet() PosSet ... } ``` Added the `PosSet` interface as follows: Interface of addition: ```go type PosSet interface { Filter(fn func(pos Pos) bool) PosSet Map(fn func(pos Pos) (Pos, error)) PosSet MapToPosSet(fn func(pos Pos) PosSet) PosSet QueryOne(kw KeyWords) Pos QueryAll(kw KeyWords) PosSet List() []Pos Targets() []Context Append(pos ...Pos) PosSet AppendWithPosSet(posSet PosSet) PosSet Error() error } ``` Methods of addition to Pos Interface: ```go type Pos interface { ... QueryOne(kw KeyWords) Pos QueryAll(kw KeyWords) PosSet } ``` To migrate the code for the `Context` operations, follow the example below: Before: ```go package main import ( "fmt" "github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context_type" "github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration" "github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context" "github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context/local" ) func main() { conf, err := configuration.NewNginxConfigFromJsonBytes(jsondata) if err != nil { panic(err) } for _, pos := range conf.Main().QueryByKeyWords(context.NewKeyWords(context_type.TypeHttp). SetSkipQueryFilter(context.SkipDisabledCtxFilterFunc)).Target(). QueryByKeyWords(context.NewKeyWords(context_type.TypeServer). SetSkipQueryFilter(context.SkipDisabledCtxFilterFunc)).Target(). QueryAllByKeyWords(context.NewKeyWords(context_type.TypeDirective). SetCascaded(false). SetStringMatchingValue("server_name test1.com"). SetSkipQueryFilter(context.SkipDisabledCtxFilterFunc)) { // query `server` context, its server name is "test1.com" server, _ := pos.Position() if server.QueryByKeyWords(context.NewKeyWords(context_type.TypeDirective). SetCascaded(false). SetRegexpMatchingValue("^listen 80$"). SetSkipQueryFilter(context.SkipDisabledCtxFilterFunc)).Target().Error() != nil { // query `server` context, its listen port is 80 continue } // query the "proxy_pass" `directive` context, which is in `if` context(value: "($http_api_name != '')") and `location` context(value: "/test1-location") ctx, idx := server.QueryByKeyWords(context.NewKeyWords(context_type.TypeLocation). SetRegexpMatchingValue(`^/test1-location$`). SetSkipQueryFilter(context.SkipDisabledCtxFilterFunc)).Target(). QueryByKeyWords(context.NewKeyWords(context_type.TypeIf). SetRegexpMatchingValue(`^\(\$http_api_name != ''\)$`). SetSkipQueryFilter(context.SkipDisabledCtxFilterFunc)).Target(). QueryByKeyWords(context.NewKeyWords(context_type.TypeDirective). SetStringMatchingValue("proxy_pass"). SetSkipQueryFilter(context.SkipDisabledCtxFilterFunc)).Position() // insert an inline comment after the "proxy_pass" `directive` context err = ctx.Insert(local.NewContext(context_type.TypeInlineComment, fmt.Sprintf("[%s]test comments", time.Now().String())), idx+1).Error() if err != nil { panic(err) } } } ``` After: ```go package main import ( "fmt" "github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context_type" "github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration" "github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context" "github.com/ClessLi/bifrost/pkg/resolv/V3/nginx/configuration/context/local" ) func main() { conf, err := configuration.NewNginxConfigFromJsonBytes(jsondata) if err != nil { panic(err) } ctx, idx := conf.Main().ChildrenPosSet(). QueryOne(nginx_ctx.NewKeyWords(context_type.TypeHttp). SetSkipQueryFilter(context.SkipDisabledCtxFilterFunc)). QueryAll(nginx_ctx.NewKeyWords(context_type.TypeServer). SetSkipQueryFilter(context.SkipDisabledCtxFilterFunc)). Filter( // filter out `server` context positions, theirs server name is "test1.com" func(pos nginx_ctx.Pos) bool { return pos.QueryOne(context.NewKeyWords(context_type.TypeDirective). SetCascaded(false). SetStringMatchingValue("server_name test1.com"). SetSkipQueryFilter(context.SkipDisabledCtxFilterFunc)). Target().Error() == nil }, ). Filter( // filter out `server` context positions, theirs listen port is 80 func(pos nginx_ctx.Pos) bool { return pos.QueryOne(context.NewKeyWords(context_type.TypeDirective). SetCascaded(false). SetRegexpMatchingValue("^listen 80$"). SetSkipQueryFilter(context.SkipDisabledCtxFilterFunc)). Target().Error() == nil }, ). // query the "proxy_pass" `directive` context position, which is in `if` context(value: "($http_api_name != '')") and `location` context(value: "/test1-location") QueryOne(nginx_ctx.NewKeyWords(context_type.TypeLocation). SetRegexpMatchingValue(`^/test1-location$`). SetSkipQueryFilter(context.SkipDisabledCtxFilterFunc)). QueryOne(nginx_ctx.NewKeyWords(context_type.TypeIf). SetRegexpMatchingValue(`^\(\$http_api_name != ''\)$`). SetSkipQueryFilter(context.SkipDisabledCtxFilterFunc)). QueryOne(nginx_ctx.NewKeyWords(context_type.TypeDirective). SetStringMatchingValue("proxy_pass"). SetSkipQueryFilter(context.SkipDisabledCtxFilterFunc)). Position() // insert an inline comment after the "proxy_pass" `directive` context err = ctx.Insert(local.NewContext(context_type.TypeInlineComment, fmt.Sprintf("[%s]test comments", time.Now().String())), idx+1).Error() if err != nil { panic(err) } } ```
1 parent d1919fe commit 03e220e

File tree

34 files changed

+652
-734
lines changed

34 files changed

+652
-734
lines changed

README.md

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -275,22 +275,44 @@ func main() {
275275
if err != nil {
276276
panic(err)
277277
}
278-
for _, pos := range conf.Main().QueryByKeyWords(context.NewKeyWords(context_type.TypeHttp)).Target().
279-
QueryByKeyWords(context.NewKeyWords(context_type.TypeServer)).Target().
280-
QueryAllByKeyWords(context.NewKeyWords(context_type.TypeDirective).SetStringMatchingValue("server_name test1.com")) { // query `server` context, its server name is "test1.com"
281-
server, _ := pos.Position()
282-
if server.QueryByKeyWords(context.NewKeyWords(context_type.TypeDirective).SetRegexpMatchingValue("^listen 80$")).Target().Error() != nil { // query `server` context, its listen port is 80
283-
continue
284-
}
285-
// query the "proxy_pass" `directive` context, which is in `if` context(value: "($http_api_name != '')") and `location` context(value: "/test1-location")
286-
ctx, idx := server.QueryByKeyWords(context.NewKeyWords(context_type.TypeLocation).SetRegexpMatchingValue(`^/test1-location$`)).Target().
287-
QueryByKeyWords(context.NewKeyWords(context_type.TypeIf).SetRegexpMatchingValue(`^\(\$http_api_name != ''\)$`)).Target().
288-
QueryByKeyWords(context.NewKeyWords(context_type.TypeDirective).SetStringMatchingValue("proxy_pass")).Position()
289-
// insert an inline comment after the "proxy_pass" `directive` context
290-
err = ctx.Insert(local.NewContext(context_type.TypeInlineComment, fmt.Sprintf("[%s]test comments", time.Now().String())), idx+1).Error()
291-
if err != nil {
292-
panic(err)
293-
}
278+
ctx, idx := conf.Main().ChildrenPosSet().
279+
QueryOne(nginx_ctx.NewKeyWords(context_type.TypeHttp).
280+
SetSkipQueryFilter(context.SkipDisabledCtxFilterFunc)).
281+
QueryAll(nginx_ctx.NewKeyWords(context_type.TypeServer).
282+
SetSkipQueryFilter(context.SkipDisabledCtxFilterFunc)).
283+
Filter( // filter out `server` context positions, theirs server name is "test1.com"
284+
func(pos nginx_ctx.Pos) bool {
285+
return pos.QueryOne(context.NewKeyWords(context_type.TypeDirective).
286+
SetCascaded(false).
287+
SetStringMatchingValue("server_name test1.com").
288+
SetSkipQueryFilter(context.SkipDisabledCtxFilterFunc)).
289+
Target().Error() == nil
290+
},
291+
).
292+
Filter( // filter out `server` context positions, theirs listen port is 80
293+
func(pos nginx_ctx.Pos) bool {
294+
return pos.QueryOne(context.NewKeyWords(context_type.TypeDirective).
295+
SetCascaded(false).
296+
SetRegexpMatchingValue("^listen 80$").
297+
SetSkipQueryFilter(context.SkipDisabledCtxFilterFunc)).
298+
Target().Error() == nil
299+
},
300+
).
301+
// query the "proxy_pass" `directive` context position, which is in `if` context(value: "($http_api_name != '')") and `location` context(value: "/test1-location")
302+
QueryOne(nginx_ctx.NewKeyWords(context_type.TypeLocation).
303+
SetRegexpMatchingValue(`^/test1-location$`).
304+
SetSkipQueryFilter(context.SkipDisabledCtxFilterFunc)).
305+
QueryOne(nginx_ctx.NewKeyWords(context_type.TypeIf).
306+
SetRegexpMatchingValue(`^\(\$http_api_name != ''\)$`).
307+
SetSkipQueryFilter(context.SkipDisabledCtxFilterFunc)).
308+
QueryOne(nginx_ctx.NewKeyWords(context_type.TypeDirective).
309+
SetStringMatchingValue("proxy_pass").
310+
SetSkipQueryFilter(context.SkipDisabledCtxFilterFunc)).
311+
Position()
312+
// insert an inline comment after the "proxy_pass" `directive` context
313+
err = ctx.Insert(local.NewContext(context_type.TypeInlineComment, fmt.Sprintf("[%s]test comments", time.Now().String())), idx+1).Error()
314+
if err != nil {
315+
panic(err)
294316
}
295317
}
296318
```

internal/bifrost/transport/v1/fake/web_server_bin_cmd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ func (w webServerBinCMD) Exec(ctx context.Context, request *pbv1.ExecuteRequest)
1212
logV1.Infof("web server binary command excuting...")
1313
return &pbv1.ExecuteResponse{
1414
Successful: true,
15-
Msg: []byte("success\n"),
15+
Stdout: []byte("success\n"),
1616
}, nil
1717
}

internal/pkg/auth/daemon/daemon.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ import (
1616

1717
// Start, 守护进程 start 方法函数
1818
// 返回值:
19-
// 错误
19+
//
20+
// 错误
2021
func Start() (err error) {
2122
// 判断当前进程是子进程还是主进程
2223
if isMain() { // 主进程时
@@ -91,7 +92,8 @@ func Start() (err error) {
9192

9293
// Stop, 守护进程 stop 方法函数
9394
// 返回值:
94-
// 错误
95+
//
96+
// 错误
9597
func Stop() error {
9698
// 判断bifrost进程是否存在
9799
process, procErr := getProc(pidFile)
@@ -117,7 +119,8 @@ func Stop() error {
117119

118120
// Restart, 守护进程 restart 方法函数
119121
// 返回值:
120-
// 错误
122+
//
123+
// 错误
121124
func Restart() error {
122125
// 判断当前进程是主进程还是子进程
123126
if isMain() { // 主进程时
@@ -146,7 +149,8 @@ func Restart() error {
146149

147150
// Status, 守护进程 status 方法函数
148151
// 返回值:
149-
// 错误
152+
//
153+
// 错误
150154
func Status() (int, error) {
151155
pid, pidErr := getPid(pidFile)
152156
if pidErr != nil {
@@ -158,7 +162,8 @@ func Status() (int, error) {
158162

159163
// isMain, 判断当前进程是否为主进程
160164
// 返回值:
161-
// true: 是主进程; false: 是子进程
165+
//
166+
// true: 是主进程; false: 是子进程
162167
func isMain() bool {
163168
return os.Getppid() != 1
164169
}

internal/pkg/auth/daemon/funcs.go

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,13 @@ import (
1414

1515
// readFile, 读取文件函数
1616
// 参数:
17-
// path: 文件路径字符串
17+
//
18+
// path: 文件路径字符串
19+
//
1820
// 返回值:
19-
// 文件数据
20-
// 错误
21+
//
22+
// 文件数据
23+
// 错误
2124
func readFile(path string) ([]byte, error) {
2225
f, err := os.Open(path)
2326
if err != nil {
@@ -33,10 +36,13 @@ func readFile(path string) ([]byte, error) {
3336

3437
// PathExists, 判断文件路径是否存在函数
3538
// 参数:
36-
// path: 待判断的文件路径字符串
39+
//
40+
// path: 待判断的文件路径字符串
41+
//
3742
// 返回值:
38-
// true: 存在; false: 不存在
39-
// 错误
43+
//
44+
// true: 存在; false: 不存在
45+
// 错误
4046
func PathExists(path string) (bool, error) {
4147
_, err := os.Stat(path)
4248
if err == nil || os.IsExist(err) {
@@ -50,8 +56,9 @@ func PathExists(path string) (bool, error) {
5056

5157
// Log, 日志记录函数
5258
// 参数:
53-
// level: 日志级别对象
54-
// message: 需记录的日志信息字符串
59+
//
60+
// level: 日志级别对象
61+
// message: 需记录的日志信息字符串
5562
func Log(level logger.LogLevel, message string, a ...interface{}) {
5663
myLogger.Log(level, fmt.Sprintf(message, a...))
5764
}
@@ -74,8 +81,9 @@ func rmPidFile(path string) {
7481

7582
// getPid, 查询pid文件并返回pid
7683
// 返回值:
77-
// pid
78-
// 错误
84+
//
85+
// pid
86+
// 错误
7987
func getPid(path string) (int, error) {
8088
// 判断pid文件是否存在
8189
if _, err := os.Stat(path); err == nil || os.IsExist(err) { // 存在
@@ -104,7 +112,8 @@ func getPid(path string) (int, error) {
104112

105113
// configCheck, 检查bifrost配置项是否完整
106114
// 返回值:
107-
// 错误
115+
//
116+
// 错误
108117
func configCheck() error {
109118
// 初始化认证数据库或认证配置信息
110119
if AuthConf.AuthService == nil {

internal/pkg/auth/service/jwt.go

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,13 @@ var ExpireTime = 3600 // token有效期
2525

2626
// getToken, token生成函数,根据jwt断言对象编码为token
2727
// 参数:
28-
// claims: 用户jwt断言对象指针
28+
//
29+
// claims: 用户jwt断言对象指针
30+
//
2931
// 返回值:
30-
// token字符串
31-
// 错误
32+
//
33+
// token字符串
34+
// 错误
3235
func (c *JWTClaims) getToken() (string, error) {
3336
token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
3437
signedToken, err := token.SignedString([]byte(password.Secret))
@@ -41,10 +44,13 @@ func (c *JWTClaims) getToken() (string, error) {
4144

4245
// verifyAction, 认证token有效性函数
4346
// 参数:
44-
// strToken: token字符串
47+
//
48+
// strToken: token字符串
49+
//
4550
// 返回值:
46-
// 用户jwt断言对象指针
47-
// 错误
51+
//
52+
// 用户jwt断言对象指针
53+
// 错误
4854
func (s *AuthService) verifyAction(strToken string) (*JWTClaims, error) {
4955
// 解析token
5056
token, err := jwt.ParseWithClaims(strToken, &JWTClaims{}, func(token *jwt.Token) (interface{}, error) {
@@ -79,9 +85,12 @@ func (s *AuthService) verifyAction(strToken string) (*JWTClaims, error) {
7985

8086
// validUser, 用户认证函数,判断用户是否有效
8187
// 参数:
82-
// claims: 用户jwt断言对象指针
88+
//
89+
// claims: 用户jwt断言对象指针
90+
//
8391
// 返回值:
84-
// 用户是否有效
92+
//
93+
// 用户是否有效
8594
func (s *AuthService) validUser(claims *JWTClaims) bool {
8695
if s.AuthDBConfig == nil {
8796
if s.AuthConfig != nil {
@@ -111,10 +120,13 @@ func (s *AuthService) validUser(claims *JWTClaims) bool {
111120

112121
// getPasswd, 用户密码查询函数
113122
// 参数:
114-
// sqlStr: 查询语句
123+
//
124+
// sqlStr: 查询语句
125+
//
115126
// 返回值:
116-
// 用户加密密码
117-
// 错误
127+
//
128+
// 用户加密密码
129+
// 错误
118130
func (s *AuthService) getPasswd(sqlStr string) (string, error) {
119131
mysqlUrl := fmt.Sprintf(
120132
"%s:%s@%s(%s:%d)/%s?charset=utf8",

pkg/client/bifrost/v1/transport/transport.go

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,16 @@ type transport struct {
4444
decoderFactory decoder.Factory
4545
encoderFactory encoder.Factory
4646

47-
onceWebServerConfig sync.Once
48-
onceWebServerStatistics sync.Once
49-
onceWebServerStatus sync.Once
50-
onceWebServerLogWatcher sync.Once
51-
onceWebServerBinCMDWatcher sync.Once
52-
singletonWSCTXP WebServerConfigTransport
53-
singletonWSSTXP WebServerStatisticsTransport
54-
singletonWSStatusTXP WebServerStatusTransport
55-
singletonWSLWTXP WebServerLogWatcherTransport
56-
singletonWSBCTXP WebServerBinCMDTransport
47+
onceWebServerConfig sync.Once
48+
onceWebServerStatistics sync.Once
49+
onceWebServerStatus sync.Once
50+
onceWebServerLogWatcher sync.Once
51+
onceWebServerBinCMD sync.Once
52+
singletonWSCTXP WebServerConfigTransport
53+
singletonWSSTXP WebServerStatisticsTransport
54+
singletonWSStatusTXP WebServerStatusTransport
55+
singletonWSLWTXP WebServerLogWatcherTransport
56+
singletonWSBCTXP WebServerBinCMDTransport
5757
}
5858

5959
func (t *transport) WebServerConfig() WebServerConfigTransport {
@@ -117,7 +117,7 @@ func (t *transport) WebServerLogWatcher() WebServerLogWatcherTransport {
117117
}
118118

119119
func (t *transport) WebServerBinCMD() WebServerBinCMDTransport {
120-
t.onceWebServerBinCMDWatcher.Do(func() {
120+
t.onceWebServerBinCMD.Do(func() {
121121
if t.singletonWSBCTXP == nil {
122122
t.singletonWSBCTXP = newWebServerBinCMDTransport(t)
123123
}
@@ -133,13 +133,13 @@ func (t *transport) WebServerBinCMD() WebServerBinCMDTransport {
133133

134134
func New(conn *grpc.ClientConn) Factory {
135135
return &transport{
136-
conn: conn,
137-
decoderFactory: decoder.New(),
138-
encoderFactory: encoder.New(),
139-
onceWebServerConfig: sync.Once{},
140-
onceWebServerStatistics: sync.Once{},
141-
onceWebServerStatus: sync.Once{},
142-
onceWebServerLogWatcher: sync.Once{},
143-
onceWebServerBinCMDWatcher: sync.Once{},
136+
conn: conn,
137+
decoderFactory: decoder.New(),
138+
encoderFactory: encoder.New(),
139+
onceWebServerConfig: sync.Once{},
140+
onceWebServerStatistics: sync.Once{},
141+
onceWebServerStatus: sync.Once{},
142+
onceWebServerLogWatcher: sync.Once{},
143+
onceWebServerBinCMD: sync.Once{},
144144
}
145145
}

pkg/json/nginx/unmarshal.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ func unmarshal(b []byte, p unmarshaler, caches *nginx.Caches) (nginx.Parser, err
361361
}
362362

363363
// unmarshalChildren, 解析并反序列化子json串切片对象的内部函数.
364+
//
364365
//nolint:funlen,gocognit,gocyclo
365366
func unmarshalChildren(bytes []*json.RawMessage, caches *nginx.Caches) (children []nginx.Parser, err error) {
366367
// parseContext, 用于解析json串归属于哪类需反序列化对象的匿名函数

pkg/resolv/V2/nginx/configuration/configuration.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ import (
2222
// keyword string: <parser type>[':sep: <value string>', ':sep: :reg: <value regexp>']
2323
//
2424
// e.g. for Nginx Config keyword string:
25-
// 1) server
26-
// 2) location:sep: :reg: \^\~\s+\/
27-
// 3) key:sep: server_name test1\.com
28-
// 4) comment:sep: :reg: .*
25+
// 1. server
26+
// 2. location:sep: :reg: \^\~\s+\/
27+
// 3. key:sep: server_name test1\.com
28+
// 4. comment:sep: :reg: .*
2929
type Configuration interface {
3030
Querier
3131
// insert

pkg/resolv/V2/nginx/configuration/querier.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ import (
1313
// keyword string: <parser type>[':sep: <value string>', ':sep: :reg: <value regexp>']
1414
//
1515
// e.g. for Nginx Config keyword string:
16-
// 1) server
17-
// 2) location:sep: :reg: \^\~\s+\/
18-
// 3) key:sep: server_name test1\.com
19-
// 4) comment:sep: :reg: .*
16+
// 1. server
17+
// 2. location:sep: :reg: \^\~\s+\/
18+
// 3. key:sep: server_name test1\.com
19+
// 4. comment:sep: :reg: .*
2020
type Querier interface {
2121
// keyword string: <parser type>[':sep: <value string>', ':sep: :reg: <value regexp>']
2222
//

pkg/resolv/V2/utils/tgz_funcs.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ import (
1212
// TarGZ, 归档操作函数
1313
//
1414
// 参数:
15-
// dest: 归档文件路径
16-
// filenames: 配置文件路径切片
15+
//
16+
// dest: 归档文件路径
17+
// filenames: 配置文件路径切片
18+
//
1719
// 返回值:
18-
// 错误
20+
//
21+
// 错误
1922
func TarGZ(dest string, filenames []string) (err error) {
2023
if filenames == nil || len(filenames) < 1 {
2124
return errors.New("filename list is null")
@@ -59,11 +62,14 @@ func TarGZ(dest string, filenames []string) (err error) {
5962
// compress, 归档压缩子函数
6063
//
6164
// 参数:
62-
// fd: 被归档文件的系统文件对象指针
63-
// prefix: 被归档文件的目录路径
64-
// tgzw: tar文件对象指针
65+
//
66+
// fd: 被归档文件的系统文件对象指针
67+
// prefix: 被归档文件的目录路径
68+
// tgzw: tar文件对象指针
69+
//
6570
// 返回值:
66-
// 错误
71+
//
72+
// 错误
6773
func compress(fd *os.File, prefix string, tgzw *tar.Writer) error {
6874

6975
// 加载被归档文件信息

0 commit comments

Comments
 (0)