camlistored: convert ui, root, jsonsign to use handler registry

This commit is contained in:
Brad Fitzpatrick 2011-05-26 07:34:39 -07:00
parent 9ad7346474
commit 4317da0308
5 changed files with 46 additions and 29 deletions

View File

@ -27,6 +27,8 @@ import (
type Loader interface {
GetStorage(prefix string) (Storage, os.Error)
GetHandler(prefix string) (http.Handler, os.Error)
GetHandlerType(prefix string) string // or ""
}
type StorageConstructor func(Loader, jsonconfig.Obj) (Storage, os.Error)

View File

@ -270,6 +270,19 @@ func (hl *handlerLoader) GetStorage(prefix string) (blobserver.Storage, os.Error
return nil, fmt.Errorf("bogus storage handler referenced as %q", prefix)
}
func (hl *handlerLoader) GetHandler(prefix string) (http.Handler, os.Error) {
hl.setupHandler(prefix)
if h, ok := hl.handler[prefix].(http.Handler); ok {
return h, nil
}
return nil, fmt.Errorf("bogus http handler referenced as %q", prefix)
}
func (hl *handlerLoader) GetHandlerType(prefix string) string {
hl.setupHandler(prefix)
return hl.configType(prefix)
}
func (hl *handlerLoader) setupHandler(prefix string) {
h, ok := hl.config[prefix]
if !ok {
@ -290,28 +303,21 @@ func (hl *handlerLoader) setupHandler(prefix string) {
panic(fmt.Sprintf("setupHandler for %q didn't install a handler", prefix))
}
}()
installHandler := func(creator func(*handlerLoader, jsonconfig.Obj) (h http.Handler, err os.Error)) {
hh, err := creator(hl, h.conf)
if err != nil {
exitFailure("error instantiating handler for prefix %s: %v",
prefix, err)
}
hl.handler[prefix] = hh
hl.ws.Handle(prefix, &httputil.PrefixHandler{prefix, hh})
}
checkConfig := func() {
if err := h.conf.Validate(); err != nil {
exitFailure("configuration error in \"handlerArgs\" for prefix %s: %v", prefix, err)
}
}
switch h.htype {
case "root":
installHandler((*handlerLoader).createRootHandler)
case "ui":
installHandler((*handlerLoader).createUIHandler)
case "jsonsign":
installHandler((*handlerLoader).createJSONSignHandler)
case "search":
case "ui", "root", "jsonsign":
hh, err := blobserver.CreateHandler(h.htype, hl, h.conf)
if err != nil {
exitFailure("error instantiating handler for prefix %q, type %q: %v",
h.prefix, h.htype, err)
}
hl.handler[prefix] = hh
hl.ws.Handle(prefix, &httputil.PrefixHandler{prefix, hh})
case "search": // TODO: use blobserver registry
indexPrefix := h.conf.RequiredString("index") // TODO: add optional help tips here?
ownerBlobStr := h.conf.RequiredString("owner")
checkConfig()
@ -327,7 +333,7 @@ func (hl *handlerLoader) setupHandler(prefix string) {
searchh := auth.RequireAuth(search.CreateHandler(indexer, ownerBlobRef))
hl.handler[h.prefix] = searchh
hl.ws.HandleFunc(prefix+"camli/", searchh)
case "sync":
case "sync": // TODO: use blobserver registry
from := h.conf.RequiredString("from")
to := h.conf.RequiredString("to")
checkConfig()

View File

@ -21,6 +21,7 @@ import (
"http"
"os"
"camli/blobserver"
"camli/jsonconfig"
)
@ -34,7 +35,11 @@ type RootHandler struct {
OfferSetup bool
}
func (hl *handlerLoader) createRootHandler(conf jsonconfig.Obj) (h http.Handler, err os.Error) {
func init() {
blobserver.RegisterHandlerConstructor("root", newRootFromConfig)
}
func newRootFromConfig(ld blobserver.Loader, conf jsonconfig.Obj) (h http.Handler, err os.Error) {
root := &RootHandler{}
root.Stealth = conf.OptionalBool("stealth", false)
if err = conf.Validate(); err != nil {

View File

@ -29,6 +29,7 @@ import (
"strings"
"camli/blobref"
"camli/blobserver"
"camli/blobserver/handlers"
"camli/httputil"
"camli/jsonconfig"
@ -63,7 +64,11 @@ func (h *JSONSignHandler) secretRingPath() string {
return filepath.Join(os.Getenv("HOME"), ".gnupg", "secring.gog")
}
func (hl *handlerLoader) createJSONSignHandler(conf jsonconfig.Obj) (http.Handler, os.Error) {
func init() {
blobserver.RegisterHandlerConstructor("jsonsign", newJsonSignFromConfig)
}
func newJsonSignFromConfig(ld blobserver.Loader, conf jsonconfig.Obj) (http.Handler, os.Error) {
h := &JSONSignHandler{
keyId: strings.ToUpper(conf.RequiredString("keyId")),
secretRing: conf.OptionalString("secretRing", ""),

View File

@ -53,7 +53,11 @@ func defaultFilesDir() string {
return filepath.Join(dir, "ui")
}
func (hl *handlerLoader) createUIHandler(conf jsonconfig.Obj) (h http.Handler, err os.Error) {
func init() {
blobserver.RegisterHandlerConstructor("ui", newUiFromConfig)
}
func newUiFromConfig(ld blobserver.Loader, conf jsonconfig.Obj) (h http.Handler, err os.Error) {
ui := &UIHandler{}
ui.BlobRoot = conf.OptionalString("blobRoot", "")
ui.SearchRoot = conf.OptionalString("searchRoot", "")
@ -68,7 +72,7 @@ func (hl *handlerLoader) createUIHandler(conf jsonconfig.Obj) (h http.Handler, e
if v == "" {
return
}
ct := hl.configType(v)
ct := ld.GetHandlerType(v)
if ct == "" {
err = fmt.Errorf("UI handler's %q references non-existant %q", key, v)
} else if ct != htype {
@ -83,14 +87,9 @@ func (hl *handlerLoader) createUIHandler(conf jsonconfig.Obj) (h http.Handler, e
}
if ui.BlobRoot != "" {
bh := hl.getOrSetup(ui.BlobRoot)
if bh == nil {
return nil, fmt.Errorf("UI handler's blobRoot references non-existant %q", ui.BlobRoot)
}
_, ok := bh.(blobserver.Storage)
if !ok {
return nil, fmt.Errorf("UI handler's blobRoot references %q of type %T; expected a storage target",
ui.BlobRoot, bh)
_, err := ld.GetStorage(ui.BlobRoot)
if err != nil {
return nil, fmt.Errorf("UI handler's blobRoot of %q error: %v", ui.BlobRoot, err)
}
}