func (cache *cacheDriver) listObjects(keys []string, key string, r drivers.BucketResourcesMetadata) ([]string, drivers.BucketResourcesMetadata) { switch true { // Prefix absent, delimit object key based on delimiter case r.IsDelimiterSet(): delim := delimiter(key, r.Delimiter) switch true { case delim == "" || delim == key: keys = appendUniq(keys, key) case delim != "": r.CommonPrefixes = appendUniq(r.CommonPrefixes, delim) } // Prefix present, delimit object key with prefix key based on delimiter case r.IsDelimiterPrefixSet(): if strings.HasPrefix(key, r.Prefix) { trimmedName := strings.TrimPrefix(key, r.Prefix) delim := delimiter(trimmedName, r.Delimiter) keys, r = cache.filterDelimiterPrefix(keys, key, delim, r) } // Prefix present, nothing to delimit case r.IsPrefixSet(): keys = appendUniq(keys, key) // Prefix and delimiter absent case r.IsDefault(): keys = appendUniq(keys, key) } return keys, r }
// ListObjects - GET bucket (list objects) func (fs *fsDriver) ListObjects(bucket string, resources drivers.BucketResourcesMetadata) ([]drivers.ObjectMetadata, drivers.BucketResourcesMetadata, error) { p := bucketDir{} p.files = make(map[string]os.FileInfo) if drivers.IsValidBucket(bucket) == false { return []drivers.ObjectMetadata{}, resources, iodine.New(drivers.BucketNameInvalid{Bucket: bucket}, nil) } if resources.Prefix != "" && drivers.IsValidObjectName(resources.Prefix) == false { return []drivers.ObjectMetadata{}, resources, iodine.New(drivers.ObjectNameInvalid{Bucket: bucket, Object: resources.Prefix}, nil) } rootPrefix := filepath.Join(fs.root, bucket) // check bucket exists if _, err := os.Stat(rootPrefix); os.IsNotExist(err) { return []drivers.ObjectMetadata{}, resources, iodine.New(drivers.BucketNotFound{Bucket: bucket}, nil) } p.root = rootPrefix err := filepath.Walk(rootPrefix, p.getAllFiles) if err != nil { return []drivers.ObjectMetadata{}, resources, iodine.New(err, nil) } var metadataList []drivers.ObjectMetadata var metadata drivers.ObjectMetadata // Populate filtering mode resources.Mode = drivers.GetMode(resources) var fileNames []string for name := range p.files { fileNames = append(fileNames, name) } sort.Strings(fileNames) for _, name := range fileNames { if len(metadataList) >= resources.Maxkeys { resources.IsTruncated = true if resources.IsTruncated && resources.IsDelimiterSet() { resources.NextMarker = metadataList[len(metadataList)-1].Key } break } if name > resources.Marker { metadata, resources, err = fs.filterObjects(bucket, name, p.files[name], resources) if err != nil { return []drivers.ObjectMetadata{}, resources, iodine.New(err, nil) } if metadata.Bucket != "" { metadataList = append(metadataList, metadata) } } } sort.Sort(byObjectKey(metadataList)) return metadataList, resources, nil }
// ListObjects - returns list of objects func (d donutDriver) ListObjects(bucketName string, resources drivers.BucketResourcesMetadata) ([]drivers.ObjectMetadata, drivers.BucketResourcesMetadata, error) { errParams := map[string]string{ "bucketName": bucketName, } if d.donut == nil { return nil, drivers.BucketResourcesMetadata{}, iodine.New(drivers.InternalError{}, errParams) } if !drivers.IsValidBucket(bucketName) || strings.Contains(bucketName, ".") { return nil, drivers.BucketResourcesMetadata{}, iodine.New(drivers.BucketNameInvalid{Bucket: bucketName}, nil) } if !drivers.IsValidObjectName(resources.Prefix) { return nil, drivers.BucketResourcesMetadata{}, iodine.New(drivers.ObjectNameInvalid{Object: resources.Prefix}, nil) } actualObjects, commonPrefixes, isTruncated, err := d.donut.ListObjects(bucketName, resources.Prefix, resources.Marker, resources.Delimiter, resources.Maxkeys) if err != nil { return nil, drivers.BucketResourcesMetadata{}, iodine.New(err, errParams) } resources.CommonPrefixes = commonPrefixes resources.IsTruncated = isTruncated if resources.IsTruncated && resources.IsDelimiterSet() { resources.NextMarker = actualObjects[len(actualObjects)-1] } var results []drivers.ObjectMetadata for _, objectName := range actualObjects { objectMetadata, err := d.donut.GetObjectMetadata(bucketName, objectName) if err != nil { return nil, drivers.BucketResourcesMetadata{}, iodine.New(err, errParams) } t, err := time.Parse(time.RFC3339Nano, objectMetadata["created"]) if err != nil { return nil, drivers.BucketResourcesMetadata{}, iodine.New(err, nil) } size, err := strconv.ParseInt(objectMetadata["size"], 10, 64) if err != nil { return nil, drivers.BucketResourcesMetadata{}, iodine.New(err, nil) } metadata := drivers.ObjectMetadata{ Key: objectName, Created: t, Size: size, } results = append(results, metadata) } sort.Sort(byObjectKey(results)) return results, resources, nil }
// ListObjects - list objects from cache func (cache *cacheDriver) ListObjects(bucket string, resources drivers.BucketResourcesMetadata) ([]drivers.ObjectMetadata, drivers.BucketResourcesMetadata, error) { cache.lock.RLock() defer cache.lock.RUnlock() if !drivers.IsValidBucket(bucket) { return nil, drivers.BucketResourcesMetadata{IsTruncated: false}, iodine.New(drivers.BucketNameInvalid{Bucket: bucket}, nil) } if !drivers.IsValidObjectName(resources.Prefix) { return nil, drivers.BucketResourcesMetadata{IsTruncated: false}, iodine.New(drivers.ObjectNameInvalid{Object: resources.Prefix}, nil) } if _, ok := cache.storedBuckets[bucket]; ok == false { return nil, drivers.BucketResourcesMetadata{IsTruncated: false}, iodine.New(drivers.BucketNotFound{Bucket: bucket}, nil) } var results []drivers.ObjectMetadata var keys []string storedBucket := cache.storedBuckets[bucket] for key := range storedBucket.objectMetadata { if strings.HasPrefix(key, bucket+"/") { key = key[len(bucket)+1:] keys, resources = cache.listObjects(keys, key, resources) } } var newKeys []string switch { case resources.Marker != "": for _, key := range keys { if key > resources.Marker { newKeys = appendUniq(newKeys, key) } } default: newKeys = keys } sort.Strings(newKeys) for _, key := range newKeys { if len(results) == resources.Maxkeys { resources.IsTruncated = true if resources.IsTruncated && resources.IsDelimiterSet() { resources.NextMarker = results[len(results)-1].Key } return results, resources, nil } object := storedBucket.objectMetadata[bucket+"/"+key] results = append(results, object) } return results, resources, nil }
// ListObjects - returns list of objects func (d donutDriver) ListObjects(bucketName string, resources drivers.BucketResourcesMetadata) ([]drivers.ObjectMetadata, drivers.BucketResourcesMetadata, error) { d.lock.RLock() defer d.lock.RUnlock() errParams := map[string]string{ "bucketName": bucketName, } if d.donut == nil { return nil, drivers.BucketResourcesMetadata{}, iodine.New(drivers.InternalError{}, errParams) } if !drivers.IsValidBucket(bucketName) { return nil, drivers.BucketResourcesMetadata{}, iodine.New(drivers.BucketNameInvalid{Bucket: bucketName}, nil) } if !drivers.IsValidObjectName(resources.Prefix) { return nil, drivers.BucketResourcesMetadata{}, iodine.New(drivers.ObjectNameInvalid{Object: resources.Prefix}, nil) } listObjects, err := d.donut.ListObjects(bucketName, resources.Prefix, resources.Marker, resources.Delimiter, resources.Maxkeys) if err != nil { return nil, drivers.BucketResourcesMetadata{}, iodine.New(err, errParams) } resources.CommonPrefixes = listObjects.CommonPrefixes resources.IsTruncated = listObjects.IsTruncated var results []drivers.ObjectMetadata for _, objMetadata := range listObjects.Objects { metadata := drivers.ObjectMetadata{ Key: objMetadata.Object, Created: objMetadata.Created, Size: objMetadata.Size, } results = append(results, metadata) } sort.Sort(byObjectName(results)) if resources.IsTruncated && resources.IsDelimiterSet() { resources.NextMarker = results[len(results)-1].Key } return results, resources, nil }
func (fs *fsDriver) filterObjects(bucket, name string, file os.FileInfo, resources drivers.BucketResourcesMetadata) (drivers.ObjectMetadata, drivers.BucketResourcesMetadata, error) { var err error var metadata drivers.ObjectMetadata switch true { // Both delimiter and Prefix is present case resources.IsDelimiterPrefixSet(): if strings.HasPrefix(name, resources.Prefix) { trimmedName := strings.TrimPrefix(name, resources.Prefix) delimitedName := delimiter(trimmedName, resources.Delimiter) switch true { case name == resources.Prefix: // Use resources.Prefix to filter out delimited files metadata, err = fs.GetObjectMetadata(bucket, name) if err != nil { return drivers.ObjectMetadata{}, resources, iodine.New(err, nil) } case delimitedName == file.Name(): // Use resources.Prefix to filter out delimited files metadata, err = fs.GetObjectMetadata(bucket, name) if err != nil { return drivers.ObjectMetadata{}, resources, iodine.New(err, nil) } case delimitedName != "": resources.CommonPrefixes = appendUniq(resources.CommonPrefixes, resources.Prefix+delimitedName) } } // Delimiter present and Prefix is absent case resources.IsDelimiterSet(): delimitedName := delimiter(name, resources.Delimiter) switch true { case delimitedName == "": metadata, err = fs.GetObjectMetadata(bucket, name) if err != nil { return drivers.ObjectMetadata{}, resources, iodine.New(err, nil) } case delimitedName == file.Name(): metadata, err = fs.GetObjectMetadata(bucket, name) if err != nil { return drivers.ObjectMetadata{}, resources, iodine.New(err, nil) } case delimitedName != "": resources.CommonPrefixes = appendUniq(resources.CommonPrefixes, delimitedName) } // Delimiter is absent and only Prefix is present case resources.IsPrefixSet(): if strings.HasPrefix(name, resources.Prefix) { // Do not strip prefix object output metadata, err = fs.GetObjectMetadata(bucket, name) if err != nil { return drivers.ObjectMetadata{}, resources, iodine.New(err, nil) } } case resources.IsDefault(): metadata, err = fs.GetObjectMetadata(bucket, name) if err != nil { return drivers.ObjectMetadata{}, resources, iodine.New(err, nil) } } return metadata, resources, nil }