77package container
88
99import (
10+ "bytes"
1011 "context"
12+ "errors"
13+ "fmt"
14+ "github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming"
1115 "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/bloberror"
1216 "net/http"
1317 "net/url"
@@ -45,7 +49,7 @@ func NewClient(containerURL string, cred azcore.TokenCredential, options *Client
4549 conOptions .PerRetryPolicies = append (conOptions .PerRetryPolicies , authPolicy )
4650 pl := runtime .NewPipeline (exported .ModuleName , exported .ModuleVersion , runtime.PipelineOptions {}, & conOptions .ClientOptions )
4751
48- return (* Client )(base .NewContainerClient (containerURL , pl , nil )), nil
52+ return (* Client )(base .NewContainerClient (containerURL , pl , & cred )), nil
4953}
5054
5155// NewClientWithNoCredential creates an instance of Client with the specified values.
@@ -102,6 +106,15 @@ func (c *Client) sharedKey() *SharedKeyCredential {
102106 return base .SharedKey ((* base.Client [generated.ContainerClient ])(c ))
103107}
104108
109+ func (c * Client ) credential () any {
110+ return base .Credential ((* base.Client [generated.ContainerClient ])(c ))
111+ }
112+
113+ // helper method to return the generated.BlobClient which is used for creating the sub-requests
114+ func getGeneratedBlobClient (b * blob.Client ) * generated.BlobClient {
115+ return base .InnerClient ((* base.Client [generated.BlobClient ])(b ))
116+ }
117+
105118// URL returns the URL endpoint used by the Client object.
106119func (c * Client ) URL () string {
107120 return c .generated ().Endpoint ()
@@ -113,7 +126,7 @@ func (c *Client) URL() string {
113126func (c * Client ) NewBlobClient (blobName string ) * blob.Client {
114127 blobName = url .PathEscape (blobName )
115128 blobURL := runtime .JoinPaths (c .URL (), blobName )
116- return (* blob .Client )(base .NewBlobClient (blobURL , c .generated ().Pipeline (), c .sharedKey ()))
129+ return (* blob .Client )(base .NewBlobClient (blobURL , c .generated ().Pipeline (), c .credential ()))
117130}
118131
119132// NewAppendBlobClient creates a new appendblob.Client object by concatenating blobName to the end of
@@ -329,3 +342,67 @@ func (c *Client) GetSASURL(permissions sas.ContainerPermissions, expiry time.Tim
329342
330343 return endpoint , nil
331344}
345+
346+ // NewBatchBuilder creates an instance of BatchBuilder using the same auth policy as the client.
347+ // BatchBuilder is used to build the batch consisting of either delete or set tier sub-requests.
348+ // All sub-requests in the batch must be of the same type, either delete or set tier.
349+ func (c * Client ) NewBatchBuilder () (* BatchBuilder , error ) {
350+ var authPolicy policy.Policy
351+
352+ switch cred := c .credential ().(type ) {
353+ case * azcore.TokenCredential :
354+ authPolicy = runtime .NewBearerTokenPolicy (* cred , []string {shared .TokenScope }, nil )
355+ case * SharedKeyCredential :
356+ authPolicy = exported .NewSharedKeyCredPolicy (cred )
357+ case nil :
358+ // for authentication using SAS
359+ authPolicy = nil
360+ default :
361+ return nil , fmt .Errorf ("unrecognised authentication type %T" , cred )
362+ }
363+
364+ return & BatchBuilder {
365+ endpoint : c .URL (),
366+ authPolicy : authPolicy ,
367+ }, nil
368+ }
369+
370+ // SubmitBatch operation allows multiple API calls to be embedded into a single HTTP request.
371+ // It builds the request body using the BatchBuilder object passed.
372+ // BatchBuilder contains the list of operations to be submitted. It supports up to 256 sub-requests in a single batch.
373+ // For more information, see https://docs.microsoft.com/rest/api/storageservices/blob-batch.
374+ func (c * Client ) SubmitBatch (ctx context.Context , bb * BatchBuilder , options * SubmitBatchOptions ) (SubmitBatchResponse , error ) {
375+ if bb == nil || len (bb .subRequests ) == 0 {
376+ return SubmitBatchResponse {}, errors .New ("batch builder is empty" )
377+ }
378+
379+ // create the request body
380+ batchReq , batchID , err := exported .CreateBatchRequest (& exported.BlobBatchBuilder {
381+ AuthPolicy : bb .authPolicy ,
382+ SubRequests : bb .subRequests ,
383+ })
384+ if err != nil {
385+ return SubmitBatchResponse {}, err
386+ }
387+
388+ reader := bytes .NewReader (batchReq )
389+ rsc := streaming .NopCloser (reader )
390+ multipartContentType := "multipart/mixed; boundary=" + batchID
391+
392+ resp , err := c .generated ().SubmitBatch (ctx , int64 (len (batchReq )), multipartContentType , rsc , options .format ())
393+ if err != nil {
394+ return SubmitBatchResponse {}, err
395+ }
396+
397+ batchResponses , err := exported .ParseBlobBatchResponse (resp .Body , resp .ContentType , bb .subRequests )
398+ if err != nil {
399+ return SubmitBatchResponse {}, err
400+ }
401+
402+ return SubmitBatchResponse {
403+ Responses : batchResponses ,
404+ ContentType : resp .ContentType ,
405+ RequestID : resp .RequestID ,
406+ Version : resp .Version ,
407+ }, nil
408+ }
0 commit comments