Newer
Older
package nucleus
import (
"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
"fmt"
"github.com/google/uuid"
gpb "github.com/openconfig/gnmi/proto/gnmi"
log "github.com/sirupsen/logrus"
"net/http"
"net/url"
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)
}
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in f", r)
}
}()
http.HandleFunc("/livez", healthCheck)
coreLock.Lock()
defer coreLock.Unlock()
httpOnce.Do(registerHttpHandler)
c.httpServer = &http.Server{Addr: ":8080"}
if err != nil {
return
}
}()
return nil
}
func healthCheck(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusOK)
}
func readynessCheck(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusOK)
}
func httpHandler(writer http.ResponseWriter, request *http.Request) {
log.WithFields(log.Fields{
"request": request,
}).Debug("incoming request")
query, err := url.ParseQuery(request.URL.RawQuery)
sid, err := uuid.Parse(query.Get("sbi"))
if err != nil {
log.Error(err)
}
var pnd PrincipalNetworkDomain
var sbi SouthboundInterface
if query.Get("q") != "init" && query.Get("q") != "getIDs" {
pnd, err = c.pndc.get(pid)
if err != nil {
log.Error(err)
writer.WriteHeader(http.StatusInternalServerError)
return
}
sbic := pnd.GetSBIs()
sbi, err = sbic.(*sbiStore).get(sid)
"available uuids": sbic.(*sbiStore).UUIDs(),
}).Error(err)
writer.WriteHeader(http.StatusInternalServerError)
return
}
switch query.Get("q") {
case "addDevice":
d, err := NewDevice(sbi, &GnmiTransportOptions{
Config: gnmi.Config{
Addr: query.Get("address"),
Password: query.Get("password"),
Username: query.Get("username"),
Encoding: gpb.Encoding_JSON_IETF,
},
SetNode: sbi.SetNode(),
Unmarshal: sbi.(*OpenConfig).Unmarshal(),
RespChan: make(chan *gpb.SubscribeResponse),
})
err = pnd.AddDevice(d)
writer.WriteHeader(http.StatusCreated)
fmt.Fprintf(writer, "device added\n")
fmt.Fprintf(writer, "UUID: %v\n", d.UUID)
case "request":
err = pnd.Request(id, query.Get("path"))
switch err.(type) {
case *ErrNotFound:
writer.WriteHeader(http.StatusNotFound)
default:
writer.WriteHeader(http.StatusInternalServerError)
}
writer.WriteHeader(http.StatusOK)
case "requestAll":
err = pnd.RequestAll(query.Get("path"))
if err != nil {
switch err.(type) {
case *ErrNotFound:
writer.WriteHeader(http.StatusNotFound)
default:
writer.WriteHeader(http.StatusInternalServerError)
log.Error(err)
return
}
writer.WriteHeader(http.StatusOK)
case "getDevice":
device, err := pnd.MarshalDevice(id)
if err != nil {
switch err.(type) {
case *ErrNotFound:
writer.WriteHeader(http.StatusNotFound)
default:
writer.WriteHeader(http.StatusInternalServerError)
}
writer.Header().Set("Content-Type", "application/json")
fmt.Fprintf(writer, "%v", device)
case "getIDs":
writeIDs := func(typ string, ids []uuid.UUID) {
fmt.Fprintf(writer, "%v:\n", typ)
for i, id := range ids {
fmt.Fprintf(writer, "%v: %v\n", i+1, id)
}
}
writeIDs("PNDs", c.pndc.UUIDs())
writeIDs("SBIs", c.sbic.UUIDs())
if pnd != nil {
writeIDs("Devices", pnd.(*pndImplementation).devices.UUIDs())
}
case "init":
writeIDs := func(typ string, ids []uuid.UUID) {
for _, id := range ids {
fmt.Fprintf(writer, "%v", id)
}
writeIDs("PNDs", c.pndc.UUIDs())
writeIDs("SBIs", c.sbic.UUIDs())
case "set":
resp, err := pnd.(*pndImplementation).Set(id, query.Get("path"), query.Get("value"))
writer.WriteHeader(http.StatusInternalServerError)
log.Error(err)
writer.WriteHeader(http.StatusOK)
fmt.Fprintln(writer, resp)
default:
writer.WriteHeader(http.StatusBadRequest)
}