Docs and minor cleanups

Change-Id: Ibf1d69c21f53cf4b5b576a0dfefa5d0e7b26264d
This commit is contained in:
Brad Fitzpatrick 2013-07-07 16:09:17 -07:00
parent 466dfcdc59
commit 62ad21ff2e
15 changed files with 102 additions and 19 deletions

1
TESTS
View File

@ -3,3 +3,4 @@ Tests needed
-cmd/camput/
-verify that stat caching works. verify that -filenodes does create the permanode even if the file was already uploaded (and cached) in a previous run.
-- blobserver/cond has no tests.

View File

@ -1,5 +1,11 @@
// +build THIS_IS_BROKEN
// The camwebdav binary is a WebDAV server to expose Camlistore as a
// filesystem that can be mounted from Windows (or other operating
// systems).
//
// It is currently broken and needs to be updated to use
// camlistore.org/pkg/fs.
package main
import (

View File

@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package atomics provides atomic types.
package atomics
import (

View File

@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package auth implements Camlistore authentication.
package auth
import (

View File

@ -14,6 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package blobref provides the BlobRef type and associate types and parsers.
// A blobref is the immutable reference to an individual blob.
package blobref
import (

View File

@ -14,6 +14,27 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Package cond registers the "cond" conditional blobserver storage type
to select routing of get/put operations on blobs to other storage
targets as a function of their content.
Currently only the "isSchema" predicate is defined.
Example usage:
"/bs-and-maybe-also-index/": {
"handler": "storage-cond",
"handlerArgs": {
"write": {
"if": "isSchema",
"then": "/bs-and-index/",
"else": "/bs/"
},
"read": "/bs/"
}
}
*/
package cond
import (

18
pkg/blobserver/doc.go Normal file
View File

@ -0,0 +1,18 @@
/*
Copyright 2013 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package blobserver defines how raw blobs are stored and accessed.
package blobserver

View File

@ -14,6 +14,19 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package encrypt registers the "encrypt" blobserver storage type
// which stores all blobs and metadata with AES encryption into other
// wrapped storage targets (e.g. localdisk, s3, remote, google).
//
// An encrypt storage target is configured with two other storage targets:
// one to hold encrypted blobs, and one to hold encrypted metadata about
// the encrypted blobs. On start-up, all the metadata blobs are read
// to discover the plaintext blobrefs.
//
// Encryption is currently always AES-128. See code for metadata formats
// and configuration details, which are currently subject to change.
//
// WARNING: work in progress as of 2013-07-13.
package encrypt
import (

View File

@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package gethandler implements the HTTP handler for fetching blobs.
package gethandler
import (
@ -38,19 +39,18 @@ type Handler struct {
Fetcher blobref.StreamingFetcher
}
func CreateGetHandler(fetcher blobref.StreamingFetcher) func(http.ResponseWriter, *http.Request) {
gh := &Handler{Fetcher: fetcher}
return func(conn http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/camli/sha1-deadbeef00000000000000000000000000000000" {
// Test handler.
simulatePrematurelyClosedConnection(conn, req)
return
}
gh.ServeHTTP(conn, req)
}
// CreateGetHandler returns an http Handler for serving blobs from fetcher.1
func CreateGetHandler(fetcher blobref.StreamingFetcher) http.Handler {
return &Handler{Fetcher: fetcher}
}
func (h *Handler) ServeHTTP(conn http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/camli/sha1-deadbeef00000000000000000000000000000000" {
// Test handler.
simulatePrematurelyClosedConnection(conn, req)
return
}
blobRef := blobFromUrlPath(req.URL.Path)
if blobRef == nil {
http.Error(conn, "Malformed GET URL.", 400)

View File

@ -163,18 +163,20 @@ type Generationer interface {
ResetStorageGeneration() error
}
// Storage is the interface that must be implemented by a blobserver
// storage type. (e.g. localdisk, s3, encrypt, shard, replica, remote)
type Storage interface {
blobref.StreamingFetcher
BlobReceiver
BlobStatter
BlobEnumerator
// Remove 0 or more blobs. Removal of non-existent items
// isn't an error. Returns failure if any items existed but
// failed to be deleted.
// RemoveBlobs removes 0 or more blobs. Removal of
// non-existent items isn't an error. Returns failure if any
// items existed but failed to be deleted.
RemoveBlobs(blobs []*blobref.BlobRef) error
// Returns the blob notification bus
// GetBlobHub returns the blob notification bus.
GetBlobHub() BlobHub
}

View File

@ -25,8 +25,9 @@ import (
"camlistore.org/pkg/blobref"
)
type NoImplStorage struct {
}
// NoImplStorage is an implementation of Storage that return a not
// implemented error for all operations.
type NoImplStorage struct{}
var _ Storage = (*NoImplStorage)(nil)

View File

@ -69,7 +69,12 @@ type Loader interface {
GetRequestContext() (ctx *http.Request, ok bool)
}
// A StorageConstructor returns a Storage implementation from a Loader
// environment and a configuration.
type StorageConstructor func(Loader, jsonconfig.Obj) (Storage, error)
// A HandlerConstructor returns an http.Handler from a Loader
// environment and a configuration.
type HandlerConstructor func(Loader, jsonconfig.Obj) (http.Handler, error)
var mapLock sync.Mutex
@ -95,6 +100,10 @@ func CreateStorage(typ string, loader Loader, config jsonconfig.Obj) (Storage, e
return ctor(loader, config)
}
// RegisterHandlerConstructor registers an http Handler constructor function
// for a given handler type.
//
// It is an error to register the same handler type twice.
func RegisterHandlerConstructor(typ string, ctor HandlerConstructor) {
mapLock.Lock()
defer mapLock.Unlock()
@ -104,6 +113,12 @@ func RegisterHandlerConstructor(typ string, ctor HandlerConstructor) {
handlerConstructors[typ] = ctor
}
// CreateHandler instantiates an http Handler of type 'typ' from the
// provided JSON configuration, and finding peer handlers and
// configuration from the environment in 'loader'.
//
// The handler 'typ' must have bee previously registered with
// RegisterHandlerConstructor.
func CreateHandler(typ string, loader Loader, config jsonconfig.Obj) (http.Handler, error) {
mapLock.Lock()
ctor, ok := handlerConstructors[typ]

View File

@ -15,8 +15,7 @@ limitations under the License.
*/
/*
Package index provides a generic indexing system on top of an abstract
index storage system (Storage).
Package index provides a generic indexing system on top of the abstract Storage interface.
The following keys & values are populated by receiving blobs and queried
for search operations:

View File

@ -34,6 +34,9 @@ import (
var ErrNotFound = errors.New("index: key not found")
// Storage is the minimal interface that must be implemented by index
// storage implementations. (e.g. mysql, postgres, mongo, sqlite,
// leveldb, dynamo)
type Storage interface {
// Get gets the value for the given key. It returns ErrNotFound if the DB
// does not contain the key.

View File

@ -120,7 +120,7 @@ func camliHandlerUsingStorage(req *http.Request, action string, storage blobserv
case "stat":
handler = handlers.CreateStatHandler(storage)
default:
handler = gethandler.CreateGetHandler(storage)
handler = gethandler.CreateGetHandler(storage).ServeHTTP
op = auth.OpGet
}
case "POST":