zoorest/rest/api.go

194 lines
3.8 KiB
Go
Raw Permalink Normal View History

2017-02-15 17:09:28 +03:00
package rest
import (
"encoding/json"
"github.com/gorilla/mux"
"github.com/samuel/go-zookeeper/zk"
2017-02-17 11:05:54 +03:00
"io/ioutil"
2017-02-15 17:09:28 +03:00
"log"
"net/http"
2017-02-17 11:05:54 +03:00
"strings"
2017-02-15 17:09:28 +03:00
"time"
)
// Ls ...
type Ls struct {
Childrens []string `json:"childrens"`
Path string `json:"path"`
State string `json:"state"`
2017-02-15 17:24:58 +03:00
Error string `json:"error"`
ZkStat *zk.Stat `json:"zkstat"`
2017-02-15 17:09:28 +03:00
}
// Get ...
type Get struct {
Path string `json:"path"`
State string `json:"state"`
Error string `json:"error"`
ZkStat *zk.Stat `json:"zkstat"`
Data []byte `json:"data"`
2017-02-15 17:09:28 +03:00
}
// LS ...
func (zk ZooNode) LS(w http.ResponseWriter, r *http.Request) {
2017-02-17 12:34:43 +03:00
if r.Method != "GET" {
e := strings.Join([]string{"Method", r.Method, "not alowed"}, " ")
w.WriteHeader(500)
w.Write([]byte(e))
return
}
2017-02-15 17:09:28 +03:00
vars := mux.Vars(r)
path := vars["path"]
ch := make(chan Ls)
go func() { ch <- zk.GetChildrens(path) }()
childrens := <-ch
data, err := json.Marshal(childrens)
if err != nil {
w.WriteHeader(500)
2017-02-15 17:24:58 +03:00
w.Write([]byte("JSON parsing failure"))
return
}
if childrens.Error != "" {
w.WriteHeader(500)
w.Write(data)
return
2017-02-15 17:09:28 +03:00
}
2017-02-15 17:24:58 +03:00
2017-02-15 17:09:28 +03:00
w.WriteHeader(200)
w.Write(data)
}
2017-02-17 11:05:54 +03:00
// ReadRequestBody ...
func ReadRequestBody(req *http.Request) ([]byte, error) {
body, err := ioutil.ReadAll(req.Body)
if err != nil {
return []byte(""), err
}
return body, err
}
// UP ...
func (zk ZooNode) UP(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
path := vars["path"]
ch := make(chan string)
// Read request body as []byte
content, err := ReadRequestBody(r)
if err != nil {
w.WriteHeader(500)
w.Write([]byte(err.Error()))
return
}
// Create node
if r.Method == "PUT" {
go func() { ch <- zk.CreateNode(path, content) }()
} else if r.Method == "POST" {
go func() { ch <- zk.UpdateNode(path, content) }()
} else if r.Method == "PATCH" {
go func() { ch <- zk.CreateChild(path, content) }()
2017-02-17 11:05:54 +03:00
} else {
2017-02-17 12:34:43 +03:00
e := strings.Join([]string{"Method", r.Method, "not alowed"}, " ")
2017-02-17 11:05:54 +03:00
w.WriteHeader(500)
w.Write([]byte(e))
return
}
defer r.Body.Close()
state := <-ch
w.WriteHeader(200)
w.Write([]byte(state))
}
2017-02-15 19:13:12 +03:00
// RM ...
func (zk ZooNode) RM(w http.ResponseWriter, r *http.Request) {
2017-02-17 12:34:43 +03:00
if r.Method != "DELETE" {
e := strings.Join([]string{"Method", r.Method, "not alowed"}, " ")
2017-02-17 11:05:54 +03:00
w.WriteHeader(500)
w.Write([]byte(e))
return
}
2017-02-15 19:13:12 +03:00
vars := mux.Vars(r)
path := vars["path"]
2017-02-17 12:34:43 +03:00
if path == "/" {
e := "Skiping root path"
w.WriteHeader(500)
w.Write([]byte(e))
return
}
var rmPath string
rmPath = strings.Join([]string{zk.Path, path}, "")
2017-02-17 12:34:43 +03:00
if strings.Contains(rmPath, "//") {
rmPath = strings.Replace(rmPath, "//", "/", 1)
}
go func() { zk.RMR(rmPath) }()
2017-02-15 19:13:12 +03:00
w.WriteHeader(200)
w.Write([]byte(path))
2017-02-15 19:13:12 +03:00
}
2017-02-15 17:09:28 +03:00
// GET ...
func (zk ZooNode) GET(w http.ResponseWriter, r *http.Request) {
2017-02-17 12:34:43 +03:00
if r.Method != "GET" {
e := strings.Join([]string{"Method", r.Method, "not alowed"}, " ")
w.WriteHeader(500)
w.Write([]byte(e))
return
}
2017-02-15 17:09:28 +03:00
vars := mux.Vars(r)
path := vars["path"]
ch := make(chan Get)
go func() { ch <- zk.GetNode(path) }()
childrens := <-ch
data, err := json.Marshal(childrens)
if err != nil {
w.WriteHeader(500)
2017-02-15 17:24:58 +03:00
w.Write([]byte("JSON parsing failure"))
return
2017-02-15 17:09:28 +03:00
}
2017-02-15 17:24:58 +03:00
if childrens.Error != "" {
w.WriteHeader(500)
w.Write(data)
return
}
2017-02-15 17:09:28 +03:00
w.WriteHeader(200)
w.Write(data)
}
// Serve ...
func Serve(listen string, zk ZooNode) {
r := mux.NewRouter()
r.HandleFunc("/v1/ls{path:[A-Za-z0-9-_/.:]+}", zk.LS)
r.HandleFunc("/v1/get{path:[A-Za-z0-9-_/.:]+}", zk.GET)
r.HandleFunc("/v1/rmr{path:[A-Za-z0-9-_/.:]+}", zk.RM)
r.HandleFunc("/v1/up{path:[A-Za-z0-9-_/.:]+}", zk.UP)
2017-02-15 17:09:28 +03:00
http.Handle("/", r)
srv := http.Server{
Handler: r,
Addr: listen,
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
log.Print("Listening API on ", listen)
log.Fatal(srv.ListenAndServe())
}