From 3bc6fb3d336a88e1bb6a68b641fc1ee8136ba861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leandro=20Ant=C3=B4nio=20Farias=20Machado?= Date: Thu, 27 Apr 2023 00:16:04 -0300 Subject: [PATCH 1/5] feat: add/create + delete api #5 --- .../services/controller/internal/api/api.go | 138 +++++++++++++++--- .../controller/internal/utils/utils.go | 36 +++++ 2 files changed, 151 insertions(+), 23 deletions(-) diff --git a/backend/services/controller/internal/api/api.go b/backend/services/controller/internal/api/api.go index fc19bb0..ee89b3c 100644 --- a/backend/services/controller/internal/api/api.go +++ b/backend/services/controller/internal/api/api.go @@ -39,8 +39,10 @@ func StartApi(a Api) { r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { return }) - r.HandleFunc("/devices", a.retrieveDevices) - r.HandleFunc("/devices/{sn}/get", a.deviceGetMsg) + r.HandleFunc("/devices", a.retrieveDevices).Methods("GET") + r.HandleFunc("/device/{sn}/get", a.deviceGetMsg).Methods("PUT") + r.HandleFunc("/device/{sn}/add", a.deviceCreateMsg).Methods("PUT") + r.HandleFunc("/device/{sn}/del", a.deviceDeleteMsg).Methods("PUT") srv := &http.Server{ Addr: "0.0.0.0:" + a.Port, @@ -74,34 +76,21 @@ func (a *Api) retrieveDevices(w http.ResponseWriter, r *http.Request) { return } -func (a *Api) deviceGetMsg(w http.ResponseWriter, r *http.Request) { +func (a *Api) deviceCreateMsg(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) sn := vars["sn"] - _, err := a.Db.RetrieveDevice(sn) - if err != nil { - if err == mongo.ErrNoDocuments { - w.WriteHeader(http.StatusBadRequest) - json.NewEncoder(w).Encode("No device with serial number " + sn + " was found") - return - } - w.WriteHeader(http.StatusInternalServerError) - return - } - var receiver usp_msg.Get - //data := []byte(`{"param_paths": {'Device.DeviceInfo.'},"max_depth": 2}`) - //data := []byte("'opa'") - //var jsonBlob = []byte(`{ - // "param_paths": ["Device.DeviceInfo.","Device.ManagementServer."], - // "max_depth": 2 - //}`) - err = json.NewDecoder(r.Body).Decode(receiver) + a.deviceExists(sn, w) + + var receiver usp_msg.Add + + err := json.NewDecoder(r.Body).Decode(&receiver) if err != nil { log.Println(err) w.WriteHeader(http.StatusBadRequest) return } - msg := utils.NewGetMsg(receiver) + msg := utils.NewCreateMsg(receiver) encodedMsg, err := proto.Marshal(&msg) if err != nil { log.Println(err) @@ -122,7 +111,7 @@ func (a *Api) deviceGetMsg(w http.ResponseWriter, r *http.Request) { select { case msg := <-a.MsgQueue[msg.Header.MsgId]: log.Printf("Received Msg") - json.NewEncoder(w).Encode(msg) + json.NewEncoder(w).Encode(msg.Body.GetResponse().GetAddResp()) return case <-time.After(time.Second * 5): log.Printf("Request Timed Out") @@ -131,3 +120,106 @@ func (a *Api) deviceGetMsg(w http.ResponseWriter, r *http.Request) { return } } + +func (a *Api) deviceGetMsg(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + sn := vars["sn"] + + a.deviceExists(sn, w) + + var receiver usp_msg.Get + + err := json.NewDecoder(r.Body).Decode(&receiver) + if err != nil { + log.Println(err) + w.WriteHeader(http.StatusBadRequest) + return + } + + msg := utils.NewGetMsg(receiver) + encodedMsg, err := proto.Marshal(&msg) + if err != nil { + log.Println(err) + w.WriteHeader(http.StatusBadRequest) + return + } + + record := utils.NewUspRecord(encodedMsg, sn) + tr369Message, err := proto.Marshal(&record) + if err != nil { + log.Fatalln("Failed to encode tr369 record:", err) + } + + a.MsgQueue[msg.Header.MsgId] = make(chan usp_msg.Msg) + a.Broker.Publish(tr369Message, "oktopus/v1/agent/"+sn, "oktopus/v1/api/"+sn) + + select { + case msg := <-a.MsgQueue[msg.Header.MsgId]: + log.Printf("Received Msg") + json.NewEncoder(w).Encode(msg.Body.GetResponse().GetGetResp()) + return + case <-time.After(time.Second * 5): + log.Printf("Request Timed Out") + w.WriteHeader(http.StatusGatewayTimeout) + json.NewEncoder(w).Encode("Request Timed Out") + return + } +} + +func (a *Api) deviceDeleteMsg(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + sn := vars["sn"] + a.deviceExists(sn, w) + + var receiver usp_msg.Delete + + err := json.NewDecoder(r.Body).Decode(&receiver) + if err != nil { + log.Println(err) + w.WriteHeader(http.StatusBadRequest) + return + } + + msg := utils.NewDelMsg(receiver) + encodedMsg, err := proto.Marshal(&msg) + if err != nil { + log.Println(err) + w.WriteHeader(http.StatusBadRequest) + return + } + + record := utils.NewUspRecord(encodedMsg, sn) + tr369Message, err := proto.Marshal(&record) + if err != nil { + log.Fatalln("Failed to encode tr369 record:", err) + } + + //a.Broker.Request(tr369Message, usp_msg.Header_GET, "oktopus/v1/agent/"+sn, "oktopus/v1/get/"+sn) + a.MsgQueue[msg.Header.MsgId] = make(chan usp_msg.Msg) + a.Broker.Publish(tr369Message, "oktopus/v1/agent/"+sn, "oktopus/v1/api/"+sn) + + select { + case msg := <-a.MsgQueue[msg.Header.MsgId]: + log.Printf("Received Msg") + json.NewEncoder(w).Encode(msg.Body.GetResponse().GetDeleteResp()) + return + case <-time.After(time.Second * 5): + log.Printf("Request Timed Out") + w.WriteHeader(http.StatusGatewayTimeout) + json.NewEncoder(w).Encode("Request Timed Out") + return + } +} + +func (a *Api) deviceExists(sn string, w http.ResponseWriter) { + _, err := a.Db.RetrieveDevice(sn) + if err != nil { + if err == mongo.ErrNoDocuments { + w.WriteHeader(http.StatusBadRequest) + json.NewEncoder(w).Encode("No device with serial number " + sn + " was found") + return + } + w.WriteHeader(http.StatusInternalServerError) + return + } +} diff --git a/backend/services/controller/internal/utils/utils.go b/backend/services/controller/internal/utils/utils.go index c636c4b..4609161 100644 --- a/backend/services/controller/internal/utils/utils.go +++ b/backend/services/controller/internal/utils/utils.go @@ -44,6 +44,24 @@ func NewUspRecord(p []byte, toId string) usp_record.Record { } } +func NewCreateMsg(createStuff usp_msg.Add) usp_msg.Msg { + return usp_msg.Msg{ + Header: &usp_msg.Header{ + MsgId: uuid.NewString(), + MsgType: usp_msg.Header_ADD, + }, + Body: &usp_msg.Body{ + MsgBody: &usp_msg.Body_Request{ + Request: &usp_msg.Request{ + ReqType: &usp_msg.Request_Add{ + Add: &createStuff, + }, + }, + }, + }, + } +} + func NewGetMsg(getStuff usp_msg.Get) usp_msg.Msg { return usp_msg.Msg{ Header: &usp_msg.Header{ @@ -61,3 +79,21 @@ func NewGetMsg(getStuff usp_msg.Get) usp_msg.Msg { }, } } + +func NewDelMsg(getStuff usp_msg.Delete) usp_msg.Msg { + return usp_msg.Msg{ + Header: &usp_msg.Header{ + MsgId: uuid.NewString(), + MsgType: usp_msg.Header_DELETE, + }, + Body: &usp_msg.Body{ + MsgBody: &usp_msg.Body_Request{ + Request: &usp_msg.Request{ + ReqType: &usp_msg.Request_Delete{ + Delete: &getStuff, + }, + }, + }, + }, + } +} From 679b04bb34a00aeb7f6a140eb22260ff539438fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leandro=20Ant=C3=B4nio=20Farias=20Machado?= Date: Thu, 27 Apr 2023 00:48:50 -0300 Subject: [PATCH 2/5] feat : api documentation close #33 --- README.en.md | 14 ++++++++++++++ README.es.md | 14 ++++++++++++++ README.md | 14 ++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/README.en.md b/README.en.md index 2e73307..9fd2204 100644 --- a/README.en.md +++ b/README.en.md @@ -16,5 +16,19 @@ This solution is inspired by the project Documentation + +
  • + Testing and development workspace +
  • + + + +
    If you are interested in internal information about the team and our intentions, visit our Wiki. diff --git a/README.es.md b/README.es.md index c61075a..44c722d 100644 --- a/README.es.md +++ b/README.es.md @@ -16,6 +16,20 @@ Esta solución se inspira en el proyecto. Documentación + +
  • + Espacio de trabajo de pruebas y desarrollo +
  • + + + +
    Si está interesado en información interna sobre el equipo y nuestras intenciones, visite nuestro Wiki. diff --git a/README.md b/README.md index 21a2558..4cc398d 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,20 @@ Esta solução tem como inspirações o projeto Documentação + +
  • + Workspace de testes e desenvolvimento +
  • + + + +
    Caso você tenha interesse em informações internas sobre o time e nossas pretensões acesse nossa Wiki. From 4c916bdab95c1ed63f0cb9fbbaf24872a468de26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leandro=20Ant=C3=B4nio=20Farias=20Machado?= Date: Fri, 28 Apr 2023 08:17:10 -0300 Subject: [PATCH 3/5] feat: api tr369 SET function for device #5 --- .../services/controller/internal/api/api.go | 48 ++++++++++++++++++- .../controller/internal/utils/utils.go | 18 +++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/backend/services/controller/internal/api/api.go b/backend/services/controller/internal/api/api.go index ee89b3c..dcecc77 100644 --- a/backend/services/controller/internal/api/api.go +++ b/backend/services/controller/internal/api/api.go @@ -43,6 +43,7 @@ func StartApi(a Api) { r.HandleFunc("/device/{sn}/get", a.deviceGetMsg).Methods("PUT") r.HandleFunc("/device/{sn}/add", a.deviceCreateMsg).Methods("PUT") r.HandleFunc("/device/{sn}/del", a.deviceDeleteMsg).Methods("PUT") + r.HandleFunc("/device/{sn}/set", a.deviceUpdateMsg).Methods("PUT") srv := &http.Server{ Addr: "0.0.0.0:" + a.Port, @@ -83,7 +84,7 @@ func (a *Api) deviceCreateMsg(w http.ResponseWriter, r *http.Request) { var receiver usp_msg.Add - err := json.NewDecoder(r.Body).Decode(&receiver) + err := json.NewDecoder(r.Body).Decode(receiver) if err != nil { log.Println(err) w.WriteHeader(http.StatusBadRequest) @@ -211,6 +212,51 @@ func (a *Api) deviceDeleteMsg(w http.ResponseWriter, r *http.Request) { } } +func (a *Api) deviceUpdateMsg(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + sn := vars["sn"] + a.deviceExists(sn, w) + + var receiver usp_msg.Set + + err := json.NewDecoder(r.Body).Decode(&receiver) + if err != nil { + log.Println(err) + w.WriteHeader(http.StatusBadRequest) + return + } + + msg := utils.NewSetMsg(receiver) + encodedMsg, err := proto.Marshal(&msg) + if err != nil { + log.Println(err) + w.WriteHeader(http.StatusBadRequest) + return + } + + record := utils.NewUspRecord(encodedMsg, sn) + tr369Message, err := proto.Marshal(&record) + if err != nil { + log.Fatalln("Failed to encode tr369 record:", err) + } + + //a.Broker.Request(tr369Message, usp_msg.Header_GET, "oktopus/v1/agent/"+sn, "oktopus/v1/get/"+sn) + a.MsgQueue[msg.Header.MsgId] = make(chan usp_msg.Msg) + a.Broker.Publish(tr369Message, "oktopus/v1/agent/"+sn, "oktopus/v1/api/"+sn) + + select { + case msg := <-a.MsgQueue[msg.Header.MsgId]: + log.Printf("Received Msg") + json.NewEncoder(w).Encode(msg.Body.GetResponse().GetSetResp()) + return + case <-time.After(time.Second * 5): + log.Printf("Request Timed Out") + w.WriteHeader(http.StatusGatewayTimeout) + json.NewEncoder(w).Encode("Request Timed Out") + return + } +} + func (a *Api) deviceExists(sn string, w http.ResponseWriter) { _, err := a.Db.RetrieveDevice(sn) if err != nil { diff --git a/backend/services/controller/internal/utils/utils.go b/backend/services/controller/internal/utils/utils.go index 4609161..b40be73 100644 --- a/backend/services/controller/internal/utils/utils.go +++ b/backend/services/controller/internal/utils/utils.go @@ -97,3 +97,21 @@ func NewDelMsg(getStuff usp_msg.Delete) usp_msg.Msg { }, } } + +func NewSetMsg(updateStuff usp_msg.Set) usp_msg.Msg { + return usp_msg.Msg{ + Header: &usp_msg.Header{ + MsgId: uuid.NewString(), + MsgType: usp_msg.Header_SET, + }, + Body: &usp_msg.Body{ + MsgBody: &usp_msg.Body_Request{ + Request: &usp_msg.Request{ + ReqType: &usp_msg.Request_Set{ + Set: &updateStuff, + }, + }, + }, + }, + } +} From 2600c1debb741faafcfadf382c33058c623550dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leandro=20Ant=C3=B4nio=20Farias=20Machado?= Date: Fri, 28 Apr 2023 08:32:23 -0300 Subject: [PATCH 4/5] feat: api middleware + header content-type as json #5 --- backend/services/controller/internal/api/api.go | 5 +++++ .../controller/internal/api/middleware/middleware.go | 12 ++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 backend/services/controller/internal/api/middleware/middleware.go diff --git a/backend/services/controller/internal/api/api.go b/backend/services/controller/internal/api/api.go index dcecc77..5d4635d 100644 --- a/backend/services/controller/internal/api/api.go +++ b/backend/services/controller/internal/api/api.go @@ -3,6 +3,7 @@ package api import ( "encoding/json" "github.com/gorilla/mux" + "github.com/leandrofars/oktopus/internal/api/middleware" "github.com/leandrofars/oktopus/internal/db" "github.com/leandrofars/oktopus/internal/mtp" usp_msg "github.com/leandrofars/oktopus/internal/usp_message" @@ -45,6 +46,10 @@ func StartApi(a Api) { r.HandleFunc("/device/{sn}/del", a.deviceDeleteMsg).Methods("PUT") r.HandleFunc("/device/{sn}/set", a.deviceUpdateMsg).Methods("PUT") + r.Use(func(handler http.Handler) http.Handler { + return middleware.Middleware(handler) + }) + srv := &http.Server{ Addr: "0.0.0.0:" + a.Port, // Good practice to set timeouts to avoid Slowloris attacks. diff --git a/backend/services/controller/internal/api/middleware/middleware.go b/backend/services/controller/internal/api/middleware/middleware.go new file mode 100644 index 0000000..97edbe4 --- /dev/null +++ b/backend/services/controller/internal/api/middleware/middleware.go @@ -0,0 +1,12 @@ +package middleware + +import "net/http" + +func Middleware(next http.Handler) http.Handler { + return http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + next.ServeHTTP(w, r) + }, + ) +} From f7833e9dd030f055897f6faa6a8d0aa0ea17b715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leandro=20Ant=C3=B4nio=20Farias=20Machado?= Date: Fri, 28 Apr 2023 08:40:55 -0300 Subject: [PATCH 5/5] feat(api): add request id in log --- backend/services/controller/internal/api/api.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/backend/services/controller/internal/api/api.go b/backend/services/controller/internal/api/api.go index 5d4635d..14f9d7f 100644 --- a/backend/services/controller/internal/api/api.go +++ b/backend/services/controller/internal/api/api.go @@ -116,11 +116,11 @@ func (a *Api) deviceCreateMsg(w http.ResponseWriter, r *http.Request) { select { case msg := <-a.MsgQueue[msg.Header.MsgId]: - log.Printf("Received Msg") + log.Printf("Received Msg: %s", msg.Header.MsgId) json.NewEncoder(w).Encode(msg.Body.GetResponse().GetAddResp()) return case <-time.After(time.Second * 5): - log.Printf("Request Timed Out") + log.Printf("Request %s Timed Out", msg.Header.MsgId) w.WriteHeader(http.StatusGatewayTimeout) json.NewEncoder(w).Encode("Request Timed Out") return @@ -161,11 +161,11 @@ func (a *Api) deviceGetMsg(w http.ResponseWriter, r *http.Request) { select { case msg := <-a.MsgQueue[msg.Header.MsgId]: - log.Printf("Received Msg") + log.Printf("Received Msg: %s", msg.Header.MsgId) json.NewEncoder(w).Encode(msg.Body.GetResponse().GetGetResp()) return case <-time.After(time.Second * 5): - log.Printf("Request Timed Out") + log.Printf("Request %s Timed Out", msg.Header.MsgId) w.WriteHeader(http.StatusGatewayTimeout) json.NewEncoder(w).Encode("Request Timed Out") return @@ -206,11 +206,11 @@ func (a *Api) deviceDeleteMsg(w http.ResponseWriter, r *http.Request) { select { case msg := <-a.MsgQueue[msg.Header.MsgId]: - log.Printf("Received Msg") + log.Printf("Received Msg: %s", msg.Header.MsgId) json.NewEncoder(w).Encode(msg.Body.GetResponse().GetDeleteResp()) return case <-time.After(time.Second * 5): - log.Printf("Request Timed Out") + log.Printf("Request %s Timed Out", msg.Header.MsgId) w.WriteHeader(http.StatusGatewayTimeout) json.NewEncoder(w).Encode("Request Timed Out") return @@ -251,11 +251,11 @@ func (a *Api) deviceUpdateMsg(w http.ResponseWriter, r *http.Request) { select { case msg := <-a.MsgQueue[msg.Header.MsgId]: - log.Printf("Received Msg") + log.Printf("Received Msg: %s", msg.Header.MsgId) json.NewEncoder(w).Encode(msg.Body.GetResponse().GetSetResp()) return case <-time.After(time.Second * 5): - log.Printf("Request Timed Out") + log.Printf("Request %s Timed Out", msg.Header.MsgId) w.WriteHeader(http.StatusGatewayTimeout) json.NewEncoder(w).Encode("Request Timed Out") return