AUTH-2587 add config watcher and reload logic for access client forwarder

This commit is contained in:
Dalton
2020-04-13 12:22:00 -05:00
parent 976eb24883
commit 41c358147c
32 changed files with 2929 additions and 8 deletions

58
watcher/file.go Normal file
View File

@@ -0,0 +1,58 @@
package watcher
import (
"github.com/fsnotify/fsnotify"
)
// File is a file watcher that notifies when a file has been changed
type File struct {
watcher *fsnotify.Watcher
shutdown chan struct{}
}
// NewFile is a standard constructor
func NewFile() (*File, error) {
watcher, err := fsnotify.NewWatcher()
if err != nil {
return nil, err
}
f := &File{
watcher: watcher,
shutdown: make(chan struct{}),
}
return f, nil
}
// Add adds a file to start watching
func (f *File) Add(filepath string) error {
return f.watcher.Add(filepath)
}
// Shutdown stop the file watching run loop
func (f *File) Shutdown() {
f.shutdown <- struct{}{}
}
// Start is a runloop to watch for files changes from the file paths added from Add()
func (f *File) Start(notifier Notification) {
for {
select {
case event, ok := <-f.watcher.Events:
if !ok {
return
}
if event.Op&fsnotify.Write == fsnotify.Write {
notifier.WatcherItemDidChange(event.Name)
}
case err, ok := <-f.watcher.Errors:
if !ok {
return
}
notifier.WatcherDidError(err)
case <-f.shutdown:
f.watcher.Close()
return
}
}
}

54
watcher/file_test.go Normal file
View File

@@ -0,0 +1,54 @@
package watcher
import (
"bufio"
"os"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
type mockNotifier struct {
eventPath string
}
func (n *mockNotifier) WatcherItemDidChange(path string) {
n.eventPath = path
}
func (n *mockNotifier) WatcherDidError(err error) {
}
func TestFileChanged(t *testing.T) {
filePath := "test_file"
f, err := os.Create(filePath)
assert.NoError(t, err)
defer func() {
f.Close()
os.Remove(filePath)
}()
service, err := NewFile()
assert.NoError(t, err)
err = service.Add(filePath)
assert.NoError(t, err)
n := &mockNotifier{}
go service.Start(n)
f.Sync()
w := bufio.NewWriter(f)
_, err = w.WriteString("hello Austin, do you like my file watcher?\n")
assert.NoError(t, err)
err = w.Flush()
assert.NoError(t, err)
// give it time to trigger
time.Sleep(10 * time.Millisecond)
service.Shutdown()
assert.Equal(t, filePath, n.eventPath, "notifier didn't get an new file write event")
}

14
watcher/notify.go Normal file
View File

@@ -0,0 +1,14 @@
package watcher
// Notification is the delegate methods from the Notifier
type Notification interface {
WatcherItemDidChange(string)
WatcherDidError(error)
}
// Notifier is the base interface for file watching
type Notifier interface {
Start(Notification)
Add(string) error
Shutdown()
}