Skip to content

Commit

Permalink
add: sentinel plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
WeixinX committed Aug 3, 2024
1 parent b2f38f6 commit 6b827cf
Show file tree
Hide file tree
Showing 21 changed files with 3,820 additions and 4 deletions.
6 changes: 6 additions & 0 deletions plugins/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ require (
require (
github.com/OneOfOne/xxhash v1.2.8 // indirect
github.com/agnivade/levenshtein v1.1.1 // indirect
github.com/alibaba/sentinel-golang v1.0.4 // indirect
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/casbin/govaluate v1.1.0 // indirect
Expand All @@ -64,6 +65,8 @@ require (
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/iancoleman/strcase v0.3.0 // indirect
github.com/lyft/protoc-gen-star/v2 v2.0.3 // indirect
github.com/planetscale/vtprotobuf v0.5.1-0.20231212170721-e7d721933795 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.19.0 // indirect
Expand All @@ -72,6 +75,7 @@ require (
github.com/prometheus/procfs v0.12.0 // indirect
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/stoewer/go-strcase v1.2.0 // indirect
github.com/tchap/go-patricia/v2 v2.3.1 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
Expand All @@ -85,10 +89,12 @@ require (
go.uber.org/zap v1.27.0 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.15.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240325203815-454cdb8f5daa // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect
google.golang.org/grpc v1.63.2 // indirect
Expand Down
389 changes: 385 additions & 4 deletions plugins/go.sum

Large diffs are not rendered by default.

59 changes: 59 additions & 0 deletions plugins/plugins/sentinel/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright The HTNN Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// 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.

package sentinel

import (
"mosn.io/htnn/api/pkg/filtermanager/api"
"mosn.io/htnn/api/pkg/plugins"
"mosn.io/htnn/plugins/plugins/sentinel/rules"
"mosn.io/htnn/types/plugins/sentinel"

sentinelApi "github.com/alibaba/sentinel-golang/api"
sentinelConf "github.com/alibaba/sentinel-golang/core/config"
)

func init() {
plugins.RegisterPlugin(sentinel.Name, &plugin{})
}

type plugin struct {
sentinel.Plugin
}

func (p *plugin) Factory() api.FilterFactory {
return factory
}

func (p *plugin) Config() api.PluginConfig {
return &config{}

Check warning on line 40 in plugins/plugins/sentinel/config.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/config.go#L39-L40

Added lines #L39 - L40 were not covered by tests
}

type config struct {
sentinel.Config
}

func (conf *config) Init(cb api.ConfigCallbackHandler) error {
sconf := sentinelConf.NewDefaultConfig()
err := sentinelApi.InitWithConfig(sconf)
if err != nil {
return err

Check warning on line 51 in plugins/plugins/sentinel/config.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/config.go#L47-L51

Added lines #L47 - L51 were not covered by tests
}

_, err = rules.Load(conf.Type, conf.Rule)
if err != nil {
return err

Check warning on line 56 in plugins/plugins/sentinel/config.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/config.go#L54-L56

Added lines #L54 - L56 were not covered by tests
}
return nil

Check warning on line 58 in plugins/plugins/sentinel/config.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/config.go#L58

Added line #L58 was not covered by tests
}
24 changes: 24 additions & 0 deletions plugins/plugins/sentinel/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright The HTNN Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// 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.

package sentinel

import (
"testing"
)

// TODO(WeixinX)
func TestConfig(t *testing.T) {

}
71 changes: 71 additions & 0 deletions plugins/plugins/sentinel/filter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright The HTNN Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// 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.

package sentinel

import (
"mosn.io/htnn/api/pkg/filtermanager/api"
types "mosn.io/htnn/types/plugins/sentinel"

sentinel "github.com/alibaba/sentinel-golang/api"
"github.com/alibaba/sentinel-golang/core/base"
)

func factory(c interface{}, callbacks api.FilterCallbackHandler) api.Filter {
return &filter{
callbacks: callbacks,
config: c.(*config),

Check warning on line 28 in plugins/plugins/sentinel/filter.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/filter.go#L25-L28

Added lines #L25 - L28 were not covered by tests
}
}

type filter struct {
api.PassThroughFilter

callbacks api.FilterCallbackHandler
config *config
}

// Sentinel traffic control
func (f *filter) verify(resName string) bool {
e, b := sentinel.Entry(resName, sentinel.WithTrafficType(base.Inbound), sentinel.WithArgs())
if b != nil {

Check warning on line 42 in plugins/plugins/sentinel/filter.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/filter.go#L40-L42

Added lines #L40 - L42 were not covered by tests
// blocked
return false

Check warning on line 44 in plugins/plugins/sentinel/filter.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/filter.go#L44

Added line #L44 was not covered by tests
}

// passed
e.Exit()
return true

Check warning on line 49 in plugins/plugins/sentinel/filter.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/filter.go#L48-L49

Added lines #L48 - L49 were not covered by tests
}

// TODO(WeixinX): 完善限流逻辑
func (f *filter) DecodeHeaders(headers api.RequestHeaderMap, endStream bool) api.ResultAction {
config := f.config
var vals []string
var resName string
if config.Key.Source == types.Key_HEADER {
vals = headers.Values(config.Key.Name)
} else {
vals = headers.URL().Query()[config.Key.Name]

Check warning on line 60 in plugins/plugins/sentinel/filter.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/filter.go#L53-L60

Added lines #L53 - L60 were not covered by tests
}

if len(vals) >= 1 {
resName = vals[0]

Check warning on line 64 in plugins/plugins/sentinel/filter.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/filter.go#L63-L64

Added lines #L63 - L64 were not covered by tests
}

if ok := f.verify(resName); !ok {
return &api.LocalResponse{Code: 429}

Check warning on line 68 in plugins/plugins/sentinel/filter.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/filter.go#L67-L68

Added lines #L67 - L68 were not covered by tests
}
return api.Continue

Check warning on line 70 in plugins/plugins/sentinel/filter.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/filter.go#L70

Added line #L70 was not covered by tests
}
24 changes: 24 additions & 0 deletions plugins/plugins/sentinel/filter_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright The HTNN Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// 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.

package sentinel

import (
"testing"
)

// TODO(WeixinX)
func TestFilter(t *testing.T) {

}
46 changes: 46 additions & 0 deletions plugins/plugins/sentinel/rules/circuitbreaker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright The HTNN Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// 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.

package rules

import (
types "mosn.io/htnn/types/plugins/sentinel"

"github.com/alibaba/sentinel-golang/core/circuitbreaker"
)

func LoadCircuitBreakerRule(rule *types.CircuitBreakerRule) (bool, error) {
oldRules := circuitbreaker.GetRules()
newRules := make([]*circuitbreaker.Rule, 0, len(oldRules)+1)
i := 0
for _, r := range oldRules {
tmp := r
newRules[i] = &tmp
i++

Check warning on line 30 in plugins/plugins/sentinel/rules/circuitbreaker.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/rules/circuitbreaker.go#L23-L30

Added lines #L23 - L30 were not covered by tests
}

newRules[i] = &circuitbreaker.Rule{
Id: rule.Id,
Resource: rule.Resource,
Strategy: circuitbreaker.Strategy(rule.Strategy),
RetryTimeoutMs: rule.RetryTimeoutMs,
MinRequestAmount: rule.MinRequestAmount,
StatIntervalMs: rule.StatIntervalMs,
StatSlidingWindowBucketCount: rule.StatSlidingWindowBucketCount,
MaxAllowedRtMs: rule.MaxAllowedRtMs,
Threshold: rule.Threshold,
ProbeNum: rule.ProbeNum,

Check warning on line 43 in plugins/plugins/sentinel/rules/circuitbreaker.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/rules/circuitbreaker.go#L33-L43

Added lines #L33 - L43 were not covered by tests
}
return circuitbreaker.LoadRules(newRules)

Check warning on line 45 in plugins/plugins/sentinel/rules/circuitbreaker.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/rules/circuitbreaker.go#L45

Added line #L45 was not covered by tests
}
51 changes: 51 additions & 0 deletions plugins/plugins/sentinel/rules/flow.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright The HTNN Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// 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.

package rules

import (
types "mosn.io/htnn/types/plugins/sentinel"

"github.com/alibaba/sentinel-golang/core/flow"
)

func LoadFlowRule(rule *types.FlowRule) (bool, error) {
oldRules := flow.GetRules()
newRules := make([]*flow.Rule, 0, len(oldRules)+1)
i := 0
for _, r := range oldRules {
tmp := r
newRules[i] = &tmp
i++

Check warning on line 30 in plugins/plugins/sentinel/rules/flow.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/rules/flow.go#L23-L30

Added lines #L23 - L30 were not covered by tests
}

newRules[i] = &flow.Rule{
ID: rule.Id,
Resource: rule.Resource,
TokenCalculateStrategy: flow.TokenCalculateStrategy(rule.TokenCalculateStrategy),
ControlBehavior: flow.ControlBehavior(rule.ControlBehavior),
Threshold: rule.Threshold,
RelationStrategy: flow.RelationStrategy(rule.RelationStrategy),
RefResource: rule.RefResource,
MaxQueueingTimeMs: rule.MaxQueueingTimeMs,
WarmUpPeriodSec: rule.WarmUpPeriodSec,
WarmUpColdFactor: rule.WarmUpColdFactor,
StatIntervalInMs: rule.StatIntervalInMs,
LowMemUsageThreshold: rule.LowMemUsageThreshold,
HighMemUsageThreshold: rule.HighMemUsageThreshold,
MemLowWaterMarkBytes: rule.MemLowWaterMarkBytes,
MemHighWaterMarkBytes: rule.MemHighWaterMarkBytes,

Check warning on line 48 in plugins/plugins/sentinel/rules/flow.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/rules/flow.go#L33-L48

Added lines #L33 - L48 were not covered by tests
}
return flow.LoadRules(newRules)

Check warning on line 50 in plugins/plugins/sentinel/rules/flow.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/rules/flow.go#L50

Added line #L50 was not covered by tests
}
52 changes: 52 additions & 0 deletions plugins/plugins/sentinel/rules/hotspot.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright The HTNN Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// 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.

package rules

import (
types "mosn.io/htnn/types/plugins/sentinel"

"github.com/alibaba/sentinel-golang/core/hotspot"
)

func LoadHotSpotRule(rule *types.HotSpotRule) (bool, error) {
oldRules := hotspot.GetRules()
newRules := make([]*hotspot.Rule, 0, len(oldRules)+1)
i := 0
for _, r := range oldRules {
tmp := r
newRules[i] = &tmp
i++

Check warning on line 30 in plugins/plugins/sentinel/rules/hotspot.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/rules/hotspot.go#L23-L30

Added lines #L23 - L30 were not covered by tests
}

var specificItems map[interface{}]int64
for k, v := range rule.SpecificItems {
specificItems[k] = v

Check warning on line 35 in plugins/plugins/sentinel/rules/hotspot.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/rules/hotspot.go#L33-L35

Added lines #L33 - L35 were not covered by tests
}
newRules[i] = &hotspot.Rule{
ID: rule.Id,
Resource: rule.Resource,
MetricType: hotspot.MetricType(rule.MetricType),
ControlBehavior: hotspot.ControlBehavior(rule.ControlBehavior),
ParamIndex: int(rule.ParamIndex),
ParamKey: rule.ParamKey,
Threshold: rule.Threshold,
MaxQueueingTimeMs: rule.MaxQueueingTimeMs,
BurstCount: rule.BurstCount,
DurationInSec: rule.DurationInSec,
ParamsMaxCapacity: rule.ParamsMaxCapacity,
SpecificItems: specificItems,

Check warning on line 49 in plugins/plugins/sentinel/rules/hotspot.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/rules/hotspot.go#L37-L49

Added lines #L37 - L49 were not covered by tests
}
return hotspot.LoadRules(newRules)

Check warning on line 51 in plugins/plugins/sentinel/rules/hotspot.go

View check run for this annotation

Codecov / codecov/patch

plugins/plugins/sentinel/rules/hotspot.go#L51

Added line #L51 was not covered by tests
}
Loading

0 comments on commit 6b827cf

Please sign in to comment.