Add additional OneDrive metadata to backup details (#952)
## Description Adds file size and timestamps to enable selectors using this metadata ## Type of change - [x] 🌻 Feature - [ ] 🐛 Bugfix - [ ] 🗺️ Documentation - [ ] 🤖 Test - [ ] 💻 CI/Deployment - [ ] 🐹 Trivial/Minor ## Issue(s) * #594 ## Test Plan <!-- How will this be tested prior to merging.--> - [ ] 💪 Manual - [x] ⚡ Unit test - [x] 💚 E2E
This commit is contained in:
parent
ea73873ffb
commit
1df48997ae
@ -45,7 +45,7 @@ type itemReaderFunc func(
|
||||
ctx context.Context,
|
||||
service graph.Service,
|
||||
driveID, itemID string,
|
||||
) (name string, itemData io.ReadCloser, err error)
|
||||
) (itemInfo *details.OneDriveInfo, itemData io.ReadCloser, err error)
|
||||
|
||||
// NewCollection creates a Collection
|
||||
func NewCollection(
|
||||
@ -113,7 +113,7 @@ func (oc *Collection) populateItems(ctx context.Context) {
|
||||
|
||||
for _, itemID := range oc.driveItemIDs {
|
||||
// Read the item
|
||||
itemName, itemData, err := oc.itemReader(ctx, oc.service, oc.driveID, itemID)
|
||||
itemInfo, itemData, err := oc.itemReader(ctx, oc.service, oc.driveID, itemID)
|
||||
if err != nil {
|
||||
errs = support.WrapAndAppendf(itemID, err, errs)
|
||||
|
||||
@ -125,14 +125,13 @@ func (oc *Collection) populateItems(ctx context.Context) {
|
||||
}
|
||||
// Item read successfully, add to collection
|
||||
itemsRead++
|
||||
|
||||
itemInfo.ParentPath = oc.folderPath.String()
|
||||
|
||||
oc.data <- &Item{
|
||||
id: itemName,
|
||||
id: itemInfo.ItemName,
|
||||
data: itemData,
|
||||
info: &details.OneDriveInfo{
|
||||
ItemType: details.OneDriveItem,
|
||||
ItemName: itemName,
|
||||
ParentPath: oc.folderPath.String(),
|
||||
},
|
||||
info: itemInfo,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@ import (
|
||||
"github.com/alcionai/corso/src/internal/connector/graph"
|
||||
"github.com/alcionai/corso/src/internal/connector/support"
|
||||
"github.com/alcionai/corso/src/internal/data"
|
||||
"github.com/alcionai/corso/src/pkg/backup/details"
|
||||
)
|
||||
|
||||
type OneDriveCollectionSuite struct {
|
||||
@ -73,8 +74,8 @@ func (suite *OneDriveCollectionSuite) TestOneDriveCollection() {
|
||||
// Set a item reader, add an item and validate we get the item back
|
||||
coll.Add(testItemID)
|
||||
|
||||
coll.itemReader = func(context.Context, graph.Service, string, string) (string, io.ReadCloser, error) {
|
||||
return testItemName, io.NopCloser(bytes.NewReader(testItemData)), nil
|
||||
coll.itemReader = func(context.Context, graph.Service, string, string) (*details.OneDriveInfo, io.ReadCloser, error) {
|
||||
return &details.OneDriveInfo{ItemName: testItemName}, io.NopCloser(bytes.NewReader(testItemData)), nil
|
||||
}
|
||||
|
||||
// Read items from the collection
|
||||
@ -122,8 +123,8 @@ func (suite *OneDriveCollectionSuite) TestOneDriveCollectionReadError() {
|
||||
|
||||
readError := errors.New("Test error")
|
||||
|
||||
coll.itemReader = func(context.Context, graph.Service, string, string) (name string, data io.ReadCloser, err error) {
|
||||
return "", nil, readError
|
||||
coll.itemReader = func(context.Context, graph.Service, string, string) (*details.OneDriveInfo, io.ReadCloser, error) {
|
||||
return nil, nil, readError
|
||||
}
|
||||
|
||||
coll.Items()
|
||||
|
||||
@ -14,6 +14,7 @@ import (
|
||||
|
||||
"github.com/alcionai/corso/src/internal/connector/graph"
|
||||
"github.com/alcionai/corso/src/internal/connector/support"
|
||||
"github.com/alcionai/corso/src/pkg/backup/details"
|
||||
"github.com/alcionai/corso/src/pkg/logger"
|
||||
)
|
||||
|
||||
@ -30,19 +31,19 @@ func driveItemReader(
|
||||
ctx context.Context,
|
||||
service graph.Service,
|
||||
driveID, itemID string,
|
||||
) (string, io.ReadCloser, error) {
|
||||
) (*details.OneDriveInfo, io.ReadCloser, error) {
|
||||
logger.Ctx(ctx).Debugf("Reading Item %s at %s", itemID, time.Now())
|
||||
|
||||
item, err := service.Client().DrivesById(driveID).ItemsById(itemID).Get(ctx, nil)
|
||||
if err != nil {
|
||||
return "", nil, errors.Wrapf(err, "failed to get item %s", itemID)
|
||||
return nil, nil, errors.Wrapf(err, "failed to get item %s", itemID)
|
||||
}
|
||||
|
||||
// Get the download URL - https://docs.microsoft.com/en-us/graph/api/driveitem-get-content
|
||||
// These URLs are pre-authenticated and can be used to download the data using the standard
|
||||
// http client
|
||||
if _, found := item.GetAdditionalData()[downloadURLKey]; !found {
|
||||
return "", nil, errors.Errorf("file does not have a download URL. ID: %s, %#v",
|
||||
return nil, nil, errors.Errorf("file does not have a download URL. ID: %s, %#v",
|
||||
itemID, item.GetAdditionalData())
|
||||
}
|
||||
|
||||
@ -52,10 +53,16 @@ func driveItemReader(
|
||||
// middleware/options configured
|
||||
resp, err := http.Get(*downloadURL)
|
||||
if err != nil {
|
||||
return "", nil, errors.Wrapf(err, "failed to download file from %s", *downloadURL)
|
||||
return nil, nil, errors.Wrapf(err, "failed to download file from %s", *downloadURL)
|
||||
}
|
||||
|
||||
return *item.GetName(), resp.Body, nil
|
||||
return &details.OneDriveInfo{
|
||||
ItemType: details.OneDriveItem,
|
||||
ItemName: *item.GetName(),
|
||||
Created: *item.GetCreatedDateTime(),
|
||||
LastModified: *item.GetLastModifiedDateTime(),
|
||||
Size: *item.GetSize(),
|
||||
}, resp.Body, nil
|
||||
}
|
||||
|
||||
// driveItemWriter is used to initialize and return an io.Writer to upload data for the specified item
|
||||
|
||||
@ -102,14 +102,16 @@ func (suite *ItemIntegrationSuite) TestItemReader() {
|
||||
)
|
||||
|
||||
// Read data for the file
|
||||
name, itemData, err := driveItemReader(ctx, suite, driveID, driveItemID)
|
||||
itemInfo, itemData, err := driveItemReader(ctx, suite, driveID, driveItemID)
|
||||
require.NoError(suite.T(), err)
|
||||
require.NotEmpty(suite.T(), name)
|
||||
require.NotNil(suite.T(), itemInfo)
|
||||
require.NotEmpty(suite.T(), itemInfo.ItemName)
|
||||
|
||||
size, err := io.Copy(io.Discard, itemData)
|
||||
require.NoError(suite.T(), err)
|
||||
require.NotZero(suite.T(), size)
|
||||
suite.T().Logf("Read %d bytes from file %s.", size, name)
|
||||
require.Equal(suite.T(), size, itemInfo.Size)
|
||||
suite.T().Logf("Read %d bytes from file %s.", size, itemInfo.ItemName)
|
||||
}
|
||||
|
||||
// TestItemWriter is an integration test for uploading data to OneDrive
|
||||
|
||||
@ -364,16 +364,22 @@ type OneDriveInfo struct {
|
||||
ItemType ItemType `json:"itemType,omitempty"`
|
||||
ParentPath string `json:"parentPath"`
|
||||
ItemName string `json:"itemName"`
|
||||
Size int64 `json:"size,omitempty"`
|
||||
Created time.Time `json:"created,omitempty"`
|
||||
LastModified time.Time `json:"lastModified,omitempty"`
|
||||
}
|
||||
|
||||
// Headers returns the human-readable names of properties in a OneDriveInfo
|
||||
// for printing out to a terminal in a columnar display.
|
||||
func (i OneDriveInfo) Headers() []string {
|
||||
return []string{"ItemName", "ParentPath"}
|
||||
return []string{"ItemName", "ParentPath", "Size", "Created", "LastModified"}
|
||||
}
|
||||
|
||||
// Values returns the values matching the Headers list for printing
|
||||
// out to a terminal in a columnar display.
|
||||
func (i OneDriveInfo) Values() []string {
|
||||
return []string{i.ItemName, i.ParentPath}
|
||||
return []string{
|
||||
i.ItemName, i.ParentPath, strconv.FormatInt(i.Size, 10),
|
||||
common.FormatTabularDisplayTime(i.Created), common.FormatTabularDisplayTime(i.LastModified),
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,11 +114,14 @@ func (suite *DetailsUnitSuite) TestDetailsEntry_HeadersValues() {
|
||||
OneDrive: &details.OneDriveInfo{
|
||||
ItemName: "itemName",
|
||||
ParentPath: "parentPath",
|
||||
Size: 1000,
|
||||
Created: now,
|
||||
LastModified: now,
|
||||
},
|
||||
},
|
||||
},
|
||||
expectHs: []string{"Reference", "ItemName", "ParentPath"},
|
||||
expectVs: []string{"deadbeef", "itemName", "parentPath"},
|
||||
expectHs: []string{"Reference", "ItemName", "ParentPath", "Size", "Created", "LastModified"},
|
||||
expectVs: []string{"deadbeef", "itemName", "parentPath", "1000", nowStr, nowStr},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user