From 21103825d03e99767f0a109a66d59f4f6338226d Mon Sep 17 00:00:00 2001 From: Godopu Date: Mon, 13 Dec 2021 14:16:05 +0900 Subject: [PATCH] commit 2021-12-13]14:16:02 --- config.properties | 3 + devicemanager/discovery.go | 33 +++++++++- devicemanager/handler.go | 81 ++++++++++++++++++++++++ devicemanager/manager.go | 45 ++++++++++++-- devicemanager/operation.go | 122 +++++++++++++++++++++++++++++++++++++ devicemanager/registry.go | 67 -------------------- dump.db | Bin 0 -> 16384 bytes go.mod | 4 ++ go.sum | 8 +++ main.go | 32 ++++++++++ model/cache.go | 43 ++++++++++--- model/device.go | 13 +++- model/handler.go | 12 +++- model/interface.go | 5 +- router/route.go | 2 +- 15 files changed, 383 insertions(+), 87 deletions(-) create mode 100644 config.properties create mode 100644 devicemanager/handler.go create mode 100644 devicemanager/operation.go delete mode 100644 devicemanager/registry.go create mode 100644 dump.db diff --git a/config.properties b/config.properties new file mode 100644 index 0000000..ea9aa64 --- /dev/null +++ b/config.properties @@ -0,0 +1,3 @@ +serverAddr = localhost:3000 +cname = controller-A +cid = 6aea5633-cdf9-45ed-9ecd-4c9fc7b98aab diff --git a/devicemanager/discovery.go b/devicemanager/discovery.go index 2df0de7..29f1651 100644 --- a/devicemanager/discovery.go +++ b/devicemanager/discovery.go @@ -3,8 +3,11 @@ package devicemanager import ( "context" "encoding/json" + "fmt" "log" "net/http" + + manager "git.godopu.net/lab/etri-smartfarm-poc-controller-serial" ) func PostDevice(w http.ResponseWriter, r *http.Request) { @@ -23,7 +26,7 @@ func PostDevice(w http.ResponseWriter, r *http.Request) { // 탐색 이벤트를 처리 큐에 입력 respCh := make(chan []byte) - ctx := context.WithValue(context.Background(), managerKey(parameterKey), ¶meter) + ctx := context.WithValue(context.Background(), managerKey(parameterKey), parameter) ctx = context.WithValue(ctx, managerKey(waitResponseKey), respCh) ctx, cancel := context.WithCancel(ctx) defer cancel() @@ -39,3 +42,31 @@ func PostDevice(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotAcceptable) } } + +func RegisterHandler(e manager.Event) { + param := e.Params() + payload := map[string]interface{}{} + payload["dname"] = param["uuid"] + payload["type"] = "device" + payload["sname"] = param["sname"] + + // b, err := json.Marshal(payload) + // if err != nil { + // log.Println(err) + // return + // } + // resp, err := http.Post("http://localhost:4000/devices", "application/json", bytes.NewReader(b)) + // if err != nil { + // log.Println(err) + // return + // } + + respCh := make(chan []byte) + ctx := context.WithValue(context.Background(), managerKey(parameterKey), payload) + ctx = context.WithValue(ctx, managerKey(waitResponseKey), respCh) + ctx, cancel := context.WithCancel(ctx) + defer cancel() + taskQueue <- &task{Event: DISCOVERY, Ctx: ctx} + + fmt.Println(string(<-respCh)) +} diff --git a/devicemanager/handler.go b/devicemanager/handler.go new file mode 100644 index 0000000..1c3400d --- /dev/null +++ b/devicemanager/handler.go @@ -0,0 +1,81 @@ +package devicemanager + +import ( + "context" + "encoding/json" + "etrismartfarmpoccontroller/model" + "fmt" + "log" + + manager "git.godopu.net/lab/etri-smartfarm-poc-controller-serial" +) + +func NewRecvHandler() manager.EventHandler { + return manager.NewEventHandler(func(e manager.Event) { + fmt.Println("RECV: ", e.Params()) + parmas := e.Params() + payload := map[string]interface{}{} + + var ok bool + payload["uuid"], ok = parmas["uuid"] + if !ok { + return + } + + db, err := model.GetDBHandler("sqlite", "./dump.db") + if err != nil { + return + } + + device, err := db.GetDeviceID(payload["uuid"].(string)) + if err != nil { + log.Println(err) + return + } + + device.DName = payload["uuid"].(string) + device.SID, err = db.GetSID(device.SName) + if err != nil { + log.Println(err) + return + } + + parameter := map[string]interface{}{ + "params": parmas, + "device": device, + } + respCh := make(chan []byte) + ctx := context.WithValue(context.Background(), managerKey(parameterKey), parameter) + ctx = context.WithValue(ctx, managerKey(waitResponseKey), respCh) + taskQueue <- &task{Event: STATUSREPORT, Ctx: ctx} + + resp := map[string]interface{}{} + b := <-respCh + err = json.Unmarshal(b, &resp) + + if err != nil { + fmt.Println(string(b)) + } else { + + changed := db.StatusCheck(device.DID, resp) + + if changed { + fmt.Println("change property: ", resp) + manager.Sync(device.DName, resp) + } + } + // ctx, cancel := context.WithCancel(ctx) + }) +} + +func RemovedHandler(e manager.Event) { + param := e.Params() + payload := map[string]interface{}{} + payload["dname"] = param["uuid"] + respCh := make(chan []byte) + ctx := context.WithValue(context.Background(), managerKey(parameterKey), payload) + ctx = context.WithValue(ctx, managerKey(waitResponseKey), respCh) + taskQueue <- &task{Event: DISCONNECTED, Ctx: ctx} + + fmt.Println(string(<-respCh)) +} diff --git a/devicemanager/manager.go b/devicemanager/manager.go index 08347e4..594abb6 100644 --- a/devicemanager/manager.go +++ b/devicemanager/manager.go @@ -2,6 +2,7 @@ package devicemanager import ( "context" + "etrismartfarmpoccontroller/model" ) type task struct { @@ -15,6 +16,8 @@ type managerKey int const ( DISCOVERY int = iota + DISCONNECTED + STATUSREPORT ) const ( @@ -41,17 +44,47 @@ func run(ctx context.Context) { switch t.Event { case DISCOVERY: p := t.Ctx.Value(managerKey(parameterKey)) - b, err := RegisterDevice(p.(*map[string]interface{}), t.Ctx.Done()) - + b, err := RegisterDevice(p.(map[string]interface{}), t.Ctx.Done()) if err != nil { continue } - respCh := t.Ctx.Value(managerKey(waitResponseKey)).(chan []byte) - if respCh != nil { - // , _ := json.Marshal(map[string]interface{}{"hello": "World"}) - respCh <- b + respCh, ok := t.Ctx.Value(managerKey(waitResponseKey)).(chan []byte) + if !ok { + return } + respCh <- b + + case DISCONNECTED: + p := t.Ctx.Value(managerKey(parameterKey)) + b, err := DeleteDevice(p.(map[string]interface{})) + if err != nil { + continue + } + + respCh, ok := t.Ctx.Value(managerKey(waitResponseKey)).(chan []byte) + if !ok { + return + } + respCh <- b + // p := t.Ctx.Value(managerKey(parameterKey)) + + case STATUSREPORT: + p := t.Ctx.Value(managerKey(parameterKey)) + params, _ := p.(map[string]interface{})["params"].(map[string]interface{}) + device, _ := p.(map[string]interface{})["device"].(*model.Device) + + respCh, ok := t.Ctx.Value(managerKey(waitResponseKey)).(chan []byte) + if !ok { + return + } + + b, err := ForwardMessage(device.DID, device.SID, params) + if err != nil { + respCh <- []byte(err.Error()) + } + + respCh <- b } } } diff --git a/devicemanager/operation.go b/devicemanager/operation.go new file mode 100644 index 0000000..4a2d9f5 --- /dev/null +++ b/devicemanager/operation.go @@ -0,0 +1,122 @@ +package devicemanager + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "etrismartfarmpoccontroller/constants" + "etrismartfarmpoccontroller/model" + "io/ioutil" + "net/http" +) + +func RegisterDevice(payload map[string]interface{}, cancelCh <-chan struct{}) ([]byte, error) { + payload["cid"] = constants.Config["cid"] + b, err := json.Marshal(payload) + if err != nil { + return nil, err + } + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + req, err := http.NewRequestWithContext( + ctx, + "POST", + "http://"+constants.Config["serverAddr"]+"/devices", + bytes.NewReader(b), + ) + req.Header.Set("Content-Type", "application/json") + var resp *http.Response + done := make(chan bool) + go func() { + resp, err = http.DefaultClient.Do(req) + if resp == nil { + return + } + done <- true + }() + + select { + case <-done: + if err != nil { + return nil, err + } + case <-cancelCh: + return nil, errors.New("cancel error") + } + + b, err = ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + if resp.StatusCode == http.StatusCreated { + db, err := model.GetDBHandler("sqlite", "./dump.db") + if err != nil { + return nil, err + } + + var device model.Device + json.Unmarshal(b, &device) + err = db.AddDevice(&device) + if err != nil { + return nil, err + } + } + + // db := model.GetDBHandler("sqlite", "./dump.db") + return b, nil +} + +func DeleteDevice(payload map[string]interface{}) ([]byte, error) { + payload["cid"] = constants.Config["cid"] + b, err := json.Marshal(payload) + if err != nil { + return nil, err + } + + req, err := http.NewRequest( + "DELETE", + "http://"+constants.Config["serverAddr"]+"/devices", + bytes.NewReader(b), + ) + if err != nil { + return nil, err + } + + req.Header.Set("Content-Type", "application/json") + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + + b, err = ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + return b, nil +} + +func ForwardMessage(did, sid string, payload map[string]interface{}) ([]byte, error) { + + b, err := json.Marshal(payload) + if err != nil { + return nil, err + } + req, err := http.NewRequest("PUT", "http://localhost:3000/services/"+sid+"/"+did, bytes.NewBuffer(b)) + if err != nil { + return nil, err + } + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + + b, err = ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return b, nil +} diff --git a/devicemanager/registry.go b/devicemanager/registry.go deleted file mode 100644 index 2f6309d..0000000 --- a/devicemanager/registry.go +++ /dev/null @@ -1,67 +0,0 @@ -package devicemanager - -import ( - "bytes" - "context" - "encoding/json" - "errors" - "etrismartfarmpoccontroller/constants" - "etrismartfarmpoccontroller/model" - "io/ioutil" - "net/http" -) - -func RegisterDevice(payload *map[string]interface{}, cancelCh <-chan struct{}) ([]byte, error) { - (*payload)["cid"] = constants.Config["cid"] - b, err := json.Marshal(payload) - if err != nil { - return nil, err - } - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - req, err := http.NewRequestWithContext( - ctx, - "POST", - "http://"+constants.Config["serverAddr"]+"/devices", - bytes.NewReader(b), - ) - req.Header.Set("Content-Type", "application/json") - var resp *http.Response - done := make(chan bool) - go func() { - resp, err = http.DefaultClient.Do(req) - if resp == nil { - return - } - done <- true - }() - - select { - case <-done: - if err != nil { - return nil, err - } - case <-cancelCh: - return nil, errors.New("cancel error") - } - - b, err = ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - - db, err := model.GetDBHandler("sqlite", "./dump.db") - if err != nil { - return nil, err - } - - var device model.Device - json.Unmarshal(b, &device) - err = db.AddDevice(&device) - if err != nil { - return nil, err - } - // db := model.GetDBHandler("sqlite", "./dump.db") - return b, nil -} diff --git a/dump.db b/dump.db new file mode 100644 index 0000000000000000000000000000000000000000..6971ecdedb5a83bcdc253c857a8126753dc4dbb6 GIT binary patch literal 16384 zcmeI$!EVzq7yw|WnKq573%3dF5>8viTseu;Bt6k>IaG{6*99>NvDmSLg4S+o0~*H) zY2s~o2F|hzjhyil zSxi_|m15q**7ja_ouRp@HWHgzKbLRhU@J}rl1+9Un?kkntS7hPcW2}F*rME9+FL1B zjOWYcdA=2kKI_TpOa9^PS39|m8J3!*@aG5Zr>%n{^GSF#NwHSDI-6I&A|qV=q$(&N z00JNY0w4eaAOHd&00JNY0=Hja)YMl{w~L~U2T`?V6WhX;jV;HtoF?^}c2EyI&$fNb z@*k0)Nyr=_#0wh2BNAHywJ~)QhJC^tn7PDd-1VqS{N3jPc14y2tuVoss#dS^0hPZqst=gb<(7fY6!A&kFIV z2vXrDn7ho!R9Y$K!tpT=QbzqWY1on!$#4Hl@@(X5E2z_%El-=&s#`RmZo{1oKO;hL z;-`#roO;~Fw81RQ9fxC&_?E*`Y1`5(Qg2)4xHy&qq3n#%kx|!OwRw8$oOG=H!kn4 oAY={#AOHd&00JNY0w4eaAOHd&00JOT7Ff`crjLIrx{j8A0x$AbKL7v# literal 0 HcmV?d00001 diff --git a/go.mod b/go.mod index 7dcf3af..6cbdede 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module etrismartfarmpoccontroller go 1.17 require ( + git.godopu.net/lab/etri-smartfarm-poc-controller-serial v0.1.6 github.com/gorilla/mux v1.8.0 github.com/magiconair/properties v1.8.5 github.com/urfave/negroni v1.0.0 @@ -11,7 +12,10 @@ require ( ) require ( + github.com/jacobsa/go-serial v0.0.0-20180131005756-15cf729a72d4 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.2 // indirect github.com/mattn/go-sqlite3 v1.14.9 // indirect + github.com/rjeczalik/notify v0.9.2 // indirect + golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7 // indirect ) diff --git a/go.sum b/go.sum index 5c69261..a546270 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,12 @@ +git.godopu.net/lab/etri-smartfarm-poc-controller-serial v0.1.6 h1:wHBwaWOfkdfX6U6C+eqmzUgf/IxyKdF4PdyaLH08Qg0= +git.godopu.net/lab/etri-smartfarm-poc-controller-serial v0.1.6/go.mod h1:G7GCLSX0CnuA50+PBlW7555iga99j7t3n3G4xN/37oo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/jacobsa/go-serial v0.0.0-20180131005756-15cf729a72d4 h1:G2ztCwXov8mRvP0ZfjE6nAlaCX2XbykaeHdbT6KwDz0= +github.com/jacobsa/go-serial v0.0.0-20180131005756-15cf729a72d4/go.mod h1:2RvX5ZjVtsznNZPEt4xwJXNJrM3VTZoQf7V6gk0ysvs= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI= @@ -13,11 +17,15 @@ github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/K github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rjeczalik/notify v0.9.2 h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w8= +github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= +golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7 h1:bit1t3mgdR35yN0cX0G8orgLtOuyL9Wqxa1mccLB0ig= +golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 837ce5d..7e69ec2 100644 --- a/main.go +++ b/main.go @@ -9,6 +9,8 @@ import ( "fmt" "io/ioutil" "net/http" + + manager "git.godopu.net/lab/etri-smartfarm-poc-controller-serial" ) // func runBootstrap() { @@ -116,5 +118,35 @@ func main() { run, _ := devicemanager.NewManager() run() + manager.AddRecvListener(devicemanager.NewRecvHandler()) + // handler := devicemanager.NewRecvHandler() + manager.AddRegisterHandleFunc(devicemanager.RegisterHandler) + manager.AddRemoveHandleFunc(devicemanager.RemovedHandler) + + go manager.Run() + http.ListenAndServe(":4000", router.NewRouter()) + + // for { + // fmt.Println("> ") + // var cmd string + // fmt.Scanln(&cmd) + // if cmd == "exit" { + // return + // } + + // handler.Handle(&Temp{}) + // } } + +// type Temp struct{} + +// func (*Temp) Key() interface{} { +// return &struct{}{} +// } + +// func (*Temp) Params() map[string]interface{} { +// return map[string]interface{}{ +// "uuid": "DEVICE-A-UUID", +// } +// } diff --git a/model/cache.go b/model/cache.go index 669f647..952b6de 100644 --- a/model/cache.go +++ b/model/cache.go @@ -1,24 +1,51 @@ package model import ( - "bytes" - "encoding/json" + "errors" "etrismartfarmpoccontroller/constants" "fmt" "io/ioutil" "net/http" ) +func (s *dbHandler) StatusCheck(did string, new map[string]interface{}) bool { + origin, ok := s.states[did] + if !ok { + fmt.Println(did) + fmt.Println("insert origin, before", s.states[did]) + s.states[did] = new + // origin = map[string]interface{}{} + // s.states[did] = origin + // for k, v := range new { + // origin[k] = v + // } + fmt.Println("insert origin, after", s.states[did]) + fmt.Println("insert origin, new", new) + return true + } + + changed := false + for k, v := range new { + if v.(float64) != origin[k].(float64) { + fmt.Println("origin, new", v, origin[k]) + origin[k] = v + changed = true + } + } + + return changed +} + func (s *dbHandler) GetSID(sname string) (string, error) { sid, ok := s.cache[sname] if !ok { - payload := map[string]string{"sname": sname} - b, _ := json.Marshal(payload) - req, err := http.NewRequest("GET", fmt.Sprintf("http://%s/%s", constants.Config["serverAddr"], "services"), - bytes.NewReader(b), + nil, ) + + req.Header.Set("sname", sname) + if err != nil { return "", err } @@ -26,9 +53,11 @@ func (s *dbHandler) GetSID(sname string) (string, error) { resp, err := http.DefaultClient.Do(req) if err != nil { return "", err + } else if resp.ContentLength == 0 { + return "", errors.New("not exist service") } - b, err = ioutil.ReadAll(resp.Body) + b, err := ioutil.ReadAll(resp.Body) if err != nil { return "", err } diff --git a/model/device.go b/model/device.go index d5d0075..3077f33 100644 --- a/model/device.go +++ b/model/device.go @@ -40,6 +40,17 @@ func (s *dbHandler) AddDevice(device *Device) error { } +func (s *dbHandler) GetDeviceID(dname string) (*Device, error) { + var device Device + tx := s.db.Select("did", "sname").First(&device, "dname=?", dname) + + if tx.Error != nil { + return nil, tx.Error + } + + return &device, nil +} + func (s *dbHandler) GetServiceForDevice(did string) (string, error) { var device Device tx := s.db.Select("sname").First(&device, "did=?", did) @@ -47,5 +58,5 @@ func (s *dbHandler) GetServiceForDevice(did string) (string, error) { return "", tx.Error } - return device.SName, nil + return s.GetSID(device.SName) } diff --git a/model/handler.go b/model/handler.go index 7dcb0e9..0273bd8 100644 --- a/model/handler.go +++ b/model/handler.go @@ -6,8 +6,10 @@ import ( ) type dbHandler struct { - db *gorm.DB - cache map[string]string + db *gorm.DB + cache map[string]string + states map[string]map[string]interface{} + } func newSqliteHandler(path string) (DBHandler, error) { @@ -18,7 +20,11 @@ func newSqliteHandler(path string) (DBHandler, error) { db.AutoMigrate(&Device{}) - return &dbHandler{db: db, cache: map[string]string{}}, nil + return &dbHandler{ + db: db, + cache: map[string]string{}, + states: map[string]map[string]interface{}{}, + }, nil } // func newPostgresqlHandler(path string) (DBHandler, error) { diff --git a/model/interface.go b/model/interface.go index a2c174d..1c27d8f 100644 --- a/model/interface.go +++ b/model/interface.go @@ -14,13 +14,16 @@ type DBHandler interface { AddDevice(device *Device) error GetSID(sname string) (string, error) GetServiceForDevice(did string) (string, error) + GetDeviceID(dname string) (*Device, error) + StatusCheck(did string, new map[string]interface{}) bool } var db DBHandler func GetDBHandler(dbtype, path string) (DBHandler, error) { if db == nil { - return newSqliteHandler(path) + db, _ = newSqliteHandler(path) + return db, nil } return db, nil } diff --git a/router/route.go b/router/route.go index e519f30..7e1ccf3 100644 --- a/router/route.go +++ b/router/route.go @@ -21,7 +21,7 @@ func init() { if err != nil { panic(err) } - + } func NewRouter() http.Handler { m := mux.NewRouter()