commit 2021-12-13]14:39:07
This commit is contained in:
parent
3ade3a2d62
commit
fa43e0cb9f
32
containers/devicemanagerb/constants/constants.go
Normal file
32
containers/devicemanagerb/constants/constants.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package constants
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getIP() string {
|
||||||
|
host, _ := os.Hostname()
|
||||||
|
addrs, _ := net.LookupIP(host)
|
||||||
|
|
||||||
|
return addrs[0].String()
|
||||||
|
}
|
||||||
|
|
||||||
|
var ServerAddr string
|
||||||
|
var MyIP string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
var exist bool
|
||||||
|
ServerAddr, exist = os.LookupEnv("SERVER_ADDR")
|
||||||
|
if !exist {
|
||||||
|
fmt.Println("Please set SERVER_ADDR as environment variable")
|
||||||
|
}
|
||||||
|
|
||||||
|
MyIP = getIP()
|
||||||
|
idx := strings.LastIndex(MyIP, ".")
|
||||||
|
ServerAddr = MyIP[:idx+1] + "1"
|
||||||
|
fmt.Println(ServerAddr)
|
||||||
|
|
||||||
|
}
|
@ -1,3 +1,8 @@
|
|||||||
module devicemanagerb
|
module devicemanagerb
|
||||||
|
|
||||||
go 1.17
|
go 1.17
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/gorilla/mux v1.7.4
|
||||||
|
github.com/urfave/negroni v1.0.0
|
||||||
|
)
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
|
||||||
|
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||||
|
github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=
|
||||||
|
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
|
@ -2,46 +2,26 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"devicemanagerb/constants"
|
||||||
"devicemanagerb/router"
|
"devicemanagerb/router"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var server_addr string
|
|
||||||
|
|
||||||
func getIP() string {
|
|
||||||
host, _ := os.Hostname()
|
|
||||||
addrs, _ := net.LookupIP(host)
|
|
||||||
|
|
||||||
return addrs[0].String()
|
|
||||||
}
|
|
||||||
func registerToServer() {
|
func registerToServer() {
|
||||||
var exist bool
|
|
||||||
server_addr, exist = os.LookupEnv("SERVER_ADDR")
|
|
||||||
if !exist {
|
|
||||||
fmt.Println("Please set SERVER_ADDR as environment variable")
|
|
||||||
}
|
|
||||||
|
|
||||||
ip := getIP()
|
|
||||||
idx := strings.LastIndex(ip, ".")
|
|
||||||
serverAddr := ip[:idx+1] + "1"
|
|
||||||
fmt.Println(serverAddr)
|
|
||||||
|
|
||||||
var obj map[string]string = make(map[string]string)
|
var obj map[string]string = make(map[string]string)
|
||||||
obj["name"] = "devicemanagerb"
|
obj["name"] = "devicemanagerb"
|
||||||
obj["addr"] = getIP() + ":3000"
|
obj["addr"] = constants.MyIP + ":3000"
|
||||||
|
|
||||||
b, err := json.Marshal(obj)
|
b, err := json.Marshal(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest("PUT", "http://"+serverAddr+":3000/services", bytes.NewBuffer(b))
|
req, err := http.NewRequest("PUT", "http://"+constants.ServerAddr+":3000/services", bytes.NewBuffer(b))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -56,7 +36,6 @@ func registerToServer() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
fmt.Println(string(b))
|
fmt.Println(string(b))
|
||||||
// http.Post("")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -1,15 +1,150 @@
|
|||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"devicemanagerb/constants"
|
||||||
|
"encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
"github.com/urfave/negroni"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewRouter() http.Handler {
|
func NewRouter() http.Handler {
|
||||||
mux := http.NewServeMux()
|
mux := mux.NewRouter()
|
||||||
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
// mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.WriteHeader(http.StatusOK)
|
// w.WriteHeader(http.StatusOK)
|
||||||
w.Write([]byte("I am devicemanagerB"))
|
// w.Write([]byte("I am devicemanagerB"))
|
||||||
})
|
// })
|
||||||
|
|
||||||
return mux
|
mux.HandleFunc("/{id}", PutStatusChangedHandle).Methods("PUT")
|
||||||
|
mux.HandleFunc("/{id}", PostStatusChangedHandle).Methods("POST")
|
||||||
|
mux.HandleFunc("/{id}", GetStatusHandle).Methods("GET")
|
||||||
|
|
||||||
|
n := negroni.Classic()
|
||||||
|
n.UseHandler(mux)
|
||||||
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sensing data per device
|
||||||
|
var s_data = map[string]interface{}{}
|
||||||
|
|
||||||
|
// status from sensor
|
||||||
|
func PutStatusChangedHandle(w http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
|
||||||
|
b, err := ioutil.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
status := map[string]interface{}{}
|
||||||
|
err = json.Unmarshal(b, &status)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
did, ok := vars["id"]
|
||||||
|
if !ok {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s_data[did] = status
|
||||||
|
log.Println(s_data)
|
||||||
|
|
||||||
|
cdata, ok := c_data[did]
|
||||||
|
if !ok {
|
||||||
|
w.Write([]byte("I am devicemanagerB"))
|
||||||
|
} else {
|
||||||
|
encoder := json.NewEncoder(w)
|
||||||
|
err := encoder.Encode(cdata)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("PUT", "http://"+constants.ServerAddr+":3000/device/"+did, bytes.NewReader(b))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var c_data = map[string]interface{}{}
|
||||||
|
|
||||||
|
func GetStatusHandle(w http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
did, ok := vars["id"]
|
||||||
|
if !ok {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
status, ok := c_data[did]
|
||||||
|
if !ok {
|
||||||
|
status = map[string]interface{}{
|
||||||
|
"servo": 0,
|
||||||
|
"fan": 0,
|
||||||
|
"light": 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
encoder := json.NewEncoder(w)
|
||||||
|
|
||||||
|
err := encoder.Encode(status)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
func PostStatusChangedHandle(w http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
|
||||||
|
b, err := ioutil.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
status := map[string]interface{}{}
|
||||||
|
err = json.Unmarshal(b, &status)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
did, ok := vars["id"]
|
||||||
|
if !ok {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c_data[did] = status
|
||||||
|
log.Println(c_data)
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
// status from user per device
|
||||||
|
4
init.sh
4
init.sh
@ -1 +1,3 @@
|
|||||||
rm -r *.db *.pcap
|
rm -r *.db
|
||||||
|
docker container stop $(docker container ls -q)
|
||||||
|
docker container prune
|
@ -55,10 +55,5 @@ func (s *dbHandler) IsExistController(cid string) bool {
|
|||||||
|
|
||||||
result := s.db.First(&controller, "cid=?", cid)
|
result := s.db.First(&controller, "cid=?", cid)
|
||||||
|
|
||||||
if result.Error != nil {
|
return result.Error == nil
|
||||||
fmt.Println(result.Error)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
@ -41,3 +41,33 @@ func (s *dbHandler) AddDevice(device *Device) error {
|
|||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *dbHandler) QueryDevice(dname string) (*Device, error) {
|
||||||
|
var device Device
|
||||||
|
tx := s.db.First(&device, "dname=?", dname)
|
||||||
|
|
||||||
|
if tx.Error != nil {
|
||||||
|
return nil, tx.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
return &device, nil
|
||||||
|
}
|
||||||
|
func (s *dbHandler) DeleteDevice(device *Device) error {
|
||||||
|
|
||||||
|
tx := s.db.Delete(device)
|
||||||
|
if tx.Error != nil {
|
||||||
|
return tx.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
tx.First(device, "did=?", device.DID)
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *dbHandler) IsExistDevice(dname string) bool {
|
||||||
|
var device = Device{}
|
||||||
|
|
||||||
|
result := s.db.First(&device, "dname=?", dname)
|
||||||
|
|
||||||
|
return result.Error != nil
|
||||||
|
}
|
||||||
|
@ -16,6 +16,9 @@ import (
|
|||||||
type DBHandler interface {
|
type DBHandler interface {
|
||||||
GetDevices() ([]*Device, int, error)
|
GetDevices() ([]*Device, int, error)
|
||||||
AddDevice(d *Device) error
|
AddDevice(d *Device) error
|
||||||
|
QueryDevice(dname string) (*Device, error)
|
||||||
|
DeleteDevice(device *Device) error
|
||||||
|
IsExistDevice(dname string) bool
|
||||||
AddController(r io.Reader) (*Controller, error)
|
AddController(r io.Reader) (*Controller, error)
|
||||||
GetControllers() ([]*Controller, error)
|
GetControllers() ([]*Controller, error)
|
||||||
IsExistController(cid string) bool
|
IsExistController(cid string) bool
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
@ -77,6 +79,9 @@ func (s *dbHandler) GetSID(name string) (string, error) {
|
|||||||
return "", tx.Error
|
return "", tx.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(service.SID) == 0 {
|
||||||
|
return "", errors.New("not installed service")
|
||||||
|
}
|
||||||
return service.SID, nil
|
return service.SID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
public-ws/index.html
Normal file
14
public-ws/index.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Web socket sample</title>
|
||||||
|
<script src="./index.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div>hello</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
25
public-ws/index.js
Normal file
25
public-ws/index.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
window.onload = () => {
|
||||||
|
if (!window.WebSocket) {
|
||||||
|
alert("No WebSocket!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
function connect() {
|
||||||
|
let ws = new WebSocket(`ws://${window.location.host}/device/73531420-ae8c-47be-9eff-308d946f3a65`);
|
||||||
|
ws.onopen = (e) => {
|
||||||
|
console.log("onopen", arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
ws.onclose = () => {
|
||||||
|
console.log("onclose", arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
ws.onmessage = function (e) {
|
||||||
|
console.log(e.data);
|
||||||
|
// addMessage(JSON.parse(e.data));
|
||||||
|
console.log(JSON.parse(e.data));
|
||||||
|
}
|
||||||
|
return ws;
|
||||||
|
}
|
||||||
|
|
||||||
|
ws = connect();
|
||||||
|
}
|
50
router/controller.go
Normal file
50
router/controller.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetControllerList(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
|
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
|
||||||
|
list, err := db.GetControllers()
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println(list)
|
||||||
|
encoder := json.NewEncoder(w)
|
||||||
|
|
||||||
|
err = encoder.Encode(list)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func PostController(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
|
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
|
||||||
|
|
||||||
|
controller, err := db.AddController(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.WriteHeader(http.StatusCreated)
|
||||||
|
encoder := json.NewEncoder(w)
|
||||||
|
err = encoder.Encode(controller)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sendNotification(&Notification{Msg: "Added Controller"})
|
||||||
|
}
|
240
router/devices.go
Normal file
240
router/devices.go
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"etrismartfarmpoc/model"
|
||||||
|
"etrismartfarmpoc/watcher"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
)
|
||||||
|
|
||||||
|
var waitPermission = map[string]chan bool{}
|
||||||
|
var mutex sync.Mutex
|
||||||
|
var discoveredDevices = []*model.Device{}
|
||||||
|
|
||||||
|
func GetDiscoveredDevices(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
|
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
|
||||||
|
|
||||||
|
encoder := json.NewEncoder(w)
|
||||||
|
encoder.Encode(discoveredDevices)
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeDevice(device *model.Device) {
|
||||||
|
for i, e := range discoveredDevices {
|
||||||
|
if e == device {
|
||||||
|
discoveredDevices[i] = discoveredDevices[len(discoveredDevices)-1]
|
||||||
|
discoveredDevices = discoveredDevices[:len(discoveredDevices)-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDevices(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
|
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
|
||||||
|
|
||||||
|
devices, _, err := db.GetDevices()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
encoder := json.NewEncoder(w)
|
||||||
|
encoder.Encode(devices)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostDevice : Handle for Receiving discovery message
|
||||||
|
func PostDevice(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var device = &model.Device{}
|
||||||
|
decoder := json.NewDecoder(r.Body)
|
||||||
|
err := decoder.Decode(device)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 등록된 제어기로 부터 전송된 요청 메시지임을 확인
|
||||||
|
if !db.IsExistController(device.CID) {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte("Wrong Controller ID"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !db.IsExistDevice(device.DName) {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte("Already exist device"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 장치 ID 생성 및 탐색된 장치 추가
|
||||||
|
device.DID = uuid.NewString()
|
||||||
|
mutex.Lock()
|
||||||
|
waitPermission[device.DID] = make(chan bool)
|
||||||
|
discoveredDevices = append(discoveredDevices, device)
|
||||||
|
|
||||||
|
// 관리자에게 탐색을 알림
|
||||||
|
sendNotification(&Notification{Msg: "Add discovered device"})
|
||||||
|
mutex.Unlock()
|
||||||
|
|
||||||
|
timer := time.NewTimer(20 * time.Second)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-r.Context().Done():
|
||||||
|
fmt.Println("^^")
|
||||||
|
mutex.Lock()
|
||||||
|
defer mutex.Unlock()
|
||||||
|
delete(waitPermission, device.DID)
|
||||||
|
removeDevice(device)
|
||||||
|
sendNotification(&Notification{Msg: "Remove discovered device"})
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Write([]byte("This operation is not permitted"))
|
||||||
|
return
|
||||||
|
case <-timer.C:
|
||||||
|
mutex.Lock()
|
||||||
|
defer mutex.Unlock()
|
||||||
|
delete(waitPermission, device.DID)
|
||||||
|
removeDevice(device)
|
||||||
|
sendNotification(&Notification{Msg: "Remove discovered device"})
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Write([]byte("This operation is not permitted"))
|
||||||
|
return
|
||||||
|
case b := <-waitPermission[device.DID]:
|
||||||
|
if b {
|
||||||
|
// 디바이스 등록 절차 수행
|
||||||
|
db.AddDevice(device)
|
||||||
|
db.AddService(device.SName)
|
||||||
|
|
||||||
|
// 디바이스 등록 알림
|
||||||
|
w.WriteHeader(http.StatusCreated)
|
||||||
|
json.NewEncoder(w).Encode(device)
|
||||||
|
sendNotification(&Notification{Msg: "Added Device"})
|
||||||
|
mutex.Lock()
|
||||||
|
defer mutex.Unlock()
|
||||||
|
delete(waitPermission, device.DID)
|
||||||
|
removeDevice(device)
|
||||||
|
sendNotification(&Notification{Msg: "Add device"})
|
||||||
|
} else {
|
||||||
|
mutex.Lock()
|
||||||
|
defer mutex.Unlock()
|
||||||
|
delete(waitPermission, device.DID)
|
||||||
|
removeDevice(device)
|
||||||
|
sendNotification(&Notification{Msg: "Remove discovered device"})
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Write([]byte("This operation is not permitted"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteDevice(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
|
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
|
||||||
|
msg := map[string]string{}
|
||||||
|
decoder := json.NewDecoder(r.Body)
|
||||||
|
err := decoder.Decode(&msg)
|
||||||
|
|
||||||
|
device, err := db.QueryDevice(msg["dname"])
|
||||||
|
db.DeleteDevice(device)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
}
|
||||||
|
|
||||||
|
sendNotification(&Notification{Msg: "Delete device"})
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
func PutDevice(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
|
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
|
||||||
|
msg := map[string]string{}
|
||||||
|
decoder := json.NewDecoder(r.Body)
|
||||||
|
err := decoder.Decode(&msg)
|
||||||
|
|
||||||
|
fmt.Println("msg[did]: ", msg["did"])
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
}
|
||||||
|
|
||||||
|
ch, ok := waitPermission[msg["did"]]
|
||||||
|
if !ok {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte("Wrong Device ID is Sended"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ch <- true
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 값 변경 알림
|
||||||
|
func PutDeviceStatus(w http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
did, ok := vars["id"]
|
||||||
|
if !ok {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte("not found did"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.ContentLength == 0 {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
watch, ok := watchers[did]
|
||||||
|
if !ok {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
param := map[string]interface{}{}
|
||||||
|
decoder := json.NewDecoder(r.Body)
|
||||||
|
|
||||||
|
err := decoder.Decode(¶m)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
watch.Notify(watcher.NewStateChangedEvent(nil, param))
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
// func PostDeviceStatus(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// vars := mux.Vars(r)
|
||||||
|
// did, ok := vars["id"]
|
||||||
|
// if !ok {
|
||||||
|
// w.WriteHeader(http.StatusBadRequest)
|
||||||
|
// w.Write([]byte("not found did"))
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if r.ContentLength == 0 {
|
||||||
|
// w.WriteHeader(http.StatusOK)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// watch, ok := watchers[did]
|
||||||
|
// if !ok {
|
||||||
|
// w.WriteHeader(http.StatusOK)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// param := map[string]interface{}{}
|
||||||
|
// decoder := json.NewDecoder(r.Body)
|
||||||
|
|
||||||
|
// err := decoder.Decode(¶m)
|
||||||
|
// if err != nil {
|
||||||
|
// w.WriteHeader(http.StatusOK)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// watch.Notify(watcher.NewStateChangedEvent(nil, param))
|
||||||
|
// }
|
151
router/notification.go
Normal file
151
router/notification.go
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"etrismartfarmpoc/watcher"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
var upgrader = websocket.Upgrader{
|
||||||
|
ReadBufferSize: 1024,
|
||||||
|
WriteBufferSize: 1024,
|
||||||
|
CheckOrigin: func(r *http.Request) bool { return true },
|
||||||
|
}
|
||||||
|
|
||||||
|
var notifications []chan *Notification
|
||||||
|
var notiMutex sync.Mutex
|
||||||
|
|
||||||
|
func sendNotification(noti *Notification) {
|
||||||
|
// notiMutex.Lock()
|
||||||
|
// defer notiMutex.Unlock()
|
||||||
|
for _, ch := range notifications {
|
||||||
|
ch <- noti
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeNotification(noti chan *Notification) {
|
||||||
|
notiMutex.Lock()
|
||||||
|
defer notiMutex.Unlock()
|
||||||
|
for i, e := range notifications {
|
||||||
|
if e == noti {
|
||||||
|
discoveredDevices[i] = discoveredDevices[len(discoveredDevices)-1]
|
||||||
|
discoveredDevices = discoveredDevices[:len(discoveredDevices)-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetNotification(w http.ResponseWriter, r *http.Request) {
|
||||||
|
notiChan := make(chan *Notification, 1)
|
||||||
|
notiMutex.Lock()
|
||||||
|
notifications = append(notifications, notiChan)
|
||||||
|
notiMutex.Unlock()
|
||||||
|
conn, err := upgrader.Upgrade(w, r, nil)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
notification := <-notiChan
|
||||||
|
// fmt.Println("Write!!", discoveredDevices)
|
||||||
|
if conn.WriteJSON(notification) != nil {
|
||||||
|
log.Println(err)
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
removeNotification(notiChan)
|
||||||
|
notiChan = nil
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var watchers = map[string]*watcher.DeviceWatcher{}
|
||||||
|
|
||||||
|
func GetDeviceWatch(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
did, ok := vars["id"]
|
||||||
|
if !ok {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte("not found did"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
conn, err := upgrader.Upgrade(w, r, nil)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// payload := map[string]interface{}{}
|
||||||
|
// decoder := json.NewDecoder(r.Body)
|
||||||
|
// err = decoder.Decode(&payload)
|
||||||
|
// if err != nil {
|
||||||
|
// w.WriteHeader(http.StatusBadRequest)
|
||||||
|
// w.Write([]byte(err.Error()))
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
if !checkDid(did) {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte("not exist did"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s := make(chan map[string]interface{})
|
||||||
|
ec := make(chan error)
|
||||||
|
|
||||||
|
defer close(s)
|
||||||
|
watch, ok := watchers[did]
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
watch = &watcher.DeviceWatcher{}
|
||||||
|
watchers[did] = watch
|
||||||
|
}
|
||||||
|
|
||||||
|
watch.Subscribe(s)
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
cnt := watch.Desubscribe(s)
|
||||||
|
if cnt == 0 {
|
||||||
|
delete(watchers, did)
|
||||||
|
log.Println("delete watchers: ", watchers)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
_, _, err := conn.ReadMessage()
|
||||||
|
if err != nil {
|
||||||
|
ec <- err
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case param := <-s:
|
||||||
|
if conn.WriteJSON(param) != nil {
|
||||||
|
log.Println(err)
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
case <-r.Context().Done():
|
||||||
|
fmt.Println("see you later~")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Write([]byte("See you later~"))
|
||||||
|
return
|
||||||
|
case <-ec:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkDid(did string) bool {
|
||||||
|
return true
|
||||||
|
}
|
375
router/route.go
375
router/route.go
@ -2,24 +2,16 @@ package router
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"etrismartfarmpoc/containermgmt"
|
|
||||||
"etrismartfarmpoc/model"
|
"etrismartfarmpoc/model"
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/gorilla/websocket"
|
|
||||||
"github.com/urfave/negroni"
|
"github.com/urfave/negroni"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Notification struct {
|
type Notification struct {
|
||||||
Msg string `json:msg`
|
Msg string `json:"msg"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var db model.DBHandler
|
var db model.DBHandler
|
||||||
@ -43,7 +35,10 @@ func NewRouter() http.Handler {
|
|||||||
mux.HandleFunc("/services", PutServices).Methods("PUT")
|
mux.HandleFunc("/services", PutServices).Methods("PUT")
|
||||||
mux.HandleFunc("/devices", PostDevice).Methods("POST")
|
mux.HandleFunc("/devices", PostDevice).Methods("POST")
|
||||||
mux.HandleFunc("/devices", GetDevices).Methods("GET")
|
mux.HandleFunc("/devices", GetDevices).Methods("GET")
|
||||||
|
mux.HandleFunc("/devices", DeleteDevice).Methods("DELETE")
|
||||||
mux.HandleFunc("/devices", PutDevice).Methods("PUT", "OPTIONS")
|
mux.HandleFunc("/devices", PutDevice).Methods("PUT", "OPTIONS")
|
||||||
|
mux.HandleFunc("/device/{id}", GetDeviceWatch).Methods("GET")
|
||||||
|
mux.HandleFunc("/device/{id}", PutDeviceStatus).Methods("PUT")
|
||||||
mux.HandleFunc("/discover", GetDiscoveredDevices).Methods("GET")
|
mux.HandleFunc("/discover", GetDiscoveredDevices).Methods("GET")
|
||||||
mux.PathPrefix("/services/").HandlerFunc(RouteRequestToService)
|
mux.PathPrefix("/services/").HandlerFunc(RouteRequestToService)
|
||||||
|
|
||||||
@ -70,101 +65,6 @@ func EchoRoute(w http.ResponseWriter, r *http.Request) {
|
|||||||
encoder.Encode(m)
|
encoder.Encode(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetControllerList(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
||||||
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
|
|
||||||
list, err := db.GetControllers()
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
w.Write([]byte(err.Error()))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fmt.Println(list)
|
|
||||||
encoder := json.NewEncoder(w)
|
|
||||||
|
|
||||||
err = encoder.Encode(list)
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
w.Write([]byte(err.Error()))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PostController(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
||||||
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
|
|
||||||
|
|
||||||
controller, err := db.AddController(r.Body)
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
w.Write([]byte(err.Error()))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusCreated)
|
|
||||||
encoder := json.NewEncoder(w)
|
|
||||||
err = encoder.Encode(controller)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
w.Write([]byte(err.Error()))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
sendNotification(&Notification{Msg: "Added Controller"})
|
|
||||||
}
|
|
||||||
|
|
||||||
var upgrader = websocket.Upgrader{
|
|
||||||
ReadBufferSize: 1024,
|
|
||||||
WriteBufferSize: 1024,
|
|
||||||
CheckOrigin: func(r *http.Request) bool { return true },
|
|
||||||
}
|
|
||||||
|
|
||||||
var notifications []chan *Notification
|
|
||||||
var notiMutex sync.Mutex
|
|
||||||
|
|
||||||
func sendNotification(noti *Notification) {
|
|
||||||
// notiMutex.Lock()
|
|
||||||
// defer notiMutex.Unlock()
|
|
||||||
for _, ch := range notifications {
|
|
||||||
ch <- noti
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func removeNotification(noti chan *Notification) {
|
|
||||||
notiMutex.Lock()
|
|
||||||
defer notiMutex.Unlock()
|
|
||||||
for i, e := range notifications {
|
|
||||||
if e == noti {
|
|
||||||
discoveredDevices[i] = discoveredDevices[len(discoveredDevices)-1]
|
|
||||||
discoveredDevices = discoveredDevices[:len(discoveredDevices)-1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func GetNotification(w http.ResponseWriter, r *http.Request) {
|
|
||||||
notiChan := make(chan *Notification, 1)
|
|
||||||
notiMutex.Lock()
|
|
||||||
notifications = append(notifications, notiChan)
|
|
||||||
notiMutex.Unlock()
|
|
||||||
conn, err := upgrader.Upgrade(w, r, nil)
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
w.Write([]byte(err.Error()))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
notification := <-notiChan
|
|
||||||
// fmt.Println("Write!!", discoveredDevices)
|
|
||||||
if conn.WriteJSON(notification) != nil {
|
|
||||||
log.Println(err)
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
removeNotification(notiChan)
|
|
||||||
notiChan = nil
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// func GetDiscoveredDevices(w http.ResponseWriter, r *http.Request) {
|
// func GetDiscoveredDevices(w http.ResponseWriter, r *http.Request) {
|
||||||
// noti := make(chan string, 1)
|
// noti := make(chan string, 1)
|
||||||
// mutex.Lock()
|
// mutex.Lock()
|
||||||
@ -187,273 +87,6 @@ func GetNotification(w http.ResponseWriter, r *http.Request) {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
var waitPermission = map[string]chan bool{}
|
|
||||||
var mutex sync.Mutex
|
|
||||||
var discoveredDevices = []*model.Device{}
|
|
||||||
|
|
||||||
func GetDiscoveredDevices(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
||||||
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
|
|
||||||
|
|
||||||
encoder := json.NewEncoder(w)
|
|
||||||
encoder.Encode(discoveredDevices)
|
|
||||||
}
|
|
||||||
|
|
||||||
func removeDevice(device *model.Device) {
|
|
||||||
for i, e := range discoveredDevices {
|
|
||||||
if e == device {
|
|
||||||
discoveredDevices[i] = discoveredDevices[len(discoveredDevices)-1]
|
|
||||||
discoveredDevices = discoveredDevices[:len(discoveredDevices)-1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetDevices(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
||||||
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
|
|
||||||
devices, _, err := db.GetDevices()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
encoder := json.NewEncoder(w)
|
|
||||||
encoder.Encode(devices)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PostDevice : Handle for Receiving discovery message
|
|
||||||
func PostDevice(w http.ResponseWriter, r *http.Request) {
|
|
||||||
var device = &model.Device{}
|
|
||||||
decoder := json.NewDecoder(r.Body)
|
|
||||||
err := decoder.Decode(device)
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 등록된 제어기로 부터 전송된 요청 메시지임을 확인
|
|
||||||
if !db.IsExistController(device.CID) {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
w.Write([]byte("Wrong Controller ID"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 장치 ID 생성 및 탐색된 장치 추가
|
|
||||||
device.DID = uuid.NewString()
|
|
||||||
mutex.Lock()
|
|
||||||
waitPermission[device.DID] = make(chan bool)
|
|
||||||
discoveredDevices = append(discoveredDevices, device)
|
|
||||||
|
|
||||||
// 관리자에게 탐색을 알림
|
|
||||||
sendNotification(&Notification{Msg: "Add discovered device"})
|
|
||||||
mutex.Unlock()
|
|
||||||
|
|
||||||
timer := time.NewTimer(20 * time.Second)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-r.Context().Done():
|
|
||||||
fmt.Println("^^")
|
|
||||||
mutex.Lock()
|
|
||||||
defer mutex.Unlock()
|
|
||||||
delete(waitPermission, device.DID)
|
|
||||||
removeDevice(device)
|
|
||||||
sendNotification(&Notification{Msg: "Remove discovered device"})
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
w.Write([]byte("This operation is not permitted"))
|
|
||||||
return
|
|
||||||
case <-timer.C:
|
|
||||||
mutex.Lock()
|
|
||||||
defer mutex.Unlock()
|
|
||||||
delete(waitPermission, device.DID)
|
|
||||||
removeDevice(device)
|
|
||||||
sendNotification(&Notification{Msg: "Remove discovered device"})
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
w.Write([]byte("This operation is not permitted"))
|
|
||||||
return
|
|
||||||
case b := <-waitPermission[device.DID]:
|
|
||||||
if b {
|
|
||||||
// 디바이스 등록 절차 수행
|
|
||||||
db.AddDevice(device)
|
|
||||||
db.AddService(device.SName)
|
|
||||||
|
|
||||||
// 디바이스 등록 알림
|
|
||||||
w.WriteHeader(http.StatusCreated)
|
|
||||||
json.NewEncoder(w).Encode(device)
|
|
||||||
sendNotification(&Notification{Msg: "Added Device"})
|
|
||||||
mutex.Lock()
|
|
||||||
defer mutex.Unlock()
|
|
||||||
delete(waitPermission, device.DID)
|
|
||||||
removeDevice(device)
|
|
||||||
sendNotification(&Notification{Msg: "Add device"})
|
|
||||||
} else {
|
|
||||||
mutex.Lock()
|
|
||||||
defer mutex.Unlock()
|
|
||||||
delete(waitPermission, device.DID)
|
|
||||||
removeDevice(device)
|
|
||||||
sendNotification(&Notification{Msg: "Remove discovered device"})
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
w.Write([]byte("This operation is not permitted"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PutDevice(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
||||||
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
|
|
||||||
msg := map[string]string{}
|
|
||||||
decoder := json.NewDecoder(r.Body)
|
|
||||||
err := decoder.Decode(&msg)
|
|
||||||
|
|
||||||
fmt.Println("msg[did]: ", msg["did"])
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
w.Write([]byte(err.Error()))
|
|
||||||
}
|
|
||||||
|
|
||||||
ch, ok := waitPermission[msg["did"]]
|
|
||||||
if !ok {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
w.Write([]byte("Wrong Device ID is Sended"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ch <- true
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetServices(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
||||||
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
|
|
||||||
|
|
||||||
if r.ContentLength != 0 {
|
|
||||||
obj := map[string]string{}
|
|
||||||
err := json.NewDecoder(r.Body).Decode(&obj)
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
sid, err := db.GetSID(obj["sname"])
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.Write([]byte(sid))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l, err := db.GetServices()
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.NewEncoder(w).Encode(l)
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func PutServices(w http.ResponseWriter, r *http.Request) {
|
|
||||||
var obj = map[string]string{}
|
|
||||||
|
|
||||||
decoder := json.NewDecoder(r.Body)
|
|
||||||
err := decoder.Decode(&obj)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
s, err := db.UpdateService(obj["name"], obj["addr"])
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
sendNotification(&Notification{Msg: "Update Service"})
|
|
||||||
err = json.NewEncoder(w).Encode(s)
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// func GetServiceList(w http.ResponseWriter, r *http.Request) {
|
|
||||||
// result := containermgmt.GetContainers(context.Background())
|
|
||||||
// b := result.Value(containermgmt.ReturnKey).([]byte)
|
|
||||||
// w.Write(b)
|
|
||||||
// }
|
|
||||||
|
|
||||||
func PostService(w http.ResponseWriter, r *http.Request) {
|
|
||||||
|
|
||||||
var obj = map[string]string{}
|
|
||||||
decoder := json.NewDecoder(r.Body)
|
|
||||||
err := decoder.Decode(&obj)
|
|
||||||
|
|
||||||
db.IsExistService(obj["name"])
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
w.Write([]byte(err.Error()))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = containermgmt.CreateContainer(obj["name"])
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
w.Write([]byte(err.Error()))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
w.WriteHeader(http.StatusCreated)
|
|
||||||
}
|
|
||||||
|
|
||||||
func RouteRequestToService(w http.ResponseWriter, r *http.Request) {
|
|
||||||
l := len([]rune("/services/"))
|
|
||||||
var id string
|
|
||||||
var url string
|
|
||||||
idx := strings.Index(r.RequestURI[l:], "/")
|
|
||||||
if idx == -1 {
|
|
||||||
id = r.RequestURI[l:]
|
|
||||||
url = "/"
|
|
||||||
} else {
|
|
||||||
id = r.RequestURI[l : l+idx]
|
|
||||||
if len([]rune(r.RequestURI)) <= l+idx {
|
|
||||||
url = "/"
|
|
||||||
} else {
|
|
||||||
url = r.RequestURI[l+idx:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// w.Write([]byte(vars["url"]))
|
|
||||||
host, err := db.GetAddr(id)
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Println("Route to", host+"/"+url)
|
|
||||||
req, err := http.NewRequest(r.Method, "http://"+host+"/"+url, r.Body)
|
|
||||||
if err != nil {
|
|
||||||
// 잘못된 메시지 포맷이 전달된 경우
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
fmt.Fprint(w, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
// 잘못된 메시지 포맷이 전달된 경우
|
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
|
||||||
fmt.Fprint(w, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
io.Copy(w, resp.Body)
|
|
||||||
}
|
|
||||||
|
|
||||||
// func mapService(urls []string) {
|
// func mapService(urls []string) {
|
||||||
|
|
||||||
// }
|
// }
|
||||||
|
139
router/services.go
Normal file
139
router/services.go
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"etrismartfarmpoc/containermgmt"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetServices(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
|
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
|
||||||
|
|
||||||
|
sname := r.Header.Get("sname")
|
||||||
|
|
||||||
|
if len(sname) != 0 {
|
||||||
|
sid, err := db.GetSID(sname)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Write([]byte(sid))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
l, err := db.GetServices()
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.NewEncoder(w).Encode(l)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func PutServices(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var obj = map[string]string{}
|
||||||
|
|
||||||
|
decoder := json.NewDecoder(r.Body)
|
||||||
|
err := decoder.Decode(&obj)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := db.UpdateService(obj["name"], obj["addr"])
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sendNotification(&Notification{Msg: "Update Service"})
|
||||||
|
err = json.NewEncoder(w).Encode(s)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// func GetServiceList(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// result := containermgmt.GetContainers(context.Background())
|
||||||
|
// b := result.Value(containermgmt.ReturnKey).([]byte)
|
||||||
|
// w.Write(b)
|
||||||
|
// }
|
||||||
|
|
||||||
|
func PostService(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
var obj = map[string]string{}
|
||||||
|
decoder := json.NewDecoder(r.Body)
|
||||||
|
err := decoder.Decode(&obj)
|
||||||
|
|
||||||
|
db.IsExistService(obj["name"])
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = containermgmt.CreateContainer(obj["name"])
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusCreated)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RouteRequestToService(w http.ResponseWriter, r *http.Request) {
|
||||||
|
l := len([]rune("/services/"))
|
||||||
|
var id string
|
||||||
|
var url string
|
||||||
|
idx := strings.Index(r.RequestURI[l:], "/")
|
||||||
|
if idx == -1 {
|
||||||
|
id = r.RequestURI[l:]
|
||||||
|
url = "/"
|
||||||
|
} else {
|
||||||
|
id = r.RequestURI[l : l+idx]
|
||||||
|
if len([]rune(r.RequestURI)) <= l+idx {
|
||||||
|
url = "/"
|
||||||
|
} else {
|
||||||
|
url = r.RequestURI[l+idx:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// w.Write([]byte(vars["url"]))
|
||||||
|
host, err := db.GetAddr(id)
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("Route to", host+url)
|
||||||
|
req, err := http.NewRequest(r.Method, "http://"+host+url, r.Body)
|
||||||
|
if err != nil {
|
||||||
|
// 잘못된 메시지 포맷이 전달된 경우
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
fmt.Fprint(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
// 잘못된 메시지 포맷이 전달된 경우
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
fmt.Fprint(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
io.Copy(w, resp.Body)
|
||||||
|
}
|
5
watcher/cli.go
Normal file
5
watcher/cli.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package watcher
|
||||||
|
|
||||||
|
func NewStateChangedEvent(t interface{}, param map[string]interface{}) *StatusChangedEvent {
|
||||||
|
return &StatusChangedEvent{t: t, param: param}
|
||||||
|
}
|
32
watcher/device_watcher.go
Normal file
32
watcher/device_watcher.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package watcher
|
||||||
|
|
||||||
|
type DeviceWatcher struct {
|
||||||
|
// did string
|
||||||
|
subscriber []chan map[string]interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dw *DeviceWatcher) Notify(e Event) {
|
||||||
|
dw.onChanged(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dw *DeviceWatcher) onChanged(e Event) {
|
||||||
|
for _, s := range dw.subscriber {
|
||||||
|
s <- e.Param()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dw *DeviceWatcher) Subscribe(s chan map[string]interface{}) {
|
||||||
|
dw.subscriber = append(dw.subscriber, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dw *DeviceWatcher) Desubscribe(s chan map[string]interface{}) int {
|
||||||
|
length := len(dw.subscriber)
|
||||||
|
for i, e := range dw.subscriber {
|
||||||
|
if s == e {
|
||||||
|
dw.subscriber[i] = dw.subscriber[length-1]
|
||||||
|
dw.subscriber = dw.subscriber[:length-1]
|
||||||
|
return length - 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return length
|
||||||
|
}
|
13
watcher/interface.go
Normal file
13
watcher/interface.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package watcher
|
||||||
|
|
||||||
|
type Watcher interface {
|
||||||
|
}
|
||||||
|
|
||||||
|
type Event interface {
|
||||||
|
Type() interface{}
|
||||||
|
Param() map[string]interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type EventListener interface {
|
||||||
|
Handle(e Event)
|
||||||
|
}
|
44
watcher/status_changed.go
Normal file
44
watcher/status_changed.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package watcher
|
||||||
|
|
||||||
|
type StatusChangedEvent struct {
|
||||||
|
Event
|
||||||
|
t interface{}
|
||||||
|
param map[string]interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *StatusChangedEvent) Type() interface{} {
|
||||||
|
return e.t
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *StatusChangedEvent) Param() map[string]interface{} {
|
||||||
|
return e.param
|
||||||
|
}
|
||||||
|
|
||||||
|
// type StatusChangedListener struct {
|
||||||
|
// h func(e Event)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (l *StatusChangedListener) Handle(e Event) {
|
||||||
|
// if l.h != nil {
|
||||||
|
// l.h(e)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (l *StatusChangedListener) AddSubscriber(s chan map[string]interface{}) {
|
||||||
|
// l.subscriber = append(l.subscriber, s)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (l *StatusChangedListener) RemoveSubscriber(s chan map[string]interface{}) int {
|
||||||
|
// length := len(l.subscriber)
|
||||||
|
// for i, e := range l.subscriber {
|
||||||
|
// if s == e {
|
||||||
|
// l.subscriber[i] = l.subscriber[length-1]
|
||||||
|
// l.subscriber = l.subscriber[:length-1]
|
||||||
|
// return length - 1
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return length
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (l *StatusChangedListener) onClose() {}
|
Loading…
Reference in New Issue
Block a user