feat(controller): enterprise version flow switch option

This commit is contained in:
leandrofars 2024-06-20 21:58:13 -03:00
parent e946468321
commit c4efccaa0a
7 changed files with 131 additions and 22 deletions

View File

@ -26,7 +26,7 @@ func main() {
db := db.NewDatabase(c.Mongo.Ctx, c.Mongo.Uri)
api := api.NewApi(c.RestApi, js, nc, bridge, db, kv)
api := api.NewApi(c, js, nc, bridge, db, kv)
api.StartApi()
<-done

View File

@ -17,13 +17,14 @@ import (
)
type Api struct {
port string
js jetstream.JetStream
nc *nats.Conn
bridge bridge.Bridge
db db.Database
kv jetstream.KeyValue
ctx context.Context
port string
js jetstream.JetStream
nc *nats.Conn
bridge bridge.Bridge
db db.Database
kv jetstream.KeyValue
ctx context.Context
enterpise bool
}
const REQUEST_TIMEOUT = time.Second * 30
@ -33,15 +34,16 @@ const (
AdminUser
)
func NewApi(c config.RestApi, js jetstream.JetStream, nc *nats.Conn, bridge bridge.Bridge, d db.Database, kv jetstream.KeyValue) Api {
func NewApi(c *config.Config, js jetstream.JetStream, nc *nats.Conn, bridge bridge.Bridge, d db.Database, kv jetstream.KeyValue) Api {
return Api{
port: c.Port,
js: js,
nc: nc,
ctx: c.Ctx,
bridge: bridge,
db: d,
kv: kv,
port: c.RestApi.Port,
js: js,
nc: nc,
ctx: c.RestApi.Ctx,
bridge: bridge,
db: d,
kv: kv,
enterpise: c.Enterprise,
}
}
@ -73,10 +75,8 @@ func (a *Api) StartApi() {
iot.HandleFunc("/{sn}/{mtp}/parameters", a.deviceGetSupportedParametersMsg).Methods("PUT")
iot.HandleFunc("/{sn}/{mtp}/instances", a.deviceGetParameterInstances).Methods("PUT")
iot.HandleFunc("/{sn}/{mtp}/operate", a.deviceOperateMsg).Methods("PUT")
iot.HandleFunc("/{sn}/{mtp}/fw_update", a.deviceFwUpdate).Methods("PUT")
iot.HandleFunc("/{sn}/{mtp}/fw_update", a.deviceFwUpdate).Methods("PUT") //TODO: put it to work and generalize for usp and cwmp
iot.HandleFunc("/{sn}/wifi", a.deviceWifi).Methods("PUT", "GET")
// mtp := r.PathPrefix("/api/mtp").Subrouter()
// mtp.HandleFunc("", a.mtpInfo).Methods("GET")
dash := r.PathPrefix("/api/info").Subrouter()
dash.HandleFunc("/vendors", a.vendorsInfo).Methods("GET")
dash.HandleFunc("/status", a.statusInfo).Methods("GET")

View File

@ -3,16 +3,20 @@ package api
import (
"encoding/json"
"encoding/xml"
"errors"
"io"
"net/http"
"github.com/leandrofars/oktopus/internal/bridge"
"github.com/leandrofars/oktopus/internal/cwmp"
"github.com/leandrofars/oktopus/internal/entity"
n "github.com/leandrofars/oktopus/internal/nats"
"github.com/leandrofars/oktopus/internal/utils"
"github.com/nats-io/nats.go"
)
var errDeviceModelNotFound = errors.New("device model not found")
func (a *Api) cwmpGetParameterNamesMsg(w http.ResponseWriter, r *http.Request) {
sn := getSerialNumberFromRequest(r)
@ -147,3 +151,17 @@ func cwmpInteraction[T cwmp.SetParameterValuesResponse | cwmp.DeleteObjectRespon
}
return data, response, err
}
func cwmpGetDeviceModel(device *entity.Device, w http.ResponseWriter) (string, error) {
var model string
if device.Model != "" {
model = device.Model
} else if device.ProductClass != "" {
model = device.ProductClass
} else {
w.WriteHeader(http.StatusInternalServerError)
w.Write(utils.Marshall("Couldn't get device model"))
return model, errDeviceModelNotFound
}
return model, nil
}

View File

@ -0,0 +1,24 @@
package api
import (
"net/http"
"github.com/leandrofars/oktopus/internal/bridge"
"github.com/leandrofars/oktopus/internal/entity"
)
func (a *Api) getEnterpriseResource(
resource string,
action string,
device *entity.Device,
sn string,
w http.ResponseWriter,
body []byte,
) error {
model, err := cwmpGetDeviceModel(device, w)
if err != nil {
return err
}
err = bridge.NatsEnterpriseInteraction("enterprise.v1.cwmp."+model+"."+sn+"."+resource+"."+action, body, w, a.nc)
return err
}

View File

@ -1,6 +1,7 @@
package api
import (
"io"
"log"
"net/http"
"strings"
@ -212,6 +213,11 @@ func (a *Api) deviceWifi(w http.ResponseWriter, r *http.Request) {
if device.Cwmp == entity.Online {
if a.enterpise {
a.getEnterpriseResource("wifi", "get", device, sn, w, []byte{})
return
}
var (
NUMBER_OF_WIFI_PARAMS_TO_GET = 5
)
@ -341,6 +347,17 @@ func (a *Api) deviceWifi(w http.ResponseWriter, r *http.Request) {
if device.Cwmp == entity.Online {
if a.enterpise {
payload, err := io.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write(utils.Marshall(err.Error()))
return
}
a.getEnterpriseResource("wifi", "set", device, sn, w, payload)
return
}
var body []WiFi
err := utils.MarshallDecoder(&body, r.Body)

View File

@ -246,3 +246,50 @@ func NatsCwmpInteraction(
return answer.Msg, nil
}
func NatsEnterpriseInteraction(
subj string,
body []byte,
w http.ResponseWriter,
nc *nats.Conn,
) error {
log.Println("Sending enterprise message")
log.Println("Subject: ", subj)
var answer entity.MsgAnswer[[]byte]
msg, err := nc.Request(subj, body, local.NATS_REQUEST_TIMEOUT)
if err != nil {
if err == nats.ErrNoResponders {
w.WriteHeader(http.StatusInternalServerError)
w.Write(utils.Marshall("You have no enterprise license, to get one contact: leandro@oktopus.app.br"))
return err
}
w.WriteHeader(http.StatusInternalServerError)
w.Write(utils.Marshall("Error to communicate with nats: " + err.Error()))
return err
}
err = json.Unmarshal(msg.Data, &answer)
if err != nil {
var errMsg *entity.MsgAnswer[*string]
err = json.Unmarshal(msg.Data, &errMsg)
if err != nil {
log.Println("Bad answer message formatting: ", err.Error())
w.WriteHeader(http.StatusInternalServerError)
w.Write(msg.Data)
return err
}
log.Printf("Error message received, msg: %s, code: %d", *errMsg.Msg, errMsg.Code)
w.WriteHeader(errMsg.Code)
w.Write(utils.Marshall(*errMsg.Msg))
return errNatsMsgReceivedWithErrorData
}
w.Write(answer.Msg)
return nil
}

View File

@ -30,9 +30,10 @@ type RestApi struct {
}
type Config struct {
RestApi RestApi
Nats Nats
Mongo Mongo
RestApi RestApi
Nats Nats
Mongo Mongo
Enterprise bool
}
func NewConfig() *Config {
@ -45,6 +46,7 @@ func NewConfig() *Config {
natsVerifyCertificates := flag.Bool("nats_verify_certificates", lookupEnvOrBool("NATS_VERIFY_CERTIFICATES", false), "verify validity of certificates from nats server")
flApiPort := flag.String("api_port", lookupEnvOrString("REST_API_PORT", "8000"), "Rest api port")
mongoUri := flag.String("mongo_uri", lookupEnvOrString("MONGO_URI", "mongodb://localhost:27017"), "uri for mongodb server")
enterpise := flag.Bool("enterprise", lookupEnvOrBool("ENTERPRISE", false), "enterprise version enable")
flHelp := flag.Bool("help", false, "Help")
/*
@ -78,6 +80,7 @@ func NewConfig() *Config {
Uri: *mongoUri,
Ctx: ctx,
},
Enterprise: *enterpise,
}
}