63 lines
1.7 KiB
Go
63 lines
1.7 KiB
Go
package utils
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"net/url"
|
|
|
|
"github.com/fiskerinc/cloud-services/pkg/remotefileupload"
|
|
"github.com/Azure/azure-storage-blob-go/azblob"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
func ReadAzureBlob(azureContainer string, vin string, year, month, day int, offset, count int64, readDirection Direction) ([]byte, int64, error) {
|
|
creds, err := AzureStorageCredential()
|
|
if err != nil {
|
|
return nil, -1, err
|
|
}
|
|
|
|
link, err := remotefileupload.AzureFilePathLink(AzureAccount, azureContainer, vin, fmt.Sprintf("%04d", year), fmt.Sprintf("%02d", month), fmt.Sprintf("%02d", day), ReadFileName)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
u, err := url.Parse(link)
|
|
if err != nil {
|
|
return nil, -1, errors.WithStack(err)
|
|
}
|
|
|
|
url := azblob.NewBlobURL(*u, azblob.NewPipeline(creds, azblob.PipelineOptions{Retry: azblob.RetryOptions{MaxTries: 100}}))
|
|
|
|
prop, err := url.GetProperties(context.Background(), azblob.BlobAccessConditions{}, azblob.ClientProvidedKeyOptions{})
|
|
if err != nil {
|
|
return nil, -1, err
|
|
}
|
|
if offset >= prop.ContentLength() {
|
|
return nil, -1, errors.New("offset out of range")
|
|
}
|
|
//count from the end of the blob
|
|
readOffset := prop.ContentLength() - offset
|
|
|
|
begin := readOffset
|
|
if readDirection == Up {
|
|
begin -= count
|
|
}
|
|
//just read the rest
|
|
if begin <= 0 {
|
|
begin = 0
|
|
count = readOffset
|
|
}
|
|
if count == 0 {
|
|
count = azblob.CountToEnd
|
|
}
|
|
reader, err := url.Download(context.Background(), begin, count,
|
|
azblob.BlobAccessConditions{}, false, azblob.ClientProvidedKeyOptions{})
|
|
if err != nil {
|
|
return nil, -1, err
|
|
}
|
|
buf := make([]byte, reader.ContentLength())
|
|
|
|
_, err = io.ReadAtLeast(reader.Body(azblob.RetryReaderOptions{}), buf, len(buf))
|
|
return buf, prop.ContentLength(), err
|
|
}
|