Merge pull request #795 from harshavardhana/pr_out_probe_revamped_to_provide_for_a_new_wrappederror_struct_to_wrap_probes_as_error_interface

Probe revamped to provide for a new WrappedError struct to wrap probes as error interface
This commit is contained in:
Harshavardhana 2015-08-08 00:23:36 -07:00
commit b4c8b4877e
34 changed files with 392 additions and 363 deletions

View file

@ -29,27 +29,27 @@ import (
func isUsable(mountPath string) (bool, *probe.Error) {
mntpoint, err := os.Stat(mountPath)
if err != nil {
return false, probe.New(err)
return false, probe.NewError(err)
}
parent, err := os.Stat("/")
if err != nil {
return false, probe.New(err)
return false, probe.NewError(err)
}
mntpointSt := mntpoint.Sys().(*syscall.Stat_t)
parentSt := parent.Sys().(*syscall.Stat_t)
if mntpointSt.Dev == parentSt.Dev {
return false, probe.New(fmt.Errorf("Not mounted %s", mountPath))
return false, probe.NewError(fmt.Errorf("Not mounted %s", mountPath))
}
testFile, err := ioutil.TempFile(mountPath, "writetest-")
if err != nil {
return false, probe.New(err)
return false, probe.NewError(err)
}
// close the file, to avoid leaky fd's
defer testFile.Close()
testFileName := testFile.Name()
if err := os.Remove(testFileName); err != nil {
return false, probe.New(err)
return false, probe.NewError(err)
}
return true, nil
}

View file

@ -32,7 +32,7 @@ func GenerateAccessKeyID() ([]byte, *probe.Error) {
alpha := make([]byte, MinioAccessID)
_, err := rand.Read(alpha)
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
for i := 0; i < MinioAccessID; i++ {
alpha[i] = alphaNumericTable[alpha[i]%byte(len(alphaNumericTable))]
@ -45,7 +45,7 @@ func GenerateSecretAccessKey() ([]byte, *probe.Error) {
rb := make([]byte, MinioSecretID)
_, err := rand.Read(rb)
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
return []byte(base64.StdEncoding.EncodeToString(rb))[:MinioSecretID], nil
}

View file

@ -44,7 +44,7 @@ func getAuthConfigPath() (string, *probe.Error) {
}
u, err := user.Current()
if err != nil {
return "", probe.New(err)
return "", probe.NewError(err)
}
authConfigPath := filepath.Join(u.HomeDir, ".minio", "users.json")
return authConfigPath, nil

View file

@ -38,74 +38,70 @@ func GetMemStats(url string) ([]byte, *probe.Error) {
Method: "MemStats.Get",
Request: rpc.Args{Request: ""},
}
req, err := NewRequest(url, op, http.DefaultTransport)
if err != nil {
return nil, err.Trace()
req, perr := NewRequest(url, op, http.DefaultTransport)
if perr != nil {
return nil, perr.Trace()
}
resp, err := req.Do()
resp, perr := req.Do()
defer closeResp(resp)
if err != nil {
return nil, err.Trace()
if perr != nil {
return nil, perr.Trace()
}
var reply rpc.MemStatsReply
if err := jsonrpc.DecodeClientResponse(resp.Body, &reply); err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
{
jsonRespBytes, err := json.MarshalIndent(reply, "", "\t")
if err != nil {
return nil, probe.New(err)
}
return jsonRespBytes, nil
jsonRespBytes, err := json.MarshalIndent(reply, "", "\t")
if err != nil {
return nil, probe.NewError(err)
}
return jsonRespBytes, nil
}
// GetSysInfo get system status of the server at given url
func GetSysInfo(url string) ([]byte, error) {
func GetSysInfo(url string) ([]byte, *probe.Error) {
op := RPCOps{
Method: "SysInfo.Get",
Request: rpc.Args{Request: ""},
}
req, err := NewRequest(url, op, http.DefaultTransport)
if err != nil {
return nil, err.Trace()
req, perr := NewRequest(url, op, http.DefaultTransport)
if perr != nil {
return nil, perr.Trace()
}
resp, err := req.Do()
resp, perr := req.Do()
defer closeResp(resp)
if err != nil {
return nil, err.Trace()
if perr != nil {
return nil, perr.Trace()
}
var reply rpc.SysInfoReply
if err := jsonrpc.DecodeClientResponse(resp.Body, &reply); err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
{
jsonRespBytes, err := json.MarshalIndent(reply, "", "\t")
if err != nil {
return nil, probe.New(err)
}
return jsonRespBytes, nil
jsonRespBytes, err := json.MarshalIndent(reply, "", "\t")
if err != nil {
return nil, probe.NewError(err)
}
return jsonRespBytes, nil
}
// GetAuthKeys get access key id and secret access key
func GetAuthKeys(url string) ([]byte, error) {
func GetAuthKeys(url string) ([]byte, *probe.Error) {
op := RPCOps{
Method: "Auth.Get",
Request: rpc.Args{Request: ""},
}
req, err := NewRequest(url, op, http.DefaultTransport)
if err != nil {
return nil, err.Trace()
req, perr := NewRequest(url, op, http.DefaultTransport)
if perr != nil {
return nil, perr.Trace()
}
resp, err := req.Do()
resp, perr := req.Do()
defer closeResp(resp)
if err != nil {
return nil, err.Trace()
if perr != nil {
return nil, perr.Trace()
}
var reply rpc.AuthReply
if err := jsonrpc.DecodeClientResponse(resp.Body, &reply); err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
authConfig := &auth.Config{}
authConfig.Version = "0.0.1"
@ -118,13 +114,11 @@ func GetAuthKeys(url string) ([]byte, error) {
if err := auth.SaveConfig(authConfig); err != nil {
return nil, err.Trace()
}
{
jsonRespBytes, err := json.MarshalIndent(reply, "", "\t")
if err != nil {
return nil, probe.New(err)
}
return jsonRespBytes, nil
jsonRespBytes, err := json.MarshalIndent(reply, "", "\t")
if err != nil {
return nil, probe.NewError(err)
}
return jsonRespBytes, nil
}
// Add more functions here for other RPC messages

View file

@ -40,11 +40,11 @@ type RPCRequest struct {
func NewRequest(url string, op RPCOps, transport http.RoundTripper) (*RPCRequest, *probe.Error) {
params, err := json.EncodeClientRequest(op.Method, op.Request)
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
req, err := http.NewRequest("POST", url, bytes.NewReader(params))
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
rpcReq := &RPCRequest{}
rpcReq.req = req
@ -60,7 +60,10 @@ func NewRequest(url string, op RPCOps, transport http.RoundTripper) (*RPCRequest
func (r RPCRequest) Do() (*http.Response, *probe.Error) {
resp, err := r.transport.RoundTrip(r.req)
if err != nil {
return nil, probe.New(err)
if werr, ok := probe.ToWrappedError(err); ok {
return nil, werr.ToError().Trace()
}
return nil, probe.NewError(err)
}
return resp, nil
}

View file

@ -54,7 +54,7 @@ type bucket struct {
// newBucket - instantiate a new bucket
func newBucket(bucketName, aclType, donutName string, nodes map[string]node) (bucket, BucketMetadata, *probe.Error) {
if strings.TrimSpace(bucketName) == "" || strings.TrimSpace(donutName) == "" {
return bucket{}, BucketMetadata{}, probe.New(InvalidArgument{})
return bucket{}, BucketMetadata{}, probe.NewError(InvalidArgument{})
}
b := bucket{}
@ -128,7 +128,7 @@ func (b bucket) getBucketMetadata() (*AllBuckets, *probe.Error) {
return metadata, nil
}
}
return nil, probe.New(err)
return nil, probe.NewError(err)
}
// GetObjectMetadata - get metadata for an object
@ -223,7 +223,7 @@ func (b bucket) ReadObject(objectName string) (reader io.ReadCloser, size int64,
}
// check if object exists
if _, ok := bucketMetadata.Buckets[b.getBucketName()].BucketObjects[objectName]; !ok {
return nil, 0, probe.New(ObjectNotFound{Object: objectName})
return nil, 0, probe.NewError(ObjectNotFound{Object: objectName})
}
objMetadata, err := b.readObjectMetadata(normalizeObjectName(objectName))
if err != nil {
@ -239,7 +239,7 @@ func (b bucket) WriteObject(objectName string, objectData io.Reader, size int64,
b.lock.Lock()
defer b.lock.Unlock()
if objectName == "" || objectData == nil {
return ObjectMetadata{}, probe.New(InvalidArgument{})
return ObjectMetadata{}, probe.NewError(InvalidArgument{})
}
writers, err := b.getObjectWriters(normalizeObjectName(objectName), "data")
if err != nil {
@ -266,7 +266,7 @@ func (b bucket) WriteObject(objectName string, objectData io.Reader, size int64,
totalLength, err := io.Copy(mw, objectData)
if err != nil {
CleanupWritersOnError(writers)
return ObjectMetadata{}, probe.New(err)
return ObjectMetadata{}, probe.NewError(err)
}
objMetadata.Size = totalLength
case false:
@ -306,7 +306,7 @@ func (b bucket) WriteObject(objectName string, objectData io.Reader, size int64,
//
// Signature mismatch occurred all temp files to be removed and all data purged.
CleanupWritersOnError(writers)
return ObjectMetadata{}, probe.New(SignatureDoesNotMatch{})
return ObjectMetadata{}, probe.NewError(SignatureDoesNotMatch{})
}
}
objMetadata.MD5Sum = hex.EncodeToString(dataMD5sum)
@ -337,24 +337,24 @@ func (b bucket) isMD5SumEqual(expectedMD5Sum, actualMD5Sum string) *probe.Error
if strings.TrimSpace(expectedMD5Sum) != "" && strings.TrimSpace(actualMD5Sum) != "" {
expectedMD5SumBytes, err := hex.DecodeString(expectedMD5Sum)
if err != nil {
return probe.New(err)
return probe.NewError(err)
}
actualMD5SumBytes, err := hex.DecodeString(actualMD5Sum)
if err != nil {
return probe.New(err)
return probe.NewError(err)
}
if !bytes.Equal(expectedMD5SumBytes, actualMD5SumBytes) {
return probe.New(BadDigest{})
return probe.NewError(BadDigest{})
}
return nil
}
return probe.New(InvalidArgument{})
return probe.NewError(InvalidArgument{})
}
// writeObjectMetadata - write additional object metadata
func (b bucket) writeObjectMetadata(objectName string, objMetadata ObjectMetadata) *probe.Error {
if objMetadata.Object == "" {
return probe.New(InvalidArgument{})
return probe.NewError(InvalidArgument{})
}
objMetadataWriters, err := b.getObjectWriters(objectName, objectMetadataConfig)
if err != nil {
@ -365,7 +365,7 @@ func (b bucket) writeObjectMetadata(objectName string, objMetadata ObjectMetadat
if err := jenc.Encode(&objMetadata); err != nil {
// Close writers and purge all temporary entries
CleanupWritersOnError(objMetadataWriters)
return probe.New(err)
return probe.NewError(err)
}
}
for _, objMetadataWriter := range objMetadataWriters {
@ -377,7 +377,7 @@ func (b bucket) writeObjectMetadata(objectName string, objMetadata ObjectMetadat
// readObjectMetadata - read object metadata
func (b bucket) readObjectMetadata(objectName string) (ObjectMetadata, *probe.Error) {
if objectName == "" {
return ObjectMetadata{}, probe.New(InvalidArgument{})
return ObjectMetadata{}, probe.NewError(InvalidArgument{})
}
objMetadata := ObjectMetadata{}
objMetadataReaders, err := b.getObjectReaders(objectName, objectMetadataConfig)
@ -395,7 +395,7 @@ func (b bucket) readObjectMetadata(objectName string) (ObjectMetadata, *probe.Er
return objMetadata, nil
}
}
return ObjectMetadata{}, probe.New(err)
return ObjectMetadata{}, probe.NewError(err)
}
}
@ -415,12 +415,12 @@ func normalizeObjectName(objectName string) string {
// getDataAndParity - calculate k, m (data and parity) values from number of disks
func (b bucket) getDataAndParity(totalWriters int) (k uint8, m uint8, err *probe.Error) {
if totalWriters <= 1 {
return 0, 0, probe.New(InvalidArgument{})
return 0, 0, probe.NewError(InvalidArgument{})
}
quotient := totalWriters / 2 // not using float or abs to let integer round off to lower value
// quotient cannot be bigger than (255 / 2) = 127
if quotient > 127 {
return 0, 0, probe.New(ParityOverflow{})
return 0, 0, probe.NewError(ParityOverflow{})
}
remainder := totalWriters % 2 // will be 1 for odd and 0 for even numbers
k = uint8(quotient + remainder)
@ -450,7 +450,7 @@ func (b bucket) writeObjectData(k, m uint8, writers []io.WriteCloser, objectData
return 0, 0, err.Trace()
}
if _, err := writer.Write(inputData); err != nil {
return 0, 0, probe.New(err)
return 0, 0, probe.NewError(err)
}
for blockIndex, block := range encodedBlocks {
errCh := make(chan error, 1)
@ -461,7 +461,7 @@ func (b bucket) writeObjectData(k, m uint8, writers []io.WriteCloser, objectData
}(writers[blockIndex], bytes.NewReader(block), errCh)
if err := <-errCh; err != nil {
// Returning error is fine here CleanupErrors() would cleanup writers
return 0, 0, probe.New(err)
return 0, 0, probe.NewError(err)
}
}
chunkCount = chunkCount + 1
@ -473,7 +473,7 @@ func (b bucket) writeObjectData(k, m uint8, writers []io.WriteCloser, objectData
func (b bucket) readObjectData(objectName string, writer *io.PipeWriter, objMetadata ObjectMetadata) {
readers, err := b.getObjectReaders(objectName, "data")
if err != nil {
writer.CloseWithError(err.Trace())
writer.CloseWithError(probe.NewWrappedError(err))
return
}
for _, reader := range readers {
@ -484,12 +484,12 @@ func (b bucket) readObjectData(objectName string, writer *io.PipeWriter, objMeta
var err error
expectedMd5sum, err = hex.DecodeString(objMetadata.MD5Sum)
if err != nil {
writer.CloseWithError(probe.New(err))
writer.CloseWithError(probe.NewWrappedError(probe.NewError(err)))
return
}
expected512Sum, err = hex.DecodeString(objMetadata.SHA512Sum)
if err != nil {
writer.CloseWithError(probe.New(err))
writer.CloseWithError(probe.NewWrappedError(probe.NewError(err)))
return
}
}
@ -499,23 +499,23 @@ func (b bucket) readObjectData(objectName string, writer *io.PipeWriter, objMeta
switch len(readers) > 1 {
case true:
if objMetadata.ErasureTechnique == "" {
writer.CloseWithError(probe.New(MissingErasureTechnique{}))
writer.CloseWithError(probe.NewWrappedError(probe.NewError(MissingErasureTechnique{})))
return
}
encoder, err := newEncoder(objMetadata.DataDisks, objMetadata.ParityDisks, objMetadata.ErasureTechnique)
if err != nil {
writer.CloseWithError(err.Trace())
writer.CloseWithError(probe.NewWrappedError(err))
return
}
totalLeft := objMetadata.Size
for i := 0; i < objMetadata.ChunkCount; i++ {
decodedData, err := b.decodeEncodedData(totalLeft, int64(objMetadata.BlockSize), readers, encoder, writer)
if err != nil {
writer.CloseWithError(err.Trace())
writer.CloseWithError(probe.NewWrappedError(err))
return
}
if _, err := io.Copy(mwriter, bytes.NewReader(decodedData)); err != nil {
writer.CloseWithError(probe.New(err))
writer.CloseWithError(probe.NewWrappedError(probe.NewError(err)))
return
}
totalLeft = totalLeft - int64(objMetadata.BlockSize)
@ -523,17 +523,17 @@ func (b bucket) readObjectData(objectName string, writer *io.PipeWriter, objMeta
case false:
_, err := io.Copy(writer, readers[0])
if err != nil {
writer.CloseWithError(probe.New(err))
writer.CloseWithError(probe.NewWrappedError(probe.NewError(err)))
return
}
}
// check if decodedData md5sum matches
if !bytes.Equal(expectedMd5sum, hasher.Sum(nil)) {
writer.CloseWithError(probe.New(ChecksumMismatch{}))
writer.CloseWithError(probe.NewWrappedError(probe.NewError(ChecksumMismatch{})))
return
}
if !bytes.Equal(expected512Sum, sum512hasher.Sum(nil)) {
writer.CloseWithError(probe.New(ChecksumMismatch{}))
writer.CloseWithError(probe.NewWrappedError(probe.NewError(ChecksumMismatch{})))
return
}
writer.Close()
@ -557,7 +557,7 @@ func (b bucket) decodeEncodedData(totalLeft, blockSize int64, readers map[int]io
var bytesBuffer bytes.Buffer
_, err := io.CopyN(&bytesBuffer, reader, int64(curChunkSize))
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
encodedBytes[i] = bytesBuffer.Bytes()
}

View file

@ -31,7 +31,7 @@ func getDonutConfigPath() (string, *probe.Error) {
}
u, err := user.Current()
if err != nil {
return "", probe.New(err)
return "", probe.NewError(err)
}
donutConfigPath := filepath.Join(u.HomeDir, ".minio", "donut.json")
return donutConfigPath, nil

View file

@ -39,20 +39,20 @@ type Disk struct {
// New - instantiate new disk
func New(diskPath string) (Disk, *probe.Error) {
if diskPath == "" {
return Disk{}, probe.New(InvalidArgument{})
return Disk{}, probe.NewError(InvalidArgument{})
}
st, err := os.Stat(diskPath)
if err != nil {
return Disk{}, probe.New(err)
return Disk{}, probe.NewError(err)
}
if !st.IsDir() {
return Disk{}, probe.New(syscall.ENOTDIR)
return Disk{}, probe.NewError(syscall.ENOTDIR)
}
s := syscall.Statfs_t{}
err = syscall.Statfs(diskPath, &s)
if err != nil {
return Disk{}, probe.New(err)
return Disk{}, probe.NewError(err)
}
disk := Disk{
lock: &sync.Mutex{},
@ -64,7 +64,7 @@ func New(diskPath string) (Disk, *probe.Error) {
disk.fsInfo["MountPoint"] = disk.path
return disk, nil
}
return Disk{}, probe.New(UnsupportedFilesystem{Type: strconv.FormatInt(int64(s.Type), 10)})
return Disk{}, probe.NewError(UnsupportedFilesystem{Type: strconv.FormatInt(int64(s.Type), 10)})
}
// IsUsable - is disk usable, alive
@ -103,7 +103,7 @@ func (disk Disk) MakeDir(dirname string) *probe.Error {
disk.lock.Lock()
defer disk.lock.Unlock()
if err := os.MkdirAll(filepath.Join(disk.path, dirname), 0700); err != nil {
return probe.New(err)
return probe.NewError(err)
}
return nil
}
@ -115,12 +115,12 @@ func (disk Disk) ListDir(dirname string) ([]os.FileInfo, *probe.Error) {
dir, err := os.Open(filepath.Join(disk.path, dirname))
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
defer dir.Close()
contents, err := dir.Readdir(-1)
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
var directories []os.FileInfo
for _, content := range contents {
@ -139,12 +139,12 @@ func (disk Disk) ListFiles(dirname string) ([]os.FileInfo, *probe.Error) {
dir, err := os.Open(filepath.Join(disk.path, dirname))
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
defer dir.Close()
contents, err := dir.Readdir(-1)
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
var files []os.FileInfo
for _, content := range contents {
@ -162,12 +162,12 @@ func (disk Disk) CreateFile(filename string) (*atomic.File, *probe.Error) {
defer disk.lock.Unlock()
if filename == "" {
return nil, probe.New(InvalidArgument{})
return nil, probe.NewError(InvalidArgument{})
}
f, err := atomic.FileCreate(filepath.Join(disk.path, filename))
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
return f, nil
@ -179,11 +179,11 @@ func (disk Disk) Open(filename string) (*os.File, *probe.Error) {
defer disk.lock.Unlock()
if filename == "" {
return nil, probe.New(InvalidArgument{})
return nil, probe.NewError(InvalidArgument{})
}
dataFile, err := os.Open(filepath.Join(disk.path, filename))
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
return dataFile, nil
}
@ -194,11 +194,11 @@ func (disk Disk) OpenFile(filename string, flags int, perm os.FileMode) (*os.Fil
defer disk.lock.Unlock()
if filename == "" {
return nil, probe.New(InvalidArgument{})
return nil, probe.NewError(InvalidArgument{})
}
dataFile, err := os.OpenFile(filepath.Join(disk.path, filename), flags, perm)
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
return dataFile, nil
}

View file

@ -38,8 +38,8 @@ func (s *MyDiskSuite) SetUpSuite(c *C) {
path, err := ioutil.TempDir(os.TempDir(), "disk-")
c.Assert(err, IsNil)
s.path = path
d, err := New(s.path)
c.Assert(err, IsNil)
d, perr := New(s.path)
c.Assert(perr, IsNil)
s.disk = d
}

View file

@ -54,7 +54,7 @@ const (
// makeBucket - make a new bucket
func (donut API) makeBucket(bucket string, acl BucketACL) *probe.Error {
if bucket == "" || strings.TrimSpace(bucket) == "" {
return probe.New(InvalidArgument{})
return probe.NewError(InvalidArgument{})
}
return donut.makeDonutBucket(bucket, acl.String())
}
@ -65,7 +65,7 @@ func (donut API) getBucketMetadata(bucketName string) (BucketMetadata, *probe.Er
return BucketMetadata{}, err.Trace()
}
if _, ok := donut.buckets[bucketName]; !ok {
return BucketMetadata{}, probe.New(BucketNotFound{Bucket: bucketName})
return BucketMetadata{}, probe.NewError(BucketNotFound{Bucket: bucketName})
}
metadata, err := donut.getDonutBucketMetadata()
if err != nil {
@ -86,7 +86,7 @@ func (donut API) setBucketMetadata(bucketName string, bucketMetadata map[string]
oldBucketMetadata := metadata.Buckets[bucketName]
acl, ok := bucketMetadata["acl"]
if !ok {
return probe.New(InvalidArgument{})
return probe.NewError(InvalidArgument{})
}
oldBucketMetadata.ACL = BucketACL(acl)
metadata.Buckets[bucketName] = oldBucketMetadata
@ -117,7 +117,7 @@ func (donut API) listObjects(bucket, prefix, marker, delimiter string, maxkeys i
return ListObjectsResults{}, err.Trace()
}
if _, ok := donut.buckets[bucket]; !ok {
return ListObjectsResults{}, probe.New(BucketNotFound{Bucket: bucket})
return ListObjectsResults{}, probe.NewError(BucketNotFound{Bucket: bucket})
}
listObjects, err := donut.buckets[bucket].ListObjects(prefix, marker, delimiter, maxkeys)
if err != nil {
@ -129,23 +129,23 @@ func (donut API) listObjects(bucket, prefix, marker, delimiter string, maxkeys i
// putObject - put object
func (donut API) putObject(bucket, object, expectedMD5Sum string, reader io.Reader, size int64, metadata map[string]string, signature *Signature) (ObjectMetadata, *probe.Error) {
if bucket == "" || strings.TrimSpace(bucket) == "" {
return ObjectMetadata{}, probe.New(InvalidArgument{})
return ObjectMetadata{}, probe.NewError(InvalidArgument{})
}
if object == "" || strings.TrimSpace(object) == "" {
return ObjectMetadata{}, probe.New(InvalidArgument{})
return ObjectMetadata{}, probe.NewError(InvalidArgument{})
}
if err := donut.listDonutBuckets(); err != nil {
return ObjectMetadata{}, err.Trace()
}
if _, ok := donut.buckets[bucket]; !ok {
return ObjectMetadata{}, probe.New(BucketNotFound{Bucket: bucket})
return ObjectMetadata{}, probe.NewError(BucketNotFound{Bucket: bucket})
}
bucketMeta, err := donut.getDonutBucketMetadata()
if err != nil {
return ObjectMetadata{}, err.Trace()
}
if _, ok := bucketMeta.Buckets[bucket].BucketObjects[object]; ok {
return ObjectMetadata{}, probe.New(ObjectExists{Object: object})
return ObjectMetadata{}, probe.NewError(ObjectExists{Object: object})
}
objMetadata, err := donut.buckets[bucket].WriteObject(object, reader, size, expectedMD5Sum, metadata, signature)
if err != nil {
@ -161,26 +161,26 @@ func (donut API) putObject(bucket, object, expectedMD5Sum string, reader io.Read
// putObject - put object
func (donut API) putObjectPart(bucket, object, expectedMD5Sum, uploadID string, partID int, reader io.Reader, size int64, metadata map[string]string, signature *Signature) (PartMetadata, *probe.Error) {
if bucket == "" || strings.TrimSpace(bucket) == "" {
return PartMetadata{}, probe.New(InvalidArgument{})
return PartMetadata{}, probe.NewError(InvalidArgument{})
}
if object == "" || strings.TrimSpace(object) == "" {
return PartMetadata{}, probe.New(InvalidArgument{})
return PartMetadata{}, probe.NewError(InvalidArgument{})
}
if err := donut.listDonutBuckets(); err != nil {
return PartMetadata{}, err.Trace()
}
if _, ok := donut.buckets[bucket]; !ok {
return PartMetadata{}, probe.New(BucketNotFound{Bucket: bucket})
return PartMetadata{}, probe.NewError(BucketNotFound{Bucket: bucket})
}
bucketMeta, err := donut.getDonutBucketMetadata()
if err != nil {
return PartMetadata{}, err.Trace()
}
if _, ok := bucketMeta.Buckets[bucket].Multiparts[object]; !ok {
return PartMetadata{}, probe.New(InvalidUploadID{UploadID: uploadID})
return PartMetadata{}, probe.NewError(InvalidUploadID{UploadID: uploadID})
}
if _, ok := bucketMeta.Buckets[bucket].BucketObjects[object]; ok {
return PartMetadata{}, probe.New(ObjectExists{Object: object})
return PartMetadata{}, probe.NewError(ObjectExists{Object: object})
}
objectPart := object + "/" + "multipart" + "/" + strconv.Itoa(partID)
objmetadata, err := donut.buckets[bucket].WriteObject(objectPart, reader, size, expectedMD5Sum, metadata, signature)
@ -205,16 +205,16 @@ func (donut API) putObjectPart(bucket, object, expectedMD5Sum, uploadID string,
// getObject - get object
func (donut API) getObject(bucket, object string) (reader io.ReadCloser, size int64, err *probe.Error) {
if bucket == "" || strings.TrimSpace(bucket) == "" {
return nil, 0, probe.New(InvalidArgument{})
return nil, 0, probe.NewError(InvalidArgument{})
}
if object == "" || strings.TrimSpace(object) == "" {
return nil, 0, probe.New(InvalidArgument{})
return nil, 0, probe.NewError(InvalidArgument{})
}
if err := donut.listDonutBuckets(); err != nil {
return nil, 0, err.Trace()
}
if _, ok := donut.buckets[bucket]; !ok {
return nil, 0, probe.New(BucketNotFound{Bucket: bucket})
return nil, 0, probe.NewError(BucketNotFound{Bucket: bucket})
}
return donut.buckets[bucket].ReadObject(object)
}
@ -225,14 +225,14 @@ func (donut API) getObjectMetadata(bucket, object string) (ObjectMetadata, *prob
return ObjectMetadata{}, err.Trace()
}
if _, ok := donut.buckets[bucket]; !ok {
return ObjectMetadata{}, probe.New(BucketNotFound{Bucket: bucket})
return ObjectMetadata{}, probe.NewError(BucketNotFound{Bucket: bucket})
}
bucketMeta, err := donut.getDonutBucketMetadata()
if err != nil {
return ObjectMetadata{}, err.Trace()
}
if _, ok := bucketMeta.Buckets[bucket].BucketObjects[object]; !ok {
return ObjectMetadata{}, probe.New(ObjectNotFound{Object: object})
return ObjectMetadata{}, probe.NewError(ObjectNotFound{Object: object})
}
objectMetadata, err := donut.buckets[bucket].GetObjectMetadata(object)
if err != nil {
@ -247,7 +247,7 @@ func (donut API) newMultipartUpload(bucket, object, contentType string) (string,
return "", err.Trace()
}
if _, ok := donut.buckets[bucket]; !ok {
return "", probe.New(BucketNotFound{Bucket: bucket})
return "", probe.NewError(BucketNotFound{Bucket: bucket})
}
allbuckets, err := donut.getDonutBucketMetadata()
if err != nil {
@ -283,16 +283,16 @@ func (donut API) newMultipartUpload(bucket, object, contentType string) (string,
// listObjectParts list all object parts
func (donut API) listObjectParts(bucket, object string, resources ObjectResourcesMetadata) (ObjectResourcesMetadata, *probe.Error) {
if bucket == "" || strings.TrimSpace(bucket) == "" {
return ObjectResourcesMetadata{}, probe.New(InvalidArgument{})
return ObjectResourcesMetadata{}, probe.NewError(InvalidArgument{})
}
if object == "" || strings.TrimSpace(object) == "" {
return ObjectResourcesMetadata{}, probe.New(InvalidArgument{})
return ObjectResourcesMetadata{}, probe.NewError(InvalidArgument{})
}
if err := donut.listDonutBuckets(); err != nil {
return ObjectResourcesMetadata{}, err.Trace()
}
if _, ok := donut.buckets[bucket]; !ok {
return ObjectResourcesMetadata{}, probe.New(BucketNotFound{Bucket: bucket})
return ObjectResourcesMetadata{}, probe.NewError(BucketNotFound{Bucket: bucket})
}
allBuckets, err := donut.getDonutBucketMetadata()
if err != nil {
@ -300,10 +300,10 @@ func (donut API) listObjectParts(bucket, object string, resources ObjectResource
}
bucketMetadata := allBuckets.Buckets[bucket]
if _, ok := bucketMetadata.Multiparts[object]; !ok {
return ObjectResourcesMetadata{}, probe.New(InvalidUploadID{UploadID: resources.UploadID})
return ObjectResourcesMetadata{}, probe.NewError(InvalidUploadID{UploadID: resources.UploadID})
}
if bucketMetadata.Multiparts[object].UploadID != resources.UploadID {
return ObjectResourcesMetadata{}, probe.New(InvalidUploadID{UploadID: resources.UploadID})
return ObjectResourcesMetadata{}, probe.NewError(InvalidUploadID{UploadID: resources.UploadID})
}
objectResourcesMetadata := resources
objectResourcesMetadata.Bucket = bucket
@ -326,7 +326,7 @@ func (donut API) listObjectParts(bucket, object string, resources ObjectResource
}
part, ok := bucketMetadata.Multiparts[object].Parts[strconv.Itoa(i)]
if !ok {
return ObjectResourcesMetadata{}, probe.New(InvalidPart{})
return ObjectResourcesMetadata{}, probe.NewError(InvalidPart{})
}
parts = append(parts, &part)
}
@ -338,16 +338,16 @@ func (donut API) listObjectParts(bucket, object string, resources ObjectResource
// completeMultipartUpload complete an incomplete multipart upload
func (donut API) completeMultipartUpload(bucket, object, uploadID string, data io.Reader, signature *Signature) (ObjectMetadata, *probe.Error) {
if bucket == "" || strings.TrimSpace(bucket) == "" {
return ObjectMetadata{}, probe.New(InvalidArgument{})
return ObjectMetadata{}, probe.NewError(InvalidArgument{})
}
if object == "" || strings.TrimSpace(object) == "" {
return ObjectMetadata{}, probe.New(InvalidArgument{})
return ObjectMetadata{}, probe.NewError(InvalidArgument{})
}
if err := donut.listDonutBuckets(); err != nil {
return ObjectMetadata{}, err.Trace()
}
if _, ok := donut.buckets[bucket]; !ok {
return ObjectMetadata{}, probe.New(BucketNotFound{Bucket: bucket})
return ObjectMetadata{}, probe.NewError(BucketNotFound{Bucket: bucket})
}
allBuckets, err := donut.getDonutBucketMetadata()
if err != nil {
@ -355,17 +355,17 @@ func (donut API) completeMultipartUpload(bucket, object, uploadID string, data i
}
bucketMetadata := allBuckets.Buckets[bucket]
if _, ok := bucketMetadata.Multiparts[object]; !ok {
return ObjectMetadata{}, probe.New(InvalidUploadID{UploadID: uploadID})
return ObjectMetadata{}, probe.NewError(InvalidUploadID{UploadID: uploadID})
}
if bucketMetadata.Multiparts[object].UploadID != uploadID {
return ObjectMetadata{}, probe.New(InvalidUploadID{UploadID: uploadID})
return ObjectMetadata{}, probe.NewError(InvalidUploadID{UploadID: uploadID})
}
var partBytes []byte
{
var err error
partBytes, err = ioutil.ReadAll(data)
if err != nil {
return ObjectMetadata{}, probe.New(err)
return ObjectMetadata{}, probe.NewError(err)
}
}
if signature != nil {
@ -374,19 +374,19 @@ func (donut API) completeMultipartUpload(bucket, object, uploadID string, data i
return ObjectMetadata{}, err.Trace()
}
if !ok {
return ObjectMetadata{}, probe.New(SignatureDoesNotMatch{})
return ObjectMetadata{}, probe.NewError(SignatureDoesNotMatch{})
}
}
parts := &CompleteMultipartUpload{}
if err := xml.Unmarshal(partBytes, parts); err != nil {
return ObjectMetadata{}, probe.New(MalformedXML{})
return ObjectMetadata{}, probe.NewError(MalformedXML{})
}
if !sort.IsSorted(completedParts(parts.Part)) {
return ObjectMetadata{}, probe.New(InvalidPartOrder{})
return ObjectMetadata{}, probe.NewError(InvalidPartOrder{})
}
for _, part := range parts.Part {
if strings.Trim(part.ETag, "\"") != bucketMetadata.Multiparts[object].Parts[strconv.Itoa(part.PartNumber)].ETag {
return ObjectMetadata{}, probe.New(InvalidPart{})
return ObjectMetadata{}, probe.NewError(InvalidPart{})
}
}
var finalETagBytes []byte
@ -395,7 +395,7 @@ func (donut API) completeMultipartUpload(bucket, object, uploadID string, data i
for _, part := range bucketMetadata.Multiparts[object].Parts {
partETagBytes, err := hex.DecodeString(part.ETag)
if err != nil {
return ObjectMetadata{}, probe.New(err)
return ObjectMetadata{}, probe.NewError(err)
}
finalETagBytes = append(finalETagBytes, partETagBytes...)
finalSize += part.Size
@ -416,7 +416,7 @@ func (donut API) listMultipartUploads(bucket string, resources BucketMultipartRe
return BucketMultipartResourcesMetadata{}, err.Trace()
}
if _, ok := donut.buckets[bucket]; !ok {
return BucketMultipartResourcesMetadata{}, probe.New(BucketNotFound{Bucket: bucket})
return BucketMultipartResourcesMetadata{}, probe.NewError(BucketNotFound{Bucket: bucket})
}
allbuckets, err := donut.getDonutBucketMetadata()
if err != nil {
@ -474,7 +474,7 @@ func (donut API) abortMultipartUpload(bucket, object, uploadID string) *probe.Er
return err.Trace()
}
if _, ok := donut.buckets[bucket]; !ok {
return probe.New(BucketNotFound{Bucket: bucket})
return probe.NewError(BucketNotFound{Bucket: bucket})
}
allbuckets, err := donut.getDonutBucketMetadata()
if err != nil {
@ -482,10 +482,10 @@ func (donut API) abortMultipartUpload(bucket, object, uploadID string) *probe.Er
}
bucketMetadata := allbuckets.Buckets[bucket]
if _, ok := bucketMetadata.Multiparts[object]; !ok {
return probe.New(InvalidUploadID{UploadID: uploadID})
return probe.NewError(InvalidUploadID{UploadID: uploadID})
}
if bucketMetadata.Multiparts[object].UploadID != uploadID {
return probe.New(InvalidUploadID{UploadID: uploadID})
return probe.NewError(InvalidUploadID{UploadID: uploadID})
}
delete(bucketMetadata.Multiparts, object)
@ -557,7 +557,7 @@ func (donut API) setDonutBucketMetadata(metadata *AllBuckets) *probe.Error {
jenc := json.NewEncoder(writer)
if err := jenc.Encode(metadata); err != nil {
CleanupWritersOnError(writers)
return probe.New(err)
return probe.NewError(err)
}
}
for _, writer := range writers {
@ -584,7 +584,7 @@ func (donut API) getDonutBucketMetadata() (*AllBuckets, *probe.Error) {
return metadata, nil
}
}
return nil, probe.New(err)
return nil, probe.NewError(err)
}
}
@ -594,7 +594,7 @@ func (donut API) makeDonutBucket(bucketName, acl string) *probe.Error {
return err.Trace()
}
if _, ok := donut.buckets[bucketName]; ok {
return probe.New(BucketExists{Bucket: bucketName})
return probe.NewError(BucketExists{Bucket: bucketName})
}
bucket, bucketMetadata, err := newBucket(bucketName, acl, donut.config.DonutName, donut.nodes)
if err != nil {
@ -662,7 +662,7 @@ func (donut API) listDonutBuckets() *probe.Error {
for _, dir := range dirs {
splitDir := strings.Split(dir.Name(), "$")
if len(splitDir) < 3 {
return probe.New(CorruptedBackend{Backend: dir.Name()})
return probe.NewError(CorruptedBackend{Backend: dir.Name()})
}
bucketName := splitDir[0]
// we dont need this once we cache from makeDonutBucket()

View file

@ -67,15 +67,15 @@ func (s *MyDonutSuite) SetUpSuite(c *C) {
conf.NodeDiskMap = createTestNodeDiskMap(root)
conf.MaxSize = 100000
SetDonutConfigPath(filepath.Join(root, "donut.json"))
err = SaveConfig(conf)
c.Assert(err, IsNil)
perr := SaveConfig(conf)
c.Assert(perr, IsNil)
dd, err = New()
c.Assert(err, IsNil)
dd, perr = New()
c.Assert(perr, IsNil)
// testing empty donut
buckets, err := dd.ListBuckets(nil)
c.Assert(err, IsNil)
buckets, perr := dd.ListBuckets(nil)
c.Assert(perr, IsNil)
c.Assert(len(buckets), Equals, 0)
}

View file

@ -98,7 +98,7 @@ func New() (Interface, *probe.Error) {
if len(a.config.NodeDiskMap) > 0 {
for k, v := range a.config.NodeDiskMap {
if len(v) == 0 {
return nil, probe.New(InvalidDisksArgument{})
return nil, probe.NewError(InvalidDisksArgument{})
}
err := a.AttachNode(k, v)
if err != nil {
@ -131,19 +131,19 @@ func (donut API) GetObject(w io.Writer, bucket string, object string, start, len
defer donut.lock.Unlock()
if !IsValidBucket(bucket) {
return 0, probe.New(BucketNameInvalid{Bucket: bucket})
return 0, probe.NewError(BucketNameInvalid{Bucket: bucket})
}
if !IsValidObjectName(object) {
return 0, probe.New(ObjectNameInvalid{Object: object})
return 0, probe.NewError(ObjectNameInvalid{Object: object})
}
if start < 0 {
return 0, probe.New(InvalidRange{
return 0, probe.NewError(InvalidRange{
Start: start,
Length: length,
})
}
if !donut.storedBuckets.Exists(bucket) {
return 0, probe.New(BucketNotFound{Bucket: bucket})
return 0, probe.NewError(BucketNotFound{Bucket: bucket})
}
objectKey := bucket + "/" + object
data, ok := donut.objects.Get(objectKey)
@ -156,7 +156,7 @@ func (donut API) GetObject(w io.Writer, bucket string, object string, start, len
}
if start > 0 {
if _, err := io.CopyN(ioutil.Discard, reader, start); err != nil {
return 0, probe.New(err)
return 0, probe.NewError(err)
}
}
// new proxy writer to capture data read from disk
@ -166,12 +166,12 @@ func (donut API) GetObject(w io.Writer, bucket string, object string, start, len
if length > 0 {
written, err = io.CopyN(pw, reader, length)
if err != nil {
return 0, probe.New(err)
return 0, probe.NewError(err)
}
} else {
written, err = io.CopyN(pw, reader, size)
if err != nil {
return 0, probe.New(err)
return 0, probe.NewError(err)
}
}
}
@ -180,23 +180,23 @@ func (donut API) GetObject(w io.Writer, bucket string, object string, start, len
pw.writtenBytes = nil
go debug.FreeOSMemory()
if !ok {
return 0, probe.New(InternalError{})
return 0, probe.NewError(InternalError{})
}
return written, nil
}
return 0, probe.New(ObjectNotFound{Object: object})
return 0, probe.NewError(ObjectNotFound{Object: object})
}
{
var err error
if start == 0 && length == 0 {
written, err = io.CopyN(w, bytes.NewBuffer(data), int64(donut.objects.Len(objectKey)))
if err != nil {
return 0, probe.New(err)
return 0, probe.NewError(err)
}
} else {
written, err = io.CopyN(w, bytes.NewBuffer(data[start:]), length)
if err != nil {
return 0, probe.New(err)
return 0, probe.NewError(err)
}
}
return written, nil
@ -214,12 +214,12 @@ func (donut API) GetBucketMetadata(bucket string, signature *Signature) (BucketM
return BucketMetadata{}, err.Trace()
}
if !ok {
return BucketMetadata{}, probe.New(SignatureDoesNotMatch{})
return BucketMetadata{}, probe.NewError(SignatureDoesNotMatch{})
}
}
if !IsValidBucket(bucket) {
return BucketMetadata{}, probe.New(BucketNameInvalid{Bucket: bucket})
return BucketMetadata{}, probe.NewError(BucketNameInvalid{Bucket: bucket})
}
if !donut.storedBuckets.Exists(bucket) {
if len(donut.config.NodeDiskMap) > 0 {
@ -231,7 +231,7 @@ func (donut API) GetBucketMetadata(bucket string, signature *Signature) (BucketM
storedBucket.bucketMetadata = bucketMetadata
donut.storedBuckets.Set(bucket, storedBucket)
}
return BucketMetadata{}, probe.New(BucketNotFound{Bucket: bucket})
return BucketMetadata{}, probe.NewError(BucketNotFound{Bucket: bucket})
}
return donut.storedBuckets.Get(bucket).(storedBucket).bucketMetadata, nil
}
@ -247,15 +247,15 @@ func (donut API) SetBucketMetadata(bucket string, metadata map[string]string, si
return err.Trace()
}
if !ok {
return probe.New(SignatureDoesNotMatch{})
return probe.NewError(SignatureDoesNotMatch{})
}
}
if !IsValidBucket(bucket) {
return probe.New(BucketNameInvalid{Bucket: bucket})
return probe.NewError(BucketNameInvalid{Bucket: bucket})
}
if !donut.storedBuckets.Exists(bucket) {
return probe.New(BucketNotFound{Bucket: bucket})
return probe.NewError(BucketNotFound{Bucket: bucket})
}
if len(donut.config.NodeDiskMap) > 0 {
if err := donut.setBucketMetadata(bucket, metadata); err != nil {
@ -273,18 +273,18 @@ func isMD5SumEqual(expectedMD5Sum, actualMD5Sum string) *probe.Error {
if strings.TrimSpace(expectedMD5Sum) != "" && strings.TrimSpace(actualMD5Sum) != "" {
expectedMD5SumBytes, err := hex.DecodeString(expectedMD5Sum)
if err != nil {
return probe.New(err)
return probe.NewError(err)
}
actualMD5SumBytes, err := hex.DecodeString(actualMD5Sum)
if err != nil {
return probe.New(err)
return probe.NewError(err)
}
if !bytes.Equal(expectedMD5SumBytes, actualMD5SumBytes) {
return probe.New(BadDigest{})
return probe.NewError(BadDigest{})
}
return nil
}
return probe.New(InvalidArgument{})
return probe.NewError(InvalidArgument{})
}
// CreateObject - create an object
@ -305,7 +305,7 @@ func (donut API) createObject(bucket, key, contentType, expectedMD5Sum string, s
if len(donut.config.NodeDiskMap) == 0 {
if size > int64(donut.config.MaxSize) {
generic := GenericObjectError{Bucket: bucket, Object: key}
return ObjectMetadata{}, probe.New(EntityTooLarge{
return ObjectMetadata{}, probe.NewError(EntityTooLarge{
GenericObjectError: generic,
Size: strconv.FormatInt(size, 10),
MaxSize: strconv.FormatUint(donut.config.MaxSize, 10),
@ -313,19 +313,19 @@ func (donut API) createObject(bucket, key, contentType, expectedMD5Sum string, s
}
}
if !IsValidBucket(bucket) {
return ObjectMetadata{}, probe.New(BucketNameInvalid{Bucket: bucket})
return ObjectMetadata{}, probe.NewError(BucketNameInvalid{Bucket: bucket})
}
if !IsValidObjectName(key) {
return ObjectMetadata{}, probe.New(ObjectNameInvalid{Object: key})
return ObjectMetadata{}, probe.NewError(ObjectNameInvalid{Object: key})
}
if !donut.storedBuckets.Exists(bucket) {
return ObjectMetadata{}, probe.New(BucketNotFound{Bucket: bucket})
return ObjectMetadata{}, probe.NewError(BucketNotFound{Bucket: bucket})
}
storedBucket := donut.storedBuckets.Get(bucket).(storedBucket)
// get object key
objectKey := bucket + "/" + key
if _, ok := storedBucket.objectMetadata[objectKey]; ok == true {
return ObjectMetadata{}, probe.New(ObjectExists{Object: key})
return ObjectMetadata{}, probe.NewError(ObjectExists{Object: key})
}
if contentType == "" {
@ -336,7 +336,7 @@ func (donut API) createObject(bucket, key, contentType, expectedMD5Sum string, s
expectedMD5SumBytes, err := base64.StdEncoding.DecodeString(strings.TrimSpace(expectedMD5Sum))
if err != nil {
// pro-actively close the connection
return ObjectMetadata{}, probe.New(InvalidDigest{Md5: expectedMD5Sum})
return ObjectMetadata{}, probe.NewError(InvalidDigest{Md5: expectedMD5Sum})
}
expectedMD5Sum = hex.EncodeToString(expectedMD5SumBytes)
}
@ -375,7 +375,7 @@ func (donut API) createObject(bucket, key, contentType, expectedMD5Sum string, s
sha256hash.Write(byteBuffer[0:length])
ok := donut.objects.Append(objectKey, byteBuffer[0:length])
if !ok {
return ObjectMetadata{}, probe.New(InternalError{})
return ObjectMetadata{}, probe.NewError(InternalError{})
}
totalLength += int64(length)
go debug.FreeOSMemory()
@ -383,17 +383,17 @@ func (donut API) createObject(bucket, key, contentType, expectedMD5Sum string, s
if totalLength != size {
// Delete perhaps the object is already saved, due to the nature of append()
donut.objects.Delete(objectKey)
return ObjectMetadata{}, probe.New(IncompleteBody{Bucket: bucket, Object: key})
return ObjectMetadata{}, probe.NewError(IncompleteBody{Bucket: bucket, Object: key})
}
if err != io.EOF {
return ObjectMetadata{}, probe.New(err)
return ObjectMetadata{}, probe.NewError(err)
}
md5SumBytes := hash.Sum(nil)
md5Sum := hex.EncodeToString(md5SumBytes)
// Verify if the written object is equal to what is expected, only if it is requested as such
if strings.TrimSpace(expectedMD5Sum) != "" {
if err := isMD5SumEqual(strings.TrimSpace(expectedMD5Sum), md5Sum); err != nil {
return ObjectMetadata{}, probe.New(BadDigest{})
return ObjectMetadata{}, probe.NewError(BadDigest{})
}
}
if signature != nil {
@ -402,7 +402,7 @@ func (donut API) createObject(bucket, key, contentType, expectedMD5Sum string, s
return ObjectMetadata{}, err.Trace()
}
if !ok {
return ObjectMetadata{}, probe.New(SignatureDoesNotMatch{})
return ObjectMetadata{}, probe.NewError(SignatureDoesNotMatch{})
}
}
@ -433,7 +433,7 @@ func (donut API) MakeBucket(bucketName, acl string, location io.Reader, signatur
if location != nil {
locationConstraintBytes, err := ioutil.ReadAll(location)
if err != nil {
return probe.New(InternalError{})
return probe.NewError(InternalError{})
}
locationSum = hex.EncodeToString(sha256.Sum256(locationConstraintBytes)[:])
}
@ -444,21 +444,21 @@ func (donut API) MakeBucket(bucketName, acl string, location io.Reader, signatur
return err.Trace()
}
if !ok {
return probe.New(SignatureDoesNotMatch{})
return probe.NewError(SignatureDoesNotMatch{})
}
}
if donut.storedBuckets.Stats().Items == totalBuckets {
return probe.New(TooManyBuckets{Bucket: bucketName})
return probe.NewError(TooManyBuckets{Bucket: bucketName})
}
if !IsValidBucket(bucketName) {
return probe.New(BucketNameInvalid{Bucket: bucketName})
return probe.NewError(BucketNameInvalid{Bucket: bucketName})
}
if !IsValidBucketACL(acl) {
return probe.New(InvalidACL{ACL: acl})
return probe.NewError(InvalidACL{ACL: acl})
}
if donut.storedBuckets.Exists(bucketName) {
return probe.New(BucketExists{Bucket: bucketName})
return probe.NewError(BucketExists{Bucket: bucketName})
}
if strings.TrimSpace(acl) == "" {
@ -493,18 +493,18 @@ func (donut API) ListObjects(bucket string, resources BucketResourcesMetadata, s
return nil, BucketResourcesMetadata{}, err.Trace()
}
if !ok {
return nil, BucketResourcesMetadata{}, probe.New(SignatureDoesNotMatch{})
return nil, BucketResourcesMetadata{}, probe.NewError(SignatureDoesNotMatch{})
}
}
if !IsValidBucket(bucket) {
return nil, BucketResourcesMetadata{IsTruncated: false}, probe.New(BucketNameInvalid{Bucket: bucket})
return nil, BucketResourcesMetadata{IsTruncated: false}, probe.NewError(BucketNameInvalid{Bucket: bucket})
}
if !IsValidPrefix(resources.Prefix) {
return nil, BucketResourcesMetadata{IsTruncated: false}, probe.New(ObjectNameInvalid{Object: resources.Prefix})
return nil, BucketResourcesMetadata{IsTruncated: false}, probe.NewError(ObjectNameInvalid{Object: resources.Prefix})
}
if !donut.storedBuckets.Exists(bucket) {
return nil, BucketResourcesMetadata{IsTruncated: false}, probe.New(BucketNotFound{Bucket: bucket})
return nil, BucketResourcesMetadata{IsTruncated: false}, probe.NewError(BucketNotFound{Bucket: bucket})
}
var results []ObjectMetadata
var keys []string
@ -593,10 +593,10 @@ func (donut API) ListBuckets(signature *Signature) ([]BucketMetadata, *probe.Err
if signature != nil {
ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
if err != nil {
return nil, probe.New(err)
return nil, err.Trace()
}
if !ok {
return nil, probe.New(SignatureDoesNotMatch{})
return nil, probe.NewError(SignatureDoesNotMatch{})
}
}
@ -630,19 +630,19 @@ func (donut API) GetObjectMetadata(bucket, key string, signature *Signature) (Ob
return ObjectMetadata{}, err.Trace()
}
if !ok {
return ObjectMetadata{}, probe.New(SignatureDoesNotMatch{})
return ObjectMetadata{}, probe.NewError(SignatureDoesNotMatch{})
}
}
// check if bucket exists
if !IsValidBucket(bucket) {
return ObjectMetadata{}, probe.New(BucketNameInvalid{Bucket: bucket})
return ObjectMetadata{}, probe.NewError(BucketNameInvalid{Bucket: bucket})
}
if !IsValidObjectName(key) {
return ObjectMetadata{}, probe.New(ObjectNameInvalid{Object: key})
return ObjectMetadata{}, probe.NewError(ObjectNameInvalid{Object: key})
}
if !donut.storedBuckets.Exists(bucket) {
return ObjectMetadata{}, probe.New(BucketNotFound{Bucket: bucket})
return ObjectMetadata{}, probe.NewError(BucketNotFound{Bucket: bucket})
}
storedBucket := donut.storedBuckets.Get(bucket).(storedBucket)
objectKey := bucket + "/" + key
@ -659,7 +659,7 @@ func (donut API) GetObjectMetadata(bucket, key string, signature *Signature) (Ob
donut.storedBuckets.Set(bucket, storedBucket)
return objMetadata, nil
}
return ObjectMetadata{}, probe.New(ObjectNotFound{Object: key})
return ObjectMetadata{}, probe.NewError(ObjectNotFound{Object: key})
}
// evictedObject callback function called when an item is evicted from memory

View file

@ -45,12 +45,12 @@ func (s *MyCacheSuite) SetUpSuite(c *C) {
s.root = root
SetDonutConfigPath(filepath.Join(root, "donut.json"))
dc, err = New()
c.Assert(err, IsNil)
dc, _ = New()
// testing empty cache
buckets, err := dc.ListBuckets(nil)
c.Assert(err, IsNil)
var buckets []BucketMetadata
buckets, perr := dc.ListBuckets(nil)
c.Assert(perr, IsNil)
c.Assert(len(buckets), Equals, 0)
}

View file

@ -38,7 +38,7 @@ func getErasureTechnique(technique string) (encoding.Technique, *probe.Error) {
case technique == "Vandermonde":
return encoding.Cauchy, nil
default:
return encoding.None, probe.New(InvalidErasureTechnique{Technique: technique})
return encoding.None, probe.NewError(InvalidErasureTechnique{Technique: technique})
}
}
@ -52,7 +52,7 @@ func newEncoder(k, m uint8, technique string) (encoder, *probe.Error) {
{
params, err := encoding.ValidateParams(k, m, t)
if err != nil {
return encoder{}, probe.New(err)
return encoder{}, probe.NewError(err)
}
e.encoder = encoding.NewErasure(params)
e.k = k
@ -66,7 +66,7 @@ func newEncoder(k, m uint8, technique string) (encoder, *probe.Error) {
// GetEncodedBlockLen - wrapper around erasure function with the same name
func (e encoder) GetEncodedBlockLen(dataLength int) (int, *probe.Error) {
if dataLength <= 0 {
return 0, probe.New(InvalidArgument{})
return 0, probe.NewError(InvalidArgument{})
}
return encoding.GetEncodedBlockLen(dataLength, e.k), nil
}
@ -74,11 +74,11 @@ func (e encoder) GetEncodedBlockLen(dataLength int) (int, *probe.Error) {
// Encode - erasure code input bytes
func (e encoder) Encode(data []byte) ([][]byte, *probe.Error) {
if data == nil {
return nil, probe.New(InvalidArgument{})
return nil, probe.NewError(InvalidArgument{})
}
encodedData, err := e.encoder.Encode(data)
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
return encodedData, nil
}
@ -86,7 +86,7 @@ func (e encoder) Encode(data []byte) ([][]byte, *probe.Error) {
func (e encoder) EncodeStream(data io.Reader, size int64) ([][]byte, []byte, *probe.Error) {
encodedData, inputData, err := e.encoder.EncodeStream(data, size)
if err != nil {
return nil, nil, probe.New(err)
return nil, nil, probe.NewError(err)
}
return encodedData, inputData, nil
}
@ -95,7 +95,7 @@ func (e encoder) EncodeStream(data io.Reader, size int64) ([][]byte, []byte, *pr
func (e encoder) Decode(encodedData [][]byte, dataLength int) ([]byte, *probe.Error) {
decodedData, err := e.encoder.Decode(encodedData, dataLength)
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
return decodedData, nil
}

View file

@ -54,7 +54,7 @@ func (donut API) healBuckets() *probe.Error {
defer bucketMetadataWriter.Close()
jenc := json.NewEncoder(bucketMetadataWriter)
if err := jenc.Encode(bucketMetadata); err != nil {
return probe.New(err)
return probe.NewError(err)
}
for bucket := range bucketMetadata.Buckets {
bucketSlice := fmt.Sprintf("%s$0$%d", bucket, order) // TODO handle node slices

View file

@ -41,7 +41,7 @@ func (donut API) Info() (nodeDiskMap map[string][]string, err *probe.Error) {
// AttachNode - attach node
func (donut API) AttachNode(hostname string, disks []string) *probe.Error {
if hostname == "" || len(disks) == 0 {
return probe.New(InvalidArgument{})
return probe.NewError(InvalidArgument{})
}
node, err := newNode(hostname)
if err != nil {
@ -71,7 +71,7 @@ func (donut API) DetachNode(hostname string) *probe.Error {
// Rebalance - rebalance an existing donut with new disks and nodes
func (donut API) Rebalance() *probe.Error {
return probe.New(APINotImplemented{API: "management.Rebalance"})
return probe.NewError(APINotImplemented{API: "management.Rebalance"})
}
// Heal - heal your donuts

View file

@ -45,10 +45,10 @@ func (donut API) NewMultipartUpload(bucket, key, contentType string, signature *
defer donut.lock.Unlock()
if !IsValidBucket(bucket) {
return "", probe.New(BucketNameInvalid{Bucket: bucket})
return "", probe.NewError(BucketNameInvalid{Bucket: bucket})
}
if !IsValidObjectName(key) {
return "", probe.New(ObjectNameInvalid{Object: key})
return "", probe.NewError(ObjectNameInvalid{Object: key})
}
if signature != nil {
ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
@ -56,19 +56,19 @@ func (donut API) NewMultipartUpload(bucket, key, contentType string, signature *
return "", err.Trace()
}
if !ok {
return "", probe.New(SignatureDoesNotMatch{})
return "", probe.NewError(SignatureDoesNotMatch{})
}
}
if len(donut.config.NodeDiskMap) > 0 {
return donut.newMultipartUpload(bucket, key, contentType)
}
if !donut.storedBuckets.Exists(bucket) {
return "", probe.New(BucketNotFound{Bucket: bucket})
return "", probe.NewError(BucketNotFound{Bucket: bucket})
}
storedBucket := donut.storedBuckets.Get(bucket).(storedBucket)
objectKey := bucket + "/" + key
if _, ok := storedBucket.objectMetadata[objectKey]; ok == true {
return "", probe.New(ObjectExists{Object: key})
return "", probe.NewError(ObjectExists{Object: key})
}
id := []byte(strconv.Itoa(rand.Int()) + bucket + key + time.Now().UTC().String())
uploadIDSum := sha512.Sum512(id)
@ -93,10 +93,10 @@ func (donut API) AbortMultipartUpload(bucket, key, uploadID string, signature *S
defer donut.lock.Unlock()
if !IsValidBucket(bucket) {
return probe.New(BucketNameInvalid{Bucket: bucket})
return probe.NewError(BucketNameInvalid{Bucket: bucket})
}
if !IsValidObjectName(key) {
return probe.New(ObjectNameInvalid{Object: key})
return probe.NewError(ObjectNameInvalid{Object: key})
}
if signature != nil {
ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
@ -104,18 +104,18 @@ func (donut API) AbortMultipartUpload(bucket, key, uploadID string, signature *S
return err.Trace()
}
if !ok {
return probe.New(SignatureDoesNotMatch{})
return probe.NewError(SignatureDoesNotMatch{})
}
}
if len(donut.config.NodeDiskMap) > 0 {
return donut.abortMultipartUpload(bucket, key, uploadID)
}
if !donut.storedBuckets.Exists(bucket) {
return probe.New(BucketNotFound{Bucket: bucket})
return probe.NewError(BucketNotFound{Bucket: bucket})
}
storedBucket := donut.storedBuckets.Get(bucket).(storedBucket)
if storedBucket.multiPartSession[key].UploadID != uploadID {
return probe.New(InvalidUploadID{UploadID: uploadID})
return probe.NewError(InvalidUploadID{UploadID: uploadID})
}
donut.cleanupMultipartSession(bucket, key, uploadID)
return nil
@ -135,10 +135,10 @@ func (donut API) CreateObjectPart(bucket, key, uploadID string, partID int, cont
// createObject - internal wrapper function called by CreateObjectPart
func (donut API) createObjectPart(bucket, key, uploadID string, partID int, contentType, expectedMD5Sum string, size int64, data io.Reader, signature *Signature) (string, *probe.Error) {
if !IsValidBucket(bucket) {
return "", probe.New(BucketNameInvalid{Bucket: bucket})
return "", probe.NewError(BucketNameInvalid{Bucket: bucket})
}
if !IsValidObjectName(key) {
return "", probe.New(ObjectNameInvalid{Object: key})
return "", probe.NewError(ObjectNameInvalid{Object: key})
}
if len(donut.config.NodeDiskMap) > 0 {
metadata := make(map[string]string)
@ -151,7 +151,7 @@ func (donut API) createObjectPart(bucket, key, uploadID string, partID int, cont
expectedMD5SumBytes, err := base64.StdEncoding.DecodeString(strings.TrimSpace(expectedMD5Sum))
if err != nil {
// pro-actively close the connection
return "", probe.New(InvalidDigest{Md5: expectedMD5Sum})
return "", probe.NewError(InvalidDigest{Md5: expectedMD5Sum})
}
expectedMD5Sum = hex.EncodeToString(expectedMD5SumBytes)
}
@ -163,12 +163,12 @@ func (donut API) createObjectPart(bucket, key, uploadID string, partID int, cont
}
if !donut.storedBuckets.Exists(bucket) {
return "", probe.New(BucketNotFound{Bucket: bucket})
return "", probe.NewError(BucketNotFound{Bucket: bucket})
}
strBucket := donut.storedBuckets.Get(bucket).(storedBucket)
// Verify upload id
if strBucket.multiPartSession[key].UploadID != uploadID {
return "", probe.New(InvalidUploadID{UploadID: uploadID})
return "", probe.NewError(InvalidUploadID{UploadID: uploadID})
}
// get object key
@ -185,7 +185,7 @@ func (donut API) createObjectPart(bucket, key, uploadID string, partID int, cont
expectedMD5SumBytes, err := base64.StdEncoding.DecodeString(strings.TrimSpace(expectedMD5Sum))
if err != nil {
// pro-actively close the connection
return "", probe.New(InvalidDigest{Md5: expectedMD5Sum})
return "", probe.NewError(InvalidDigest{Md5: expectedMD5Sum})
}
expectedMD5Sum = hex.EncodeToString(expectedMD5SumBytes)
}
@ -204,17 +204,17 @@ func (donut API) createObjectPart(bucket, key, uploadID string, partID int, cont
sha256hash.Write(byteBuffer[0:length])
ok := donut.multiPartObjects[uploadID].Append(partID, byteBuffer[0:length])
if !ok {
return "", probe.New(InternalError{})
return "", probe.NewError(InternalError{})
}
totalLength += int64(length)
go debug.FreeOSMemory()
}
if totalLength != size {
donut.multiPartObjects[uploadID].Delete(partID)
return "", probe.New(IncompleteBody{Bucket: bucket, Object: key})
return "", probe.NewError(IncompleteBody{Bucket: bucket, Object: key})
}
if err != io.EOF {
return "", probe.New(err)
return "", probe.NewError(err)
}
md5SumBytes := hash.Sum(nil)
@ -233,7 +233,7 @@ func (donut API) createObjectPart(bucket, key, uploadID string, partID int, cont
return "", err.Trace()
}
if !ok {
return "", probe.New(SignatureDoesNotMatch{})
return "", probe.NewError(SignatureDoesNotMatch{})
}
}
}
@ -271,11 +271,11 @@ func (donut API) CompleteMultipartUpload(bucket, key, uploadID string, data io.R
if !IsValidBucket(bucket) {
donut.lock.Unlock()
return ObjectMetadata{}, probe.New(BucketNameInvalid{Bucket: bucket})
return ObjectMetadata{}, probe.NewError(BucketNameInvalid{Bucket: bucket})
}
if !IsValidObjectName(key) {
donut.lock.Unlock()
return ObjectMetadata{}, probe.New(ObjectNameInvalid{Object: key})
return ObjectMetadata{}, probe.NewError(ObjectNameInvalid{Object: key})
}
if len(donut.config.NodeDiskMap) > 0 {
donut.lock.Unlock()
@ -284,18 +284,18 @@ func (donut API) CompleteMultipartUpload(bucket, key, uploadID string, data io.R
if !donut.storedBuckets.Exists(bucket) {
donut.lock.Unlock()
return ObjectMetadata{}, probe.New(BucketNotFound{Bucket: bucket})
return ObjectMetadata{}, probe.NewError(BucketNotFound{Bucket: bucket})
}
storedBucket := donut.storedBuckets.Get(bucket).(storedBucket)
// Verify upload id
if storedBucket.multiPartSession[key].UploadID != uploadID {
donut.lock.Unlock()
return ObjectMetadata{}, probe.New(InvalidUploadID{UploadID: uploadID})
return ObjectMetadata{}, probe.NewError(InvalidUploadID{UploadID: uploadID})
}
partBytes, err := ioutil.ReadAll(data)
if err != nil {
donut.lock.Unlock()
return ObjectMetadata{}, probe.New(err)
return ObjectMetadata{}, probe.NewError(err)
}
if signature != nil {
ok, err := signature.DoesSignatureMatch(hex.EncodeToString(sha256.Sum256(partBytes)[:]))
@ -305,17 +305,17 @@ func (donut API) CompleteMultipartUpload(bucket, key, uploadID string, data io.R
}
if !ok {
donut.lock.Unlock()
return ObjectMetadata{}, probe.New(SignatureDoesNotMatch{})
return ObjectMetadata{}, probe.NewError(SignatureDoesNotMatch{})
}
}
parts := &CompleteMultipartUpload{}
if err := xml.Unmarshal(partBytes, parts); err != nil {
donut.lock.Unlock()
return ObjectMetadata{}, probe.New(MalformedXML{})
return ObjectMetadata{}, probe.NewError(MalformedXML{})
}
if !sort.IsSorted(completedParts(parts.Part)) {
donut.lock.Unlock()
return ObjectMetadata{}, probe.New(InvalidPartOrder{})
return ObjectMetadata{}, probe.NewError(InvalidPartOrder{})
}
var size int64
@ -325,7 +325,7 @@ func (donut API) CompleteMultipartUpload(bucket, key, uploadID string, data io.R
object, ok := donut.multiPartObjects[uploadID].Get(parts.Part[i].PartNumber)
if ok == false {
donut.lock.Unlock()
return ObjectMetadata{}, probe.New(InvalidPart{})
return ObjectMetadata{}, probe.NewError(InvalidPart{})
}
size += int64(len(object))
calcMD5Bytes := md5.Sum(object)
@ -333,15 +333,15 @@ func (donut API) CompleteMultipartUpload(bucket, key, uploadID string, data io.R
recvMD5Bytes, err := hex.DecodeString(strings.Trim(recvMD5, "\""))
if err != nil {
donut.lock.Unlock()
return ObjectMetadata{}, probe.New(InvalidDigest{Md5: recvMD5})
return ObjectMetadata{}, probe.NewError(InvalidDigest{Md5: recvMD5})
}
if !bytes.Equal(recvMD5Bytes, calcMD5Bytes[:]) {
donut.lock.Unlock()
return ObjectMetadata{}, probe.New(BadDigest{})
return ObjectMetadata{}, probe.NewError(BadDigest{})
}
if _, err := io.Copy(&fullObject, bytes.NewBuffer(object)); err != nil {
donut.lock.Unlock()
return ObjectMetadata{}, probe.New(err)
return ObjectMetadata{}, probe.NewError(err)
}
object = nil
go debug.FreeOSMemory()
@ -386,12 +386,12 @@ func (donut API) ListMultipartUploads(bucket string, resources BucketMultipartRe
return BucketMultipartResourcesMetadata{}, err.Trace()
}
if !ok {
return BucketMultipartResourcesMetadata{}, probe.New(SignatureDoesNotMatch{})
return BucketMultipartResourcesMetadata{}, probe.NewError(SignatureDoesNotMatch{})
}
}
if !IsValidBucket(bucket) {
return BucketMultipartResourcesMetadata{}, probe.New(BucketNameInvalid{Bucket: bucket})
return BucketMultipartResourcesMetadata{}, probe.NewError(BucketNameInvalid{Bucket: bucket})
}
if len(donut.config.NodeDiskMap) > 0 {
@ -399,7 +399,7 @@ func (donut API) ListMultipartUploads(bucket string, resources BucketMultipartRe
}
if !donut.storedBuckets.Exists(bucket) {
return BucketMultipartResourcesMetadata{}, probe.New(BucketNotFound{Bucket: bucket})
return BucketMultipartResourcesMetadata{}, probe.NewError(BucketNotFound{Bucket: bucket})
}
storedBucket := donut.storedBuckets.Get(bucket).(storedBucket)
@ -468,15 +468,15 @@ func (donut API) ListObjectParts(bucket, key string, resources ObjectResourcesMe
return ObjectResourcesMetadata{}, err.Trace()
}
if !ok {
return ObjectResourcesMetadata{}, probe.New(SignatureDoesNotMatch{})
return ObjectResourcesMetadata{}, probe.NewError(SignatureDoesNotMatch{})
}
}
if !IsValidBucket(bucket) {
return ObjectResourcesMetadata{}, probe.New(BucketNameInvalid{Bucket: bucket})
return ObjectResourcesMetadata{}, probe.NewError(BucketNameInvalid{Bucket: bucket})
}
if !IsValidObjectName(key) {
return ObjectResourcesMetadata{}, probe.New(ObjectNameInvalid{Object: key})
return ObjectResourcesMetadata{}, probe.NewError(ObjectNameInvalid{Object: key})
}
if len(donut.config.NodeDiskMap) > 0 {
@ -484,14 +484,14 @@ func (donut API) ListObjectParts(bucket, key string, resources ObjectResourcesMe
}
if !donut.storedBuckets.Exists(bucket) {
return ObjectResourcesMetadata{}, probe.New(BucketNotFound{Bucket: bucket})
return ObjectResourcesMetadata{}, probe.NewError(BucketNotFound{Bucket: bucket})
}
storedBucket := donut.storedBuckets.Get(bucket).(storedBucket)
if _, ok := storedBucket.multiPartSession[key]; ok == false {
return ObjectResourcesMetadata{}, probe.New(ObjectNotFound{Object: key})
return ObjectResourcesMetadata{}, probe.NewError(ObjectNotFound{Object: key})
}
if storedBucket.multiPartSession[key].UploadID != resources.UploadID {
return ObjectResourcesMetadata{}, probe.New(InvalidUploadID{UploadID: resources.UploadID})
return ObjectResourcesMetadata{}, probe.NewError(InvalidUploadID{UploadID: resources.UploadID})
}
storedParts := storedBucket.partMetadata[key]
objectResourcesMetadata := resources
@ -515,7 +515,7 @@ func (donut API) ListObjectParts(bucket, key string, resources ObjectResourcesMe
}
part, ok := storedParts[i]
if !ok {
return ObjectResourcesMetadata{}, probe.New(InvalidPart{})
return ObjectResourcesMetadata{}, probe.NewError(InvalidPart{})
}
parts = append(parts, &part)
}

View file

@ -30,7 +30,7 @@ type node struct {
// newNode - instantiates a new node
func newNode(hostname string) (node, *probe.Error) {
if hostname == "" {
return node{}, probe.New(InvalidArgument{})
return node{}, probe.NewError(InvalidArgument{})
}
disks := make(map[int]disk.Disk)
n := node{
@ -53,7 +53,7 @@ func (n node) ListDisks() (map[int]disk.Disk, *probe.Error) {
// AttachDisk - attach a disk
func (n node) AttachDisk(disk disk.Disk, diskOrder int) *probe.Error {
if diskOrder < 0 {
return probe.New(InvalidArgument{})
return probe.NewError(InvalidArgument{})
}
n.disks[diskOrder] = disk
return nil
@ -67,10 +67,10 @@ func (n node) DetachDisk(diskOrder int) *probe.Error {
// SaveConfig - save node configuration
func (n node) SaveConfig() *probe.Error {
return probe.New(NotImplemented{Function: "SaveConfig"})
return probe.NewError(NotImplemented{Function: "SaveConfig"})
}
// LoadConfig - load node configuration from saved configs
func (n node) LoadConfig() *probe.Error {
return probe.New(NotImplemented{Function: "LoadConfig"})
return probe.NewError(NotImplemented{Function: "LoadConfig"})
}

View file

@ -78,7 +78,7 @@ func urlEncodeName(name string) (string, *probe.Error) {
default:
len := utf8.RuneLen(s)
if len < 0 {
return "", probe.New(InvalidArgument{})
return "", probe.NewError(InvalidArgument{})
}
u := make([]byte, len)
utf8.EncodeRune(u, s)
@ -220,12 +220,12 @@ func (r *Signature) DoesSignatureMatch(hashedPayload string) (bool, *probe.Error
var date string
if date = r.Request.Header.Get(http.CanonicalHeaderKey("x-amz-date")); date == "" {
if date = r.Request.Header.Get("Date"); date == "" {
return false, probe.New(MissingDateHeader{})
return false, probe.NewError(MissingDateHeader{})
}
}
t, err := time.Parse(iso8601Format, date)
if err != nil {
return false, probe.New(err)
return false, probe.NewError(err)
}
canonicalRequest := r.getCanonicalRequest()
stringToSign := r.getStringToSign(canonicalRequest, t)

View file

@ -66,11 +66,11 @@ type Error struct {
tracePoints []tracePoint
}
// New function instantiates an error probe for tracing. Original errors.error (golang's error
// NewError function instantiates an error probe for tracing. Original errors.error (golang's error
// interface) is injected in only once during this New call. Rest of the time, you
// trace the return path with Probe.Trace and finally handle reporting or quitting
// at the top level.
func New(e error) *Error {
func NewError(e error) *Error {
if e == nil {
return nil
}
@ -124,17 +124,9 @@ func (e *Error) Untrace() {
e.tracePoints = e.tracePoints[:l-1]
}
// Error returns error string.
func (e *Error) Error() string {
if e == nil {
return "<nil>"
}
return e.String()
}
// String returns error message.
func (e *Error) String() string {
if e == nil {
if e == nil || e.e == nil {
return "<nil>"
}
e.lock.RLock()
@ -164,7 +156,7 @@ func (e *Error) String() string {
// JSON returns JSON formated error trace.
func (e *Error) JSON() string {
if e == nil {
if e == nil || e.e == nil {
return "<nil>"
}
@ -187,8 +179,38 @@ func (e *Error) JSON() string {
return string(jBytes)
}
// ToError returns original emnedded error.
// ToError returns original embedded error.
func (e *Error) ToError() error {
// No need to lock. "e.e" is set once during New and never changed.
return e.e
}
// WrappedError implements container for *probe.Error
type WrappedError struct {
err *Error
}
// NewWrappedError function wraps a *probe.Error into a 'error' compatible duck type
func NewWrappedError(err *Error) error {
return &WrappedError{err: err}
}
// Error interface method
func (w *WrappedError) Error() string {
return w.err.String()
}
// ToError get the *probe.Error embedded internally
func (w *WrappedError) ToError() *Error {
return w.err
}
// ToWrappedError try to convert generic 'error' into typed *WrappedError, returns true if yes, false otherwise
func ToWrappedError(err error) (*WrappedError, bool) {
switch e := err.(type) {
case *WrappedError:
return e, true
default:
return nil, false
}
}

View file

@ -13,33 +13,41 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package probe
package probe_test
import (
"os"
"testing"
"github.com/minio/minio/pkg/probe"
. "gopkg.in/check.v1"
)
func testDummy() *Error {
_, e := os.Stat("this-file-cannot-exit-234234232423423")
es := New(e)
es.Trace("this is hell", "asdf")
func Test(t *testing.T) { TestingT(t) }
type MySuite struct{}
var _ = Suite(&MySuite{})
func testDummy() *probe.Error {
_, e := os.Stat("this-file-cannot-exit")
es := probe.NewError(e)
es.Trace("Important info 1", "Import into 2")
return es
}
func TestProbe(t *testing.T) {
func (s *MySuite) TestProbe(c *C) {
es := testDummy()
if es == nil {
t.Fail()
}
c.Assert(es, Not(Equals), nil)
newES := es.Trace()
if newES == nil {
t.Fail()
}
/*
fmt.Println(es)
fmt.Println(es.JSON())
fmt.Println(es.ToError())
*/
c.Assert(newES, Not(Equals), nil)
}
func (s *MySuite) TestWrappedError(c *C) {
_, e := os.Stat("this-file-cannot-exit")
es := probe.NewError(e) // *probe.Error
e = probe.NewWrappedError(es) // *probe.WrappedError
_, ok := probe.ToWrappedError(e)
c.Assert(ok, Equals, true)
}

View file

@ -52,17 +52,17 @@ type config struct {
// CheckData - checks the validity of config data. Data sould be of type struct and contain a string type field called "Version"
func CheckData(data interface{}) *probe.Error {
if !structs.IsStruct(data) {
return probe.New(fmt.Errorf("Invalid argument type. Expecing \"struct\" type."))
return probe.NewError(fmt.Errorf("Invalid argument type. Expecing \"struct\" type."))
}
st := structs.New(data)
f, ok := st.FieldOk("Version")
if !ok {
return probe.New(fmt.Errorf("Invalid type of struct argument. No [%s.Version] field found.", st.Name()))
return probe.NewError(fmt.Errorf("Invalid type of struct argument. No [%s.Version] field found.", st.Name()))
}
if f.Kind() != reflect.String {
return probe.New(fmt.Errorf("Invalid type of struct argument. Expecting \"string\" type [%s.Version] field.", st.Name()))
return probe.NewError(fmt.Errorf("Invalid type of struct argument. Expecting \"string\" type [%s.Version] field.", st.Name()))
}
return nil
@ -111,7 +111,7 @@ func (d config) Save(filename string) *probe.Error {
jsonData, err := json.MarshalIndent(d.data, "", "\t")
if err != nil {
return probe.New(err)
return probe.NewError(err)
}
if runtime.GOOS == "windows" {
@ -120,7 +120,7 @@ func (d config) Save(filename string) *probe.Error {
err = ioutil.WriteFile(filename, jsonData, 0600)
if err != nil {
return probe.New(err)
return probe.NewError(err)
}
return nil
@ -133,12 +133,12 @@ func (d *config) Load(filename string) *probe.Error {
_, err := os.Stat(filename)
if err != nil {
return probe.New(err)
return probe.NewError(err)
}
fileData, err := ioutil.ReadFile(filename)
if err != nil {
return probe.New(err)
return probe.NewError(err)
}
if runtime.GOOS == "windows" {
@ -147,7 +147,7 @@ func (d *config) Load(filename string) *probe.Error {
err = json.Unmarshal(fileData, (*d).data)
if err != nil {
return probe.New(err)
return probe.NewError(err)
}
if err := CheckData(*(*d).data); err != nil {
@ -157,11 +157,11 @@ func (d *config) Load(filename string) *probe.Error {
st := structs.New(*(*d).data)
f, ok := st.FieldOk("Version")
if !ok {
return probe.New(fmt.Errorf("Argument struct [%s] does not contain field \"Version\".", st.Name()))
return probe.NewError(fmt.Errorf("Argument struct [%s] does not contain field \"Version\".", st.Name()))
}
if (*d).Version() != f.Value() {
return probe.New(fmt.Errorf("Version mismatch"))
return probe.NewError(fmt.Errorf("Version mismatch"))
}
return nil

View file

@ -24,7 +24,6 @@ import (
"os"
"time"
"github.com/minio/minio/pkg/probe"
"github.com/minio/minio/pkg/utils/log"
)
@ -99,12 +98,12 @@ func fileLogger(filename string) (chan<- []byte, error) {
ch := make(chan []byte)
file, err := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
if err != nil {
return nil, probe.New(err)
return nil, err
}
go func() {
for message := range ch {
if _, err := io.Copy(file, bytes.NewBuffer(message)); err != nil {
log.Errorln(probe.New(err))
log.Errorln(err)
}
}
}()

View file

@ -41,7 +41,7 @@ func (r *httpRange) String() string {
}
// Grab new range from request header
func getRequestedRange(hrange string, size int64) (*httpRange, error) {
func getRequestedRange(hrange string, size int64) (*httpRange, *probe.Error) {
r := &httpRange{
start: 0,
length: 0,
@ -51,16 +51,16 @@ func getRequestedRange(hrange string, size int64) (*httpRange, error) {
if hrange != "" {
err := r.parseRange(hrange)
if err != nil {
return nil, probe.New(err)
return nil, err.Trace()
}
}
return r, nil
}
func (r *httpRange) parse(ra string) error {
func (r *httpRange) parse(ra string) *probe.Error {
i := strings.Index(ra, "-")
if i < 0 {
return probe.New(donut.InvalidRange{})
return probe.NewError(donut.InvalidRange{})
}
start, end := strings.TrimSpace(ra[:i]), strings.TrimSpace(ra[i+1:])
if start == "" {
@ -68,7 +68,7 @@ func (r *httpRange) parse(ra string) error {
// range start relative to the end of the file.
i, err := strconv.ParseInt(end, 10, 64)
if err != nil {
return probe.New(donut.InvalidRange{})
return probe.NewError(donut.InvalidRange{})
}
if i > r.size {
i = r.size
@ -78,7 +78,7 @@ func (r *httpRange) parse(ra string) error {
} else {
i, err := strconv.ParseInt(start, 10, 64)
if err != nil || i > r.size || i < 0 {
return probe.New(donut.InvalidRange{})
return probe.NewError(donut.InvalidRange{})
}
r.start = i
if end == "" {
@ -87,7 +87,7 @@ func (r *httpRange) parse(ra string) error {
} else {
i, err := strconv.ParseInt(end, 10, 64)
if err != nil || r.start > i {
return probe.New(donut.InvalidRange{})
return probe.NewError(donut.InvalidRange{})
}
if i >= r.size {
i = r.size - 1
@ -99,26 +99,26 @@ func (r *httpRange) parse(ra string) error {
}
// parseRange parses a Range header string as per RFC 2616.
func (r *httpRange) parseRange(s string) error {
func (r *httpRange) parseRange(s string) *probe.Error {
if s == "" {
return probe.New(errors.New("header not present"))
return probe.NewError(errors.New("header not present"))
}
if !strings.HasPrefix(s, b) {
return probe.New(donut.InvalidRange{})
return probe.NewError(donut.InvalidRange{})
}
ras := strings.Split(s[len(b):], ",")
if len(ras) == 0 {
return probe.New(errors.New("invalid request"))
return probe.NewError(errors.New("invalid request"))
}
// Just pick the first one and ignore the rest, we only support one range per object
if len(ras) > 1 {
return probe.New(errors.New("multiple ranges specified"))
return probe.NewError(errors.New("multiple ranges specified"))
}
ra := strings.TrimSpace(ras[0])
if ra == "" {
return probe.New(donut.InvalidRange{})
return probe.NewError(donut.InvalidRange{})
}
return r.parse(ra)
}

View file

@ -72,7 +72,7 @@ func InitSignatureV4(req *http.Request) (*donut.Signature, *probe.Error) {
var err error
accessKeyID, err = StripAccessKeyID(ah)
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
}
authConfig, err := auth.LoadConfig()
@ -80,7 +80,7 @@ func InitSignatureV4(req *http.Request) (*donut.Signature, *probe.Error) {
return nil, err.Trace()
}
if _, ok := authConfig.Users[accessKeyID]; !ok {
return nil, probe.New(errors.New("AccessID not found"))
return nil, probe.NewError(errors.New("AccessID not found"))
}
signature := &donut.Signature{
AccessKeyID: authConfig.Users[accessKeyID].AccessKeyID,

View file

@ -52,8 +52,8 @@ func (s *MyAPIDonutCacheSuite) SetUpSuite(c *C) {
conf.Version = "0.0.1"
conf.MaxSize = 100000
donut.SetDonutConfigPath(filepath.Join(root, "donut.json"))
err = donut.SaveConfig(conf)
c.Assert(err, IsNil)
perr := donut.SaveConfig(conf)
c.Assert(perr, IsNil)
httpHandler, minioAPI := getAPIHandler(api.Config{RateLimit: 16})
go startTM(minioAPI)

View file

@ -71,8 +71,8 @@ func (s *MyAPIDonutSuite) SetUpSuite(c *C) {
conf.NodeDiskMap = createTestNodeDiskMap(root)
conf.MaxSize = 100000
donut.SetDonutConfigPath(filepath.Join(root, "donut.json"))
err = donut.SaveConfig(conf)
c.Assert(err, IsNil)
perr := donut.SaveConfig(conf)
c.Assert(perr, IsNil)
httpHandler, minioAPI := getAPIHandler(api.Config{RateLimit: 16})
go startTM(minioAPI)

View file

@ -60,13 +60,13 @@ func (s *MyAPISignatureV4Suite) SetUpSuite(c *C) {
conf.NodeDiskMap = createTestNodeDiskMap(root)
conf.MaxSize = 100000
donut.SetDonutConfigPath(filepath.Join(root, "donut.json"))
err = donut.SaveConfig(conf)
c.Assert(err, IsNil)
perr := donut.SaveConfig(conf)
c.Assert(perr, IsNil)
accessKeyID, err := auth.GenerateAccessKeyID()
c.Assert(err, IsNil)
secretAccessKey, err := auth.GenerateSecretAccessKey()
c.Assert(err, IsNil)
accessKeyID, perr := auth.GenerateAccessKeyID()
c.Assert(perr, IsNil)
secretAccessKey, perr := auth.GenerateSecretAccessKey()
c.Assert(perr, IsNil)
authConf := &auth.Config{}
authConf.Users = make(map[string]*auth.User)
@ -79,8 +79,8 @@ func (s *MyAPISignatureV4Suite) SetUpSuite(c *C) {
s.secretAccessKey = string(secretAccessKey)
auth.SetAuthConfigPath(filepath.Join(root, "users.json"))
err = auth.SaveConfig(authConf)
c.Assert(err, IsNil)
perr = auth.SaveConfig(authConf)
c.Assert(perr, IsNil)
httpHandler, minioAPI := getAPIHandler(api.Config{RateLimit: 16})
go startTM(minioAPI)

View file

@ -41,7 +41,7 @@ type app struct {
listeners []net.Listener
sds []httpdown.Server
net *minNet
errors chan error
errors chan *probe.Error
}
// listen initailize listeners
@ -79,7 +79,7 @@ func (a *app) wait() {
go func(s httpdown.Server) {
defer wg.Done()
if err := s.Wait(); err != nil {
a.errors <- probe.New(err)
a.errors <- probe.NewError(err)
}
}(s)
}
@ -101,7 +101,7 @@ func (a *app) trapSignal(wg *sync.WaitGroup) {
go func(s httpdown.Server) {
defer wg.Done()
if err := s.Stop(); err != nil {
a.errors <- probe.New(err)
a.errors <- probe.NewError(err)
}
}(s)
}
@ -112,7 +112,7 @@ func (a *app) trapSignal(wg *sync.WaitGroup) {
// we only return here if there's an error, otherwise the new process
// will send us a TERM when it's ready to trigger the actual shutdown.
if _, err := a.net.StartProcess(); err != nil {
a.errors <- probe.New(err)
a.errors <- err.Trace()
}
}
}
@ -129,7 +129,7 @@ func ListenAndServe(servers ...*http.Server) *probe.Error {
listeners: make([]net.Listener, 0, len(servers)),
sds: make([]httpdown.Server, 0, len(servers)),
net: &minNet{},
errors: make(chan error, 1+(len(servers)*2)),
errors: make(chan *probe.Error, 1+(len(servers)*2)),
}
// Acquire Listeners
@ -143,7 +143,7 @@ func ListenAndServe(servers ...*http.Server) *probe.Error {
// Close the parent if we inherited and it wasn't init that started us.
if os.Getenv("LISTEN_FDS") != "" && ppid != 1 {
if err := syscall.Kill(ppid, syscall.SIGTERM); err != nil {
return probe.New(err)
return probe.NewError(err)
}
}
@ -160,7 +160,7 @@ func ListenAndServe(servers ...*http.Server) *probe.Error {
if err == nil {
panic("unexpected nil error")
}
return probe.New(err)
return err.Trace()
case <-waitdone:
return nil
}
@ -176,7 +176,7 @@ func ListenAndServeLimited(connLimit int, servers ...*http.Server) *probe.Error
listeners: make([]net.Listener, 0, len(servers)),
sds: make([]httpdown.Server, 0, len(servers)),
net: &minNet{connLimit: connLimit},
errors: make(chan error, 1+(len(servers)*2)),
errors: make(chan *probe.Error, 1+(len(servers)*2)),
}
// Acquire Listeners
@ -190,7 +190,7 @@ func ListenAndServeLimited(connLimit int, servers ...*http.Server) *probe.Error
// Close the parent if we inherited and it wasn't init that started us.
if os.Getenv("LISTEN_FDS") != "" && ppid != 1 {
if err := syscall.Kill(ppid, syscall.SIGTERM); err != nil {
return probe.New(err)
return probe.NewError(err)
}
}
@ -207,7 +207,7 @@ func ListenAndServeLimited(connLimit int, servers ...*http.Server) *probe.Error
if err == nil {
panic("unexpected nil error")
}
return probe.New(err)
return err.Trace()
case <-waitdone:
return nil
}

View file

@ -82,7 +82,7 @@ func (n *minNet) getInheritedListeners() *probe.Error {
}
count, err := strconv.Atoi(countStr)
if err != nil {
retErr = probe.New(fmt.Errorf("found invalid count value: %s=%s", envCountKey, countStr))
retErr = probe.NewError(fmt.Errorf("found invalid count value: %s=%s", envCountKey, countStr))
return
}
@ -92,18 +92,18 @@ func (n *minNet) getInheritedListeners() *probe.Error {
l, err := net.FileListener(file)
if err != nil {
file.Close()
retErr = probe.New(err)
retErr = probe.NewError(err)
return
}
if err := file.Close(); err != nil {
retErr = probe.New(err)
retErr = probe.NewError(err)
return
}
n.inheritedListeners = append(n.inheritedListeners, l)
}
})
if retErr != nil {
return probe.New(retErr)
return retErr.Trace()
}
return nil
}
@ -115,17 +115,17 @@ func (n *minNet) getInheritedListeners() *probe.Error {
func (n *minNet) Listen(nett, laddr string) (net.Listener, *probe.Error) {
switch nett {
default:
return nil, probe.New(net.UnknownNetworkError(nett))
return nil, probe.NewError(net.UnknownNetworkError(nett))
case "tcp", "tcp4", "tcp6":
addr, err := net.ResolveTCPAddr(nett, laddr)
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
return n.ListenTCP(nett, addr)
case "unix", "unixpacket":
addr, err := net.ResolveUnixAddr(nett, laddr)
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
return n.ListenUnix(nett, addr)
}
@ -158,7 +158,7 @@ func (n *minNet) ListenTCP(nett string, laddr *net.TCPAddr) (net.Listener, *prob
// make a fresh listener
l, err := net.ListenTCP(nett, laddr)
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
n.activeListeners = append(n.activeListeners, rateLimitedListener(l, n.connLimit))
return l, nil
@ -191,7 +191,7 @@ func (n *minNet) ListenUnix(nett string, laddr *net.UnixAddr) (net.Listener, *pr
// make a fresh listener
l, err := net.ListenUnix(nett, laddr)
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
n.activeListeners = append(n.activeListeners, rateLimitedListener(l, n.connLimit))
return l, nil
@ -240,7 +240,7 @@ func (n *minNet) StartProcess() (int, *probe.Error) {
var err error
files[i], err = l.(fileListener).File()
if err != nil {
return 0, probe.New(err)
return 0, probe.NewError(err)
}
defer files[i].Close()
}
@ -249,7 +249,7 @@ func (n *minNet) StartProcess() (int, *probe.Error) {
// the file it points to has been changed we will use the updated symlink.
argv0, err := exec.LookPath(os.Args[0])
if err != nil {
return 0, probe.New(err)
return 0, probe.NewError(err)
}
// Pass on the environment and replace the old count key with the new one.
@ -268,7 +268,7 @@ func (n *minNet) StartProcess() (int, *probe.Error) {
Files: allFiles,
})
if err != nil {
return 0, probe.New(err)
return 0, probe.NewError(err)
}
return process.Pid, nil
}

View file

@ -49,7 +49,7 @@ func getAuth(reply *AuthReply) *probe.Error {
// Get auth keys
func (s *AuthService) Get(r *http.Request, args *Args, reply *AuthReply) error {
if err := getAuth(reply); err != nil {
return err
return probe.NewWrappedError(err)
}
return nil
}

View file

@ -56,5 +56,8 @@ func setDonut(args *DonutArgs, reply *Reply) *probe.Error {
// Set method
func (s *DonutService) Set(r *http.Request, args *DonutArgs, reply *Reply) error {
return setDonut(args, reply)
if err := setDonut(args, reply); err != nil {
return probe.NewWrappedError(err)
}
return nil
}

View file

@ -55,7 +55,7 @@ func setSysInfoReply(sis *SysInfoReply) *probe.Error {
var err error
sis.Hostname, err = os.Hostname()
if err != nil {
return probe.New(err)
return probe.NewError(err)
}
return nil
}
@ -70,7 +70,7 @@ func setMemStatsReply(sis *MemStatsReply) *probe.Error {
// Get method
func (s *SysInfoService) Get(r *http.Request, args *Args, reply *SysInfoReply) error {
if err := setSysInfoReply(reply); err != nil {
return err
return probe.NewWrappedError(err)
}
return nil
}
@ -78,7 +78,7 @@ func (s *SysInfoService) Get(r *http.Request, args *Args, reply *SysInfoReply) e
// Get method
func (s *MemStatsService) Get(r *http.Request, args *Args, reply *MemStatsReply) error {
if err := setMemStatsReply(reply); err != nil {
return err
return probe.NewWrappedError(err)
}
return nil
}

View file

@ -44,13 +44,13 @@ func getAPIServer(conf api.Config, apiHandler http.Handler) (*http.Server, *prob
httpServer.TLSConfig.Certificates = make([]tls.Certificate, 1)
httpServer.TLSConfig.Certificates[0], err = tls.LoadX509KeyPair(conf.CertFile, conf.KeyFile)
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
}
host, port, err := net.SplitHostPort(conf.Address)
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
var hosts []string
@ -60,7 +60,7 @@ func getAPIServer(conf api.Config, apiHandler http.Handler) (*http.Server, *prob
default:
addrs, err := net.InterfaceAddrs()
if err != nil {
return nil, probe.New(err)
return nil, probe.NewError(err)
}
for _, addr := range addrs {
if addr.Network() == "ip+net" {