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 Addr string
Username string Username string
Password string Password string
DefaultNamespace string
} }
func Values() Config { func Values() Config {

View File

@ -12,7 +12,9 @@ func New() error {
Username: orEnv("", "USER", "USERNAME"), Username: orEnv("", "USER", "USERNAME"),
Password: orEnv("", "PASS", "PASSWORD"), Password: orEnv("", "PASS", "PASSWORD"),
Port: orEnv("21412", "PORT", "LISTEN"), 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) DB, err := storage.New(storage.TypeFromString(config.db), config.Addr, config.Username, config.Password)
config.DB = DB config.DB = DB
return err return err

View File

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

View File

@ -10,6 +10,7 @@ import (
"testing" "testing"
) )
var validNS = "ns"
var validKey = "key" var validKey = "key"
var validValue = "value" var validValue = "value"
@ -112,7 +113,7 @@ func TestPutGet(t *testing.T) {
} }
w := httptest.NewRecorder() 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 { if err != nil {
t.Fatalf("err making put request: %v", err) t.Fatalf("err making put request: %v", err)
} }
@ -122,7 +123,17 @@ func TestPutGet(t *testing.T) {
} }
w = httptest.NewRecorder() 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 { if err != nil {
t.Fatalf("err making get request: %v", err) t.Fatalf("err making get request: %v", err)
} }