Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add NewWatcherWithConfig() #25

Merged
merged 4 commits into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,49 @@ func main() {
}
```

## Simple Example(Configuration Mode)

```go
package main

import (
"log"

casbin "github.com/casbin/casbin/v2"
etcdwatcher "github.com/casbin/etcd-watcher/v2"
)

func updateCallback(rev string) {
log.Println("New revision detected:", rev)
}

func main() {
// Initialize the watcher.
// Use the configuration file as the parameter
w, _ := etcdwatcher.NewWatcherWithConfig(etcdwatcher.WatcherConfig{
Hosts: []string{"http://127.0.0.1:2379"},
Key: "/casbin",
User: "root",
Pass: "123",
})

// Initialize the enforcer.
e, _ := casbin.NewEnforcer("examples/rbac_model.conf", "examples/rbac_policy.csv")

// Set the watcher for the enforcer.
e.SetWatcher(w)

// By default, the watcher's callback is automatically set to the
// enforcer's LoadPolicy() in the SetWatcher() call.
// We can change it by explicitly setting a callback.
w.SetUpdateCallback(updateCallback)

// Update the policy to test the effect.
// You should see "[New revision detected: X]" in the log.
e.SavePolicy()
}
```

## Getting Help

- [Casbin](https://github.com/casbin/casbin)
Expand Down
45 changes: 45 additions & 0 deletions watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ type Watcher struct {
keyName string
password string
lastSentRev int64
conf *WatcherConfig
}

type WatcherConfig struct {
Hosts []string
Key string `json:",default=casbin_watcher"`
User string
Pass string
DialKeepAliveTimeout time.Duration `json:",default=10"`
DialTimeout time.Duration `json:",default=30"`
}

// finalizer is the destructor for Watcher.
Expand Down Expand Up @@ -70,6 +80,30 @@ func NewWatcher(endpoints []string, keyName string, password ...string) (persist
return w, nil
}

// NewWatcherWithConfig is a configurable Watcher constructor
func NewWatcherWithConfig(config WatcherConfig) (persist.Watcher, error) {
w := &Watcher{}
w.running = true
w.callback = nil
w.keyName = config.Key
w.conf = &config

// Create the client.
err := w.createClient()
if err != nil {
return nil, err
}

// Call the destructor when the object is released.
runtime.SetFinalizer(w, finalizer)

go func() {
_ = w.startWatch()
}()

return w, nil
}

// Close closes the Watcher.
func (w *Watcher) Close() {
finalizer(w)
Expand All @@ -84,6 +118,17 @@ func (w *Watcher) createClient() error {
Password: w.password,
}

if w.conf != nil {
cfg = client.Config{
Endpoints: w.conf.Hosts,
// set timeout per request to fail fast when the target endpoints is unavailable
DialTimeout: time.Second * w.conf.DialTimeout,
DialKeepAliveTimeout: time.Second * w.conf.DialKeepAliveTimeout,
Username: w.conf.User,
Password: w.conf.Pass,
}
}

c, err := client.New(cfg)
if err != nil {
return err
Expand Down
12 changes: 12 additions & 0 deletions watcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ func TestWatcher(t *testing.T) {
// Use the endpoints of etcd cluster as parameter.
updater, _ := NewWatcher([]string{"http://127.0.0.1:2379"}, "/casbin")

withConfigUpdater, _ := NewWatcherWithConfig(WatcherConfig{
Hosts: []string{"http://127.0.0.1:2379"},
Key: "/casbin",
User: "",
Pass: "",
})

// listener represents any other Casbin enforcer instance that watches the change of policy in DB.
listener, _ := NewWatcher([]string{"http://127.0.0.1:2379"}, "/casbin")
// listener should set a callback that gets called when policy changes.
Expand All @@ -41,6 +48,11 @@ func TestWatcher(t *testing.T) {
panic(err)
}

err = withConfigUpdater.Update()
if err != nil {
panic(err)
}

// Now the listener's callback updateCallback() should be called,
// because it receives the notification of policy update.
// You should see "[New revision detected: X]" in the log.
Expand Down
Loading