diff --git a/nucleus/controller.go b/nucleus/controller.go index 50ae2e12872de103bf24a6ef66889235cfec6e02..ac94a076a682483e6d3a6c8278eb9d53c1706a8e 100644 --- a/nucleus/controller.go +++ b/nucleus/controller.go @@ -5,6 +5,9 @@ import ( "context" "github.com/google/uuid" log "github.com/sirupsen/logrus" + "net/http" + "os" + "os/signal" "time" ) @@ -13,19 +16,28 @@ type Core struct { // deprecated database database.Database - pndc pndStore - sbic sbiStore + pndc pndStore + sbic sbiStore + httpServer *http.Server + stopChan chan os.Signal } var c *Core -//Initialize does start-up housekeeping like reading controller config files -func initialize() error { +func init() { c = &Core{ - database: database.Database{}, - pndc: pndStore{}, - sbic: sbiStore{}, + database: database.Database{}, + pndc: pndStore{}, + sbic: sbiStore{}, + stopChan: make(chan os.Signal, 1), } + + // Setting up signal capturing + signal.Notify(c.stopChan, os.Interrupt) +} + +// initialize does start-up housekeeping like reading controller config files +func initialize() error { c.sbic = sbiStore{ store{}, } @@ -83,10 +95,17 @@ func Run(ctx context.Context) error { log.WithFields(log.Fields{}).Info("initialisation finished") for { select { + case <-c.stopChan: + return shutdown() case <-ctx.Done(): - return nil + return shutdown() case <-time.Tick(time.Minute): log.Debug("up and running") } } } + +func shutdown()error{ + log.Info("shutting down controller") + return stopHttpServer() +} \ No newline at end of file diff --git a/nucleus/controller_test.go b/nucleus/controller_test.go index 0fa4ffa903a1f894325aaf5211341e19a2df754a..8b59316492b90f54093c586d75eb800320dc68ef 100644 --- a/nucleus/controller_test.go +++ b/nucleus/controller_test.go @@ -1 +1,52 @@ package nucleus + +import ( + "context" + "net/http" + "testing" + "time" +) + +func TestRun(t *testing.T) { + type args struct { + request string + } + tests := []struct { + name string + args args + want interface{} + wantErr bool + }{ + { + name: "liveliness indicator", + args: args{request: apiEndpoint + "/livez"}, + want: &http.Response{StatusCode: http.StatusOK}, + wantErr: false, + }, + { + name: "readyness indicator", + args: args{request: apiEndpoint + "/readyz"}, + want: &http.Response{StatusCode: http.StatusOK}, + wantErr: false, + }, + { + name: "init", + args: args{request: apiEndpoint + "/api?q=init"}, + want: &http.Response{StatusCode: http.StatusOK}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + go func() { + if err := Run(ctx); (err != nil) != tt.wantErr { + t.Errorf("Run() error = %v, wantErr %v", err, tt.wantErr) + } + }() + time.Sleep(time.Second) + cancel() + time.Sleep(time.Second) + }) + } +} diff --git a/nucleus/http.go b/nucleus/http.go index 12610d9eea4e011285efecc8a5e9563020937e01..e54857066940079c211c837907bcedd99db611da 100644 --- a/nucleus/http.go +++ b/nucleus/http.go @@ -2,22 +2,41 @@ package nucleus import ( "code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi" + "context" "fmt" "github.com/google/uuid" gpb "github.com/openconfig/gnmi/proto/gnmi" log "github.com/sirupsen/logrus" "net/http" "net/url" + "time" ) -// deprecated -func httpApi() (err error) { +func stopHttpServer() error { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + log.Info("shutting down http server") + return c.httpServer.Shutdown(ctx) +} + +func registerHttpHandler(){ + defer func() { + if r := recover(); r != nil { + fmt.Println("Recovered in f", r) + } + }() http.HandleFunc("/api", httpHandler) http.HandleFunc("/livez", healthCheck) http.HandleFunc("/readyz", readynessCheck) +} + +// deprecated +func httpApi() (err error) { + registerHttpHandler() + c.httpServer = &http.Server{Addr: ":8080"} go func() { - err = http.ListenAndServe(":8080", nil) + err = c.httpServer.ListenAndServe() if err != nil { return }