mirror of https://github.com/minio/minio.git
				
				
				
			Use getObjectInfo() in both FS and XL ListObjects() to simplify and to return complete object information (#3247)
This commit is contained in:
		
							parent
							
								
									716316f711
								
							
						
					
					
						commit
						380d6c6435
					
				
							
								
								
									
										47
									
								
								cmd/fs-v1.go
								
								
								
								
							
							
						
						
									
										47
									
								
								cmd/fs-v1.go
								
								
								
								
							|  | @ -24,7 +24,6 @@ import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"hash" | 	"hash" | ||||||
| 	"io" | 	"io" | ||||||
| 	"os" |  | ||||||
| 	"path" | 	"path" | ||||||
| 	"sort" | 	"sort" | ||||||
| 	"strings" | 	"strings" | ||||||
|  | @ -502,27 +501,17 @@ func (fs fsObjects) DeleteObject(bucket, object string) error { | ||||||
| // ListObjects - list all objects at prefix upto maxKeys., optionally delimited by '/'. Maintains the list pool
 | // ListObjects - list all objects at prefix upto maxKeys., optionally delimited by '/'. Maintains the list pool
 | ||||||
| // state for future re-entrant list requests.
 | // state for future re-entrant list requests.
 | ||||||
| func (fs fsObjects) ListObjects(bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsInfo, error) { | func (fs fsObjects) ListObjects(bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsInfo, error) { | ||||||
| 	// Convert entry to FileInfo
 | 	// Convert entry to ObjectInfo
 | ||||||
| 	entryToFileInfo := func(entry string) (fileInfo FileInfo, err error) { | 	entryToObjectInfo := func(entry string) (objInfo ObjectInfo, err error) { | ||||||
| 		if strings.HasSuffix(entry, slashSeparator) { | 		if strings.HasSuffix(entry, slashSeparator) { | ||||||
| 			// Object name needs to be full path.
 | 			// Object name needs to be full path.
 | ||||||
| 			fileInfo.Name = entry | 			objInfo.Name = entry | ||||||
| 			fileInfo.Mode = os.ModeDir | 			objInfo.IsDir = true | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		if fileInfo, err = fs.storage.StatFile(bucket, entry); err != nil { | 		if objInfo, err = fs.getObjectInfo(bucket, entry); err != nil { | ||||||
| 			return FileInfo{}, traceError(err) | 			return ObjectInfo{}, err | ||||||
| 		} | 		} | ||||||
| 		fsMeta, mErr := readFSMetadata(fs.storage, minioMetaBucket, path.Join(bucketMetaPrefix, bucket, entry, fsMetaJSONFile)) |  | ||||||
| 		if mErr != nil && errorCause(mErr) != errFileNotFound { |  | ||||||
| 			return FileInfo{}, traceError(mErr) |  | ||||||
| 		} |  | ||||||
| 		if len(fsMeta.Meta) == 0 { |  | ||||||
| 			fsMeta.Meta = make(map[string]string) |  | ||||||
| 		} |  | ||||||
| 		// Object name needs to be full path.
 |  | ||||||
| 		fileInfo.Name = entry |  | ||||||
| 		fileInfo.MD5Sum = fsMeta.Meta["md5Sum"] |  | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -591,7 +580,7 @@ func (fs fsObjects) ListObjects(bucket, prefix, marker, delimiter string, maxKey | ||||||
| 		listDir := listDirFactory(isLeaf, fsTreeWalkIgnoredErrs, fs.storage) | 		listDir := listDirFactory(isLeaf, fsTreeWalkIgnoredErrs, fs.storage) | ||||||
| 		walkResultCh = startTreeWalk(bucket, prefix, marker, recursive, listDir, isLeaf, endWalkCh) | 		walkResultCh = startTreeWalk(bucket, prefix, marker, recursive, listDir, isLeaf, endWalkCh) | ||||||
| 	} | 	} | ||||||
| 	var fileInfos []FileInfo | 	var objInfos []ObjectInfo | ||||||
| 	var eof bool | 	var eof bool | ||||||
| 	var nextMarker string | 	var nextMarker string | ||||||
| 	for i := 0; i < maxKeys; { | 	for i := 0; i < maxKeys; { | ||||||
|  | @ -609,12 +598,12 @@ func (fs fsObjects) ListObjects(bucket, prefix, marker, delimiter string, maxKey | ||||||
| 			} | 			} | ||||||
| 			return ListObjectsInfo{}, toObjectErr(walkResult.err, bucket, prefix) | 			return ListObjectsInfo{}, toObjectErr(walkResult.err, bucket, prefix) | ||||||
| 		} | 		} | ||||||
| 		fileInfo, err := entryToFileInfo(walkResult.entry) | 		objInfo, err := entryToObjectInfo(walkResult.entry) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return ListObjectsInfo{}, nil | 			return ListObjectsInfo{}, nil | ||||||
| 		} | 		} | ||||||
| 		nextMarker = fileInfo.Name | 		nextMarker = objInfo.Name | ||||||
| 		fileInfos = append(fileInfos, fileInfo) | 		objInfos = append(objInfos, objInfo) | ||||||
| 		if walkResult.end { | 		if walkResult.end { | ||||||
| 			eof = true | 			eof = true | ||||||
| 			break | 			break | ||||||
|  | @ -627,19 +616,13 @@ func (fs fsObjects) ListObjects(bucket, prefix, marker, delimiter string, maxKey | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	result := ListObjectsInfo{IsTruncated: !eof} | 	result := ListObjectsInfo{IsTruncated: !eof} | ||||||
| 	for _, fileInfo := range fileInfos { | 	for _, objInfo := range objInfos { | ||||||
| 		result.NextMarker = fileInfo.Name | 		result.NextMarker = objInfo.Name | ||||||
| 		if fileInfo.Mode.IsDir() { | 		if objInfo.IsDir { | ||||||
| 			result.Prefixes = append(result.Prefixes, fileInfo.Name) | 			result.Prefixes = append(result.Prefixes, objInfo.Name) | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 		result.Objects = append(result.Objects, ObjectInfo{ | 		result.Objects = append(result.Objects, objInfo) | ||||||
| 			Name:    fileInfo.Name, |  | ||||||
| 			ModTime: fileInfo.ModTime, |  | ||||||
| 			Size:    fileInfo.Size, |  | ||||||
| 			MD5Sum:  fileInfo.MD5Sum, |  | ||||||
| 			IsDir:   false, |  | ||||||
| 		}) |  | ||||||
| 	} | 	} | ||||||
| 	return result, nil | 	return result, nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -51,20 +51,21 @@ func testListObjects(obj ObjectLayer, instanceType string, t TestErrHandler) { | ||||||
| 	testObjects := []struct { | 	testObjects := []struct { | ||||||
| 		name    string | 		name    string | ||||||
| 		content string | 		content string | ||||||
|  | 		meta    map[string]string | ||||||
| 	}{ | 	}{ | ||||||
| 		{"Asia-maps", "asis-maps"}, | 		{"Asia-maps.png", "asis-maps", map[string]string{"content-type": "image/png"}}, | ||||||
| 		{"Asia/India/India-summer-photos-1", "contentstring"}, | 		{"Asia/India/India-summer-photos-1", "contentstring", nil}, | ||||||
| 		{"Asia/India/Karnataka/Bangalore/Koramangala/pics", "contentstring"}, | 		{"Asia/India/Karnataka/Bangalore/Koramangala/pics", "contentstring", nil}, | ||||||
| 		{"newPrefix0", "newPrefix0"}, | 		{"newPrefix0", "newPrefix0", nil}, | ||||||
| 		{"newPrefix1", "newPrefix1"}, | 		{"newPrefix1", "newPrefix1", nil}, | ||||||
| 		{"newzen/zen/recurse/again/again/again/pics", "recurse"}, | 		{"newzen/zen/recurse/again/again/again/pics", "recurse", nil}, | ||||||
| 		{"obj0", "obj0"}, | 		{"obj0", "obj0", nil}, | ||||||
| 		{"obj1", "obj1"}, | 		{"obj1", "obj1", nil}, | ||||||
| 		{"obj2", "obj2"}, | 		{"obj2", "obj2", nil}, | ||||||
| 	} | 	} | ||||||
| 	sha256sum := "" | 	sha256sum := "" | ||||||
| 	for _, object := range testObjects { | 	for _, object := range testObjects { | ||||||
| 		_, err = obj.PutObject(testBuckets[0], object.name, int64(len(object.content)), bytes.NewBufferString(object.content), nil, sha256sum) | 		_, err = obj.PutObject(testBuckets[0], object.name, int64(len(object.content)), bytes.NewBufferString(object.content), object.meta, sha256sum) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			t.Fatalf("%s : %s", instanceType, err.Error()) | 			t.Fatalf("%s : %s", instanceType, err.Error()) | ||||||
| 		} | 		} | ||||||
|  | @ -80,7 +81,7 @@ func testListObjects(obj ObjectLayer, instanceType string, t TestErrHandler) { | ||||||
| 		{ | 		{ | ||||||
| 			IsTruncated: false, | 			IsTruncated: false, | ||||||
| 			Objects: []ObjectInfo{ | 			Objects: []ObjectInfo{ | ||||||
| 				{Name: "Asia-maps"}, | 				{Name: "Asia-maps.png", ContentType: "image/png"}, | ||||||
| 				{Name: "Asia/India/India-summer-photos-1"}, | 				{Name: "Asia/India/India-summer-photos-1"}, | ||||||
| 				{Name: "Asia/India/Karnataka/Bangalore/Koramangala/pics"}, | 				{Name: "Asia/India/Karnataka/Bangalore/Koramangala/pics"}, | ||||||
| 				{Name: "newPrefix0"}, | 				{Name: "newPrefix0"}, | ||||||
|  | @ -96,7 +97,7 @@ func testListObjects(obj ObjectLayer, instanceType string, t TestErrHandler) { | ||||||
| 		{ | 		{ | ||||||
| 			IsTruncated: true, | 			IsTruncated: true, | ||||||
| 			Objects: []ObjectInfo{ | 			Objects: []ObjectInfo{ | ||||||
| 				{Name: "Asia-maps"}, | 				{Name: "Asia-maps.png", ContentType: "image/png"}, | ||||||
| 				{Name: "Asia/India/India-summer-photos-1"}, | 				{Name: "Asia/India/India-summer-photos-1"}, | ||||||
| 				{Name: "Asia/India/Karnataka/Bangalore/Koramangala/pics"}, | 				{Name: "Asia/India/Karnataka/Bangalore/Koramangala/pics"}, | ||||||
| 				{Name: "newPrefix0"}, | 				{Name: "newPrefix0"}, | ||||||
|  | @ -108,7 +109,7 @@ func testListObjects(obj ObjectLayer, instanceType string, t TestErrHandler) { | ||||||
| 		{ | 		{ | ||||||
| 			IsTruncated: true, | 			IsTruncated: true, | ||||||
| 			Objects: []ObjectInfo{ | 			Objects: []ObjectInfo{ | ||||||
| 				{Name: "Asia-maps"}, | 				{Name: "Asia-maps.png", ContentType: "image/png"}, | ||||||
| 				{Name: "Asia/India/India-summer-photos-1"}, | 				{Name: "Asia/India/India-summer-photos-1"}, | ||||||
| 				{Name: "Asia/India/Karnataka/Bangalore/Koramangala/pics"}, | 				{Name: "Asia/India/Karnataka/Bangalore/Koramangala/pics"}, | ||||||
| 				{Name: "newPrefix0"}, | 				{Name: "newPrefix0"}, | ||||||
|  | @ -119,7 +120,7 @@ func testListObjects(obj ObjectLayer, instanceType string, t TestErrHandler) { | ||||||
| 		{ | 		{ | ||||||
| 			IsTruncated: true, | 			IsTruncated: true, | ||||||
| 			Objects: []ObjectInfo{ | 			Objects: []ObjectInfo{ | ||||||
| 				{Name: "Asia-maps"}, | 				{Name: "Asia-maps.png", ContentType: "image/png"}, | ||||||
| 				{Name: "Asia/India/India-summer-photos-1"}, | 				{Name: "Asia/India/India-summer-photos-1"}, | ||||||
| 				{Name: "Asia/India/Karnataka/Bangalore/Koramangala/pics"}, | 				{Name: "Asia/India/Karnataka/Bangalore/Koramangala/pics"}, | ||||||
| 			}, | 			}, | ||||||
|  | @ -130,7 +131,7 @@ func testListObjects(obj ObjectLayer, instanceType string, t TestErrHandler) { | ||||||
| 		{ | 		{ | ||||||
| 			IsTruncated: true, | 			IsTruncated: true, | ||||||
| 			Objects: []ObjectInfo{ | 			Objects: []ObjectInfo{ | ||||||
| 				{Name: "Asia-maps"}, | 				{Name: "Asia-maps.png", ContentType: "image/png"}, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
| 		// ListObjectsResult-5.
 | 		// ListObjectsResult-5.
 | ||||||
|  | @ -233,7 +234,7 @@ func testListObjects(obj ObjectLayer, instanceType string, t TestErrHandler) { | ||||||
| 		{ | 		{ | ||||||
| 			IsTruncated: false, | 			IsTruncated: false, | ||||||
| 			Objects: []ObjectInfo{ | 			Objects: []ObjectInfo{ | ||||||
| 				{Name: "Asia-maps"}, | 				{Name: "Asia-maps.png", ContentType: "image/png"}, | ||||||
| 				{Name: "Asia/India/India-summer-photos-1"}, | 				{Name: "Asia/India/India-summer-photos-1"}, | ||||||
| 				{Name: "Asia/India/Karnataka/Bangalore/Koramangala/pics"}, | 				{Name: "Asia/India/Karnataka/Bangalore/Koramangala/pics"}, | ||||||
| 				{Name: "newPrefix0"}, | 				{Name: "newPrefix0"}, | ||||||
|  | @ -342,7 +343,7 @@ func testListObjects(obj ObjectLayer, instanceType string, t TestErrHandler) { | ||||||
| 		{ | 		{ | ||||||
| 			IsTruncated: false, | 			IsTruncated: false, | ||||||
| 			Objects: []ObjectInfo{ | 			Objects: []ObjectInfo{ | ||||||
| 				{Name: "Asia-maps"}, | 				{Name: "Asia-maps.png", ContentType: "image/png"}, | ||||||
| 				{Name: "Asia/India/India-summer-photos-1"}, | 				{Name: "Asia/India/India-summer-photos-1"}, | ||||||
| 				{Name: "Asia/India/Karnataka/Bangalore/Koramangala/pics"}, | 				{Name: "Asia/India/Karnataka/Bangalore/Koramangala/pics"}, | ||||||
| 			}, | 			}, | ||||||
|  | @ -353,7 +354,7 @@ func testListObjects(obj ObjectLayer, instanceType string, t TestErrHandler) { | ||||||
| 		{ | 		{ | ||||||
| 			IsTruncated: false, | 			IsTruncated: false, | ||||||
| 			Objects: []ObjectInfo{ | 			Objects: []ObjectInfo{ | ||||||
| 				{Name: "Asia-maps"}, | 				{Name: "Asia-maps.png", ContentType: "image/png"}, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
| 		// ListObjectsResult-26.
 | 		// ListObjectsResult-26.
 | ||||||
|  | @ -548,6 +549,10 @@ func testListObjects(obj ObjectLayer, instanceType string, t TestErrHandler) { | ||||||
| 				if testCase.result.Objects[j].Name != result.Objects[j].Name { | 				if testCase.result.Objects[j].Name != result.Objects[j].Name { | ||||||
| 					t.Errorf("Test %d: %s: Expected object name to be \"%s\", but found \"%s\" instead", i+1, instanceType, testCase.result.Objects[j].Name, result.Objects[j].Name) | 					t.Errorf("Test %d: %s: Expected object name to be \"%s\", but found \"%s\" instead", i+1, instanceType, testCase.result.Objects[j].Name, result.Objects[j].Name) | ||||||
| 				} | 				} | ||||||
|  | 				if testCase.result.Objects[j].ContentType != result.Objects[j].ContentType { | ||||||
|  | 					t.Errorf("Test %d: %s: Expected object contentType to be \"%s\", but found \"%s\" instead", i+1, instanceType, testCase.result.Objects[j].ContentType, result.Objects[j].ContentType) | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
| 			} | 			} | ||||||
| 			if testCase.result.IsTruncated != result.IsTruncated { | 			if testCase.result.IsTruncated != result.IsTruncated { | ||||||
| 				t.Errorf("Test %d: %s: Expected IsTruncated flag to be %v, but instead found it to be %v", i+1, instanceType, testCase.result.IsTruncated, result.IsTruncated) | 				t.Errorf("Test %d: %s: Expected IsTruncated flag to be %v, but instead found it to be %v", i+1, instanceType, testCase.result.IsTruncated, result.IsTruncated) | ||||||
|  |  | ||||||
|  | @ -46,7 +46,4 @@ type FileInfo struct { | ||||||
| 
 | 
 | ||||||
| 	// File mode bits.
 | 	// File mode bits.
 | ||||||
| 	Mode os.FileMode | 	Mode os.FileMode | ||||||
| 
 |  | ||||||
| 	// Hex encoded md5 checksum of the file.
 |  | ||||||
| 	MD5Sum string |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -93,13 +93,7 @@ func (xl xlObjects) listObjects(bucket, prefix, marker, delimiter string, maxKey | ||||||
| 			result.Prefixes = append(result.Prefixes, objInfo.Name) | 			result.Prefixes = append(result.Prefixes, objInfo.Name) | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 		result.Objects = append(result.Objects, ObjectInfo{ | 		result.Objects = append(result.Objects, objInfo) | ||||||
| 			Name:    objInfo.Name, |  | ||||||
| 			ModTime: objInfo.ModTime, |  | ||||||
| 			Size:    objInfo.Size, |  | ||||||
| 			MD5Sum:  objInfo.MD5Sum, |  | ||||||
| 			IsDir:   false, |  | ||||||
| 		}) |  | ||||||
| 	} | 	} | ||||||
| 	return result, nil | 	return result, nil | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue