Implement optional namespace for server

master
Bel LaPointe 2019-03-20 10:00:19 -06:00
parent b6baf90dc4
commit 73423064a8
5 changed files with 55 additions and 21 deletions

View File

@ -0,0 +1,9 @@
a key goes to a consistent hash to determine a partition id. Look up the addr which holds that partition ID.
end:1 key -> client
client:1 key -> 1+ partitionID
client:1 partitionID -> serverAddr
client:partition,key,serverAddr -> server
server:partition,key -> value
1+ server:value -> client
client:1+ value -> 1 end:value

View File

@ -16,6 +16,7 @@ type Config struct {
Addr string
Username string
Password string
DefaultNamespace string
}
func Values() Config {

View File

@ -12,7 +12,9 @@ func New() error {
Username: orEnv("", "USER", "USERNAME"),
Password: orEnv("", "PASS", "PASSWORD"),
Port: orEnv("21412", "PORT", "LISTEN"),
DefaultNamespace: orEnv(storage.DefaultNamespace, "NS", "NAMESPACE"),
}
storage.DefaultNamespace = config.DefaultNamespace
DB, err := storage.New(storage.TypeFromString(config.db), config.Addr, config.Username, config.Password)
config.DB = DB
return err

View File

@ -6,17 +6,26 @@ import (
"local/s2sa/s2sa/server/router"
"local/storage"
"net/http"
"path"
"strings"
)
func (s *Server) Routes() error {
if err := s.router.Add("/"+router.Wildcard, s.CatchAll); err != nil {
if err := s.router.Add("/"+router.Wildcard, s.SimpleCatchAll); err != nil {
return err
}
if err := s.router.Add("/"+router.Wildcard+"/"+router.Wildcard, s.NSCatchAll); err != nil {
return err
}
return nil
}
func (s *Server) CatchAll(w http.ResponseWriter, r *http.Request) {
func (s *Server) SimpleCatchAll(w http.ResponseWriter, r *http.Request) {
r.URL.Path = path.Join("/"+storage.DefaultNamespace, r.URL.Path)
s.NSCatchAll(w, r)
}
func (s *Server) NSCatchAll(w http.ResponseWriter, r *http.Request) {
foo := http.NotFound
switch strings.ToLower(r.Method) {
case "get":
@ -30,9 +39,10 @@ func (s *Server) CatchAll(w http.ResponseWriter, r *http.Request) {
}
func (s *Server) get(w http.ResponseWriter, r *http.Request) {
config := config.Values()
key := strings.Split(r.URL.Path, "/")[1]
if value, err := config.DB.Get(key); err == storage.ErrNotFound {
db := config.Values().DB
ns := strings.Split(r.URL.Path, "/")[1]
key := strings.Split(r.URL.Path, "/")[2]
if value, err := db.Get(key, ns); err == storage.ErrNotFound {
w.WriteHeader(http.StatusNotFound)
return
} else if err != nil {
@ -44,8 +54,9 @@ func (s *Server) get(w http.ResponseWriter, r *http.Request) {
}
func (s *Server) put(w http.ResponseWriter, r *http.Request) {
config := config.Values()
key := strings.Split(r.URL.Path, "/")[1]
db := config.Values().DB
ns := strings.Split(r.URL.Path, "/")[1]
key := strings.Split(r.URL.Path, "/")[2]
if r == nil || r.Body == nil {
w.WriteHeader(http.StatusBadRequest)
return
@ -55,7 +66,7 @@ func (s *Server) put(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusBadRequest)
return
}
if err := config.DB.Set(key, value); err != nil {
if err := db.Set(key, value, ns); err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}

View File

@ -10,6 +10,7 @@ import (
"testing"
)
var validNS = "ns"
var validKey = "key"
var validValue = "value"
@ -112,7 +113,7 @@ func TestPutGet(t *testing.T) {
}
w := httptest.NewRecorder()
r, err := http.NewRequest("PUT", "/"+validKey, strings.NewReader(validValue))
r, err := http.NewRequest("PUT", "/"+validNS+"/"+validKey, strings.NewReader(validValue))
if err != nil {
t.Fatalf("err making put request: %v", err)
}
@ -122,7 +123,17 @@ func TestPutGet(t *testing.T) {
}
w = httptest.NewRecorder()
r, err = http.NewRequest("GET", "/"+validKey, nil)
r, err = http.NewRequest("GET", "/not_"+validNS+"/"+validKey, nil)
if err != nil {
t.Fatalf("err making get request: %v", err)
}
s.get(w, r)
if w.Code != http.StatusNotFound {
t.Fatalf("err status on bad get: %v", w.Code)
}
w = httptest.NewRecorder()
r, err = http.NewRequest("GET", "/"+validNS+"/"+validKey, nil)
if err != nil {
t.Fatalf("err making get request: %v", err)
}