github.com/StarfishStorage/goofys@v0.23.2-0.20200415030923-535558486b34/internal/backend_adlv2.go (about)

     1  // Copyright 2019 Databricks
     2  // Copyright (c) Microsoft and contributors for generated code from azure-sdk-for-go
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  package internal
    17  
    18  import (
    19  	. "github.com/kahing/goofys/api/common"
    20  
    21  	"context"
    22  	"encoding/base64"
    23  	"encoding/json"
    24  	"fmt"
    25  	"io"
    26  	"net/http"
    27  	"net/url"
    28  	"strconv"
    29  	"strings"
    30  	"sync/atomic"
    31  	"syscall"
    32  	"time"
    33  
    34  	"github.com/google/uuid"
    35  	"github.com/jacobsa/fuse"
    36  	"github.com/sirupsen/logrus"
    37  
    38  	adl2 "github.com/Azure/azure-sdk-for-go/services/storage/datalake/2018-11-09/storagedatalake"
    39  	"github.com/Azure/go-autorest/autorest"
    40  	"github.com/Azure/go-autorest/autorest/azure"
    41  )
    42  
    43  type ADLv2 struct {
    44  	cap Capabilities
    45  
    46  	flags  *FlagStorage
    47  	config *ADLv2Config
    48  
    49  	client adl2PathClient
    50  	bucket string
    51  }
    52  
    53  const ADL2_CLIENT_REQUEST_ID = "X-Ms-Client-Request-Id"
    54  const ADL2_REQUEST_ID = "X-Ms-Request-Id"
    55  
    56  var adl2Log = GetLogger("adlv2")
    57  
    58  type ADLv2MultipartBlobCommitInput struct {
    59  	Size           uint64
    60  	ContentType    string
    61  	RenewLeaseStop chan bool
    62  }
    63  
    64  func IsADLv2Endpoint(endpoint string) bool {
    65  	return strings.HasPrefix(endpoint, "abfs://")
    66  }
    67  
    68  func adl2LogResp(level logrus.Level, r *http.Response) {
    69  	if r == nil {
    70  		return
    71  	}
    72  
    73  	if adl2Log.IsLevelEnabled(level) {
    74  		requestId := r.Request.Header.Get(ADL2_CLIENT_REQUEST_ID)
    75  		respId := r.Header.Get(ADL2_REQUEST_ID)
    76  		// don't log anything if this is being called twice,
    77  		// which it is via ResponseInspector
    78  		if respId != "" {
    79  			adl2Log.Logf(level, "%v %v %v %v %v", r.Request.Method,
    80  				r.Request.URL.String(),
    81  				requestId, r.Status, respId)
    82  			r.Header.Del(ADL2_REQUEST_ID)
    83  		}
    84  	}
    85  }
    86  
    87  func NewADLv2(bucket string, flags *FlagStorage, config *ADLv2Config) (*ADLv2, error) {
    88  	u, err := url.Parse(config.Endpoint)
    89  	if err != nil {
    90  		return nil, err
    91  	}
    92  
    93  	parts := strings.SplitN(u.Hostname(), ".", 2)
    94  	if len(parts) != 2 {
    95  		return nil, fmt.Errorf("Invalid endpoint: %v", config.Endpoint)
    96  	}
    97  	storageAccountName := parts[0]
    98  	dnsSuffix := parts[1]
    99  
   100  	LogRequest := func(p autorest.Preparer) autorest.Preparer {
   101  		return autorest.PreparerFunc(func(r *http.Request) (*http.Request, error) {
   102  			r.URL.Scheme = u.Scheme
   103  			date := time.Now().Format(time.RFC1123)
   104  			date = strings.Replace(date, "UTC", "GMT", 1)
   105  
   106  			r.Header.Set("X-Ms-Date", date)
   107  			r.Header.Set("X-Ms-Version", "2018-11-09")
   108  			r.Header.Set(ADL2_CLIENT_REQUEST_ID, uuid.New().String())
   109  			r.Header.Set("Accept-Charset", "utf-8")
   110  			r.Header.Set("Content-Type", "")
   111  			r.Header.Set("Accept", "application/json, application/octet-stream")
   112  			// set transfer encoding and non-nil Body to
   113  			// ensure Content-Length: 0 is sent, seems
   114  			// like an idiotic golang behavior:
   115  			// https://github.com/golang/go/issues/20257
   116  			// azure server side rejects the request if
   117  			// Content-Length is missing
   118  			r.TransferEncoding = []string{"identity"}
   119  			if r.Header.Get("Content-Length") == "0" {
   120  				r.Body = http.NoBody
   121  			} else if r.Body == nil {
   122  				r.Body = http.NoBody
   123  			}
   124  
   125  			if adl2Log.IsLevelEnabled(logrus.DebugLevel) {
   126  				requestId := r.Header.Get(ADL2_CLIENT_REQUEST_ID)
   127  				op := r.Method
   128  				switch op {
   129  				case http.MethodPost:
   130  					// this is a lease
   131  					leaseAction := r.Header.Get("X-Ms-Lease-Action")
   132  					leaseId := r.Header.Get("X-Ms-Lease-Id")
   133  					proposeLeaseId := r.Header.Get("X-Ms-Proposed-Lease-Id")
   134  					op += fmt.Sprintf(" %v (%v, %v)",
   135  						leaseAction, leaseId, proposeLeaseId)
   136  				case http.MethodPatch:
   137  					action := r.URL.Query().Get("action")
   138  					op += " " + action
   139  					if action == "append" {
   140  						op += fmt.Sprintf("(%v)", r.ContentLength)
   141  					}
   142  				}
   143  				adl2Log.Debugf("%v %v %v", op,
   144  					r.URL.String(), requestId)
   145  			}
   146  
   147  			r, err := p.Prepare(r)
   148  			if err != nil {
   149  				adl2Log.Error(err)
   150  			}
   151  			return r, err
   152  		})
   153  	}
   154  
   155  	LogResponse := func(p autorest.Responder) autorest.Responder {
   156  		return autorest.ResponderFunc(func(r *http.Response) error {
   157  			adl2LogResp(logrus.DebugLevel, r)
   158  			err := p.Respond(r)
   159  			if err != nil {
   160  				adl2Log.Error(err)
   161  			}
   162  			return err
   163  		})
   164  	}
   165  
   166  	client := adl2.NewWithoutDefaults("", storageAccountName, dnsSuffix)
   167  	client.Authorizer = config.Authorizer
   168  	client.RequestInspector = LogRequest
   169  	client.ResponseInspector = LogResponse
   170  	client.Sender.(*http.Client).Transport = GetHTTPTransport()
   171  
   172  	b := &ADLv2{
   173  		flags:  flags,
   174  		config: config,
   175  		client: adl2PathClient{client},
   176  		bucket: bucket,
   177  		cap: Capabilities{
   178  			DirBlob: true,
   179  			Name:    "adl2",
   180  			// tested on 2019-11-07, seems to have same
   181  			// limit as azblob
   182  			MaxMultipartSize: 100 * 1024 * 1024,
   183  		},
   184  	}
   185  
   186  	return b, nil
   187  }
   188  
   189  func (b *ADLv2) Bucket() string {
   190  	return b.bucket
   191  }
   192  
   193  func (b *ADLv2) Delegate() interface{} {
   194  	return b
   195  }
   196  
   197  func (b *ADLv2) Init(key string) (err error) {
   198  	_, err = b.HeadBlob(&HeadBlobInput{Key: key})
   199  	if err == fuse.ENOENT {
   200  		err = nil
   201  	}
   202  	return
   203  }
   204  
   205  func (b *ADLv2) Capabilities() *Capabilities {
   206  	return &b.cap
   207  }
   208  
   209  type ADL2Error struct {
   210  	adl2.DataLakeStorageError
   211  }
   212  
   213  func (e ADL2Error) Error() string {
   214  	return fmt.Sprintf("%v: %v", *e.DataLakeStorageError.Error.Code,
   215  		*e.DataLakeStorageError.Error.Message)
   216  }
   217  
   218  func decodeADLv2Error(body io.Reader) (adlErr adl2.DataLakeStorageError, err error) {
   219  	decoder := json.NewDecoder(body)
   220  	err = decoder.Decode(&adlErr)
   221  	return
   222  }
   223  
   224  func mapADLv2Error(resp *http.Response, err error, rawError bool) error {
   225  
   226  	if resp == nil {
   227  		if err != nil {
   228  			if detailedError, ok := err.(autorest.DetailedError); ok {
   229  				if urlErr, ok := detailedError.Original.(*url.Error); ok {
   230  					adl2Log.Errorf("url.Err: %T: %v %v %v %v %v", urlErr.Err, urlErr.Err, urlErr.Temporary(), urlErr.Timeout(), urlErr.Op, urlErr.URL)
   231  				} else {
   232  					adl2Log.Errorf("%T: %v", detailedError.Original, detailedError.Original)
   233  				}
   234  			} else {
   235  				adl2Log.Errorf("unknown error: %v", err)
   236  			}
   237  			return syscall.EAGAIN
   238  		} else {
   239  			return err
   240  		}
   241  	}
   242  
   243  	if resp.StatusCode < 200 || resp.StatusCode >= 300 {
   244  		defer resp.Body.Close()
   245  		if rawError {
   246  			adlErr, err := decodeADLv2Error(resp.Body)
   247  			if err == nil {
   248  				return ADL2Error{adlErr}
   249  			} else {
   250  				adl2Log.Errorf("cannot parse error: %v", err)
   251  				return syscall.EAGAIN
   252  			}
   253  		} else {
   254  			switch resp.StatusCode {
   255  			case http.StatusBadRequest:
   256  				if !adl2Log.IsLevelEnabled(logrus.DebugLevel) {
   257  					adl2LogResp(logrus.ErrorLevel, resp)
   258  				}
   259  				adlErr, err := decodeADLv2Error(resp.Body)
   260  				if err == nil {
   261  					switch *adlErr.Error.Code {
   262  					case "MissingRequiredHeader", "UnsupportedHeader":
   263  						var s strings.Builder
   264  						for k, _ := range resp.Request.Header {
   265  							s.WriteString(k)
   266  							s.WriteString(" ")
   267  						}
   268  						adl2Log.Errorf("%v, sent: %v",
   269  							*adlErr.Error.Code,
   270  							s.String())
   271  					case "InvalidSourceUri":
   272  						adl2Log.Errorf("SourceUri: %v",
   273  							resp.Request.Header.Get("X-Ms-Rename-Source"))
   274  					}
   275  				}
   276  			case http.StatusPreconditionFailed:
   277  				return syscall.EAGAIN
   278  			}
   279  
   280  			err = mapHttpError(resp.StatusCode)
   281  			if err != nil {
   282  				return err
   283  			} else {
   284  				if !adl2Log.IsLevelEnabled(logrus.DebugLevel) {
   285  					adl2LogResp(logrus.ErrorLevel, resp)
   286  				}
   287  				adl2Log.Errorf("resp: %#v %v", resp, err)
   288  				return syscall.EINVAL
   289  			}
   290  		}
   291  	} else {
   292  		return err
   293  	}
   294  }
   295  
   296  func getHeader(resp *http.Response, key string) *string {
   297  	if v, set := resp.Header[http.CanonicalHeaderKey(key)]; set {
   298  		return &v[0]
   299  	} else {
   300  		return nil
   301  	}
   302  }
   303  
   304  func parseADLv2Time(v string) *time.Time {
   305  	t, err := time.Parse(time.RFC1123, v)
   306  	if err == nil {
   307  		return &t
   308  	} else {
   309  		return nil
   310  	}
   311  }
   312  
   313  func adlv2ToBlobItem(resp *http.Response, key string) BlobItemOutput {
   314  	return BlobItemOutput{
   315  		Key:          &key,
   316  		ETag:         getHeader(resp, "ETag"),
   317  		Size:         uint64(resp.ContentLength),
   318  		LastModified: parseADLv2Time(resp.Header.Get("Last-Modified")),
   319  	}
   320  }
   321  
   322  func (b *ADLv2) HeadBlob(param *HeadBlobInput) (*HeadBlobOutput, error) {
   323  	key := param.Key
   324  	if strings.HasSuffix(key, "/") {
   325  		key = key[:len(key)-1]
   326  	}
   327  
   328  	// GetProperties(GetStatus) does not return user defined
   329  	// properties, despite what the documentation says, use a 0
   330  	// bytes range get instead
   331  	res, err := b.GetBlob(&GetBlobInput{
   332  		Key:   key,
   333  		Start: 0,
   334  		Count: 0,
   335  	})
   336  	if err != nil {
   337  		return nil, err
   338  	}
   339  	res.Body.Close()
   340  
   341  	return &res.HeadBlobOutput, nil
   342  }
   343  
   344  func (b *ADLv2) ListBlobs(param *ListBlobsInput) (*ListBlobsOutput, error) {
   345  	if param.Delimiter != nil && *param.Delimiter != "/" {
   346  		return nil, fuse.EINVAL
   347  	}
   348  
   349  	var maxResults *int32
   350  	if param.MaxKeys != nil {
   351  		maxResults = PInt32(int32(*param.MaxKeys))
   352  	}
   353  
   354  	res, err := b.client.List(context.TODO(), param.Delimiter == nil, b.bucket,
   355  		nilStr(param.Prefix), nilStr(param.ContinuationToken), maxResults,
   356  		nil, "", nil, "")
   357  	if err != nil {
   358  		err = mapADLv2Error(res.Response.Response, err, false)
   359  		if err == fuse.ENOENT {
   360  			return &ListBlobsOutput{
   361  				RequestId: res.Response.Response.Header.Get(ADL2_REQUEST_ID),
   362  			}, nil
   363  		} else {
   364  			return nil, err
   365  		}
   366  	}
   367  
   368  	var prefixes []BlobPrefixOutput
   369  	var items []BlobItemOutput
   370  
   371  	if param.Delimiter != nil && param.Prefix != nil {
   372  		// we didn't get 404 which means the path must
   373  		// exists. If the path is actually a file, adlv2
   374  		// returns the file itself as the result. That's
   375  		// already handled by the loop below
   376  		if len(*res.Paths) != 1 ||
   377  			*(*res.Paths)[0].Name != strings.TrimRight(*param.Prefix, "/") {
   378  			// the prefix we listed is a directory
   379  			if strings.HasSuffix(*param.Prefix, "/") {
   380  				// we listed for the dir object itself
   381  				items = append(items, BlobItemOutput{
   382  					Key: param.Prefix,
   383  				})
   384  			} else {
   385  				prefixes = append(prefixes, BlobPrefixOutput{
   386  					PString(*param.Prefix + "/"),
   387  				})
   388  			}
   389  		} else {
   390  			if strings.HasSuffix(*param.Prefix, "/") {
   391  				// we asked for a dir and got a file
   392  				return &ListBlobsOutput{
   393  					RequestId: res.Response.Response.Header.Get(ADL2_REQUEST_ID),
   394  				}, nil
   395  			}
   396  		}
   397  	}
   398  
   399  	for _, p := range *res.Paths {
   400  		if param.Delimiter != nil {
   401  			if p.isDirectory() {
   402  				prefixes = append(prefixes, BlobPrefixOutput{
   403  					PString(*p.Name + "/"),
   404  				})
   405  				continue
   406  			}
   407  		}
   408  
   409  		key := *p.Name
   410  		if p.isDirectory() {
   411  			key += "/"
   412  		}
   413  		items = append(items, BlobItemOutput{
   414  			Key:          &key,
   415  			ETag:         p.ETag,
   416  			LastModified: parseADLv2Time(nilStr(p.LastModified)),
   417  			Size:         uint64(p.contentLength()),
   418  		})
   419  	}
   420  
   421  	continuationToken := getHeader(res.Response.Response, "x-ms-continuation")
   422  
   423  	return &ListBlobsOutput{
   424  		Prefixes:              prefixes,
   425  		Items:                 items,
   426  		NextContinuationToken: continuationToken,
   427  		IsTruncated:           continuationToken != nil,
   428  		RequestId:             res.Response.Response.Header.Get(ADL2_REQUEST_ID),
   429  	}, nil
   430  }
   431  
   432  func (b *ADLv2) DeleteBlob(param *DeleteBlobInput) (*DeleteBlobOutput, error) {
   433  	if strings.HasSuffix(param.Key, "/") {
   434  		return b.DeleteBlob(&DeleteBlobInput{param.Key[:len(param.Key)-1]})
   435  	}
   436  
   437  	res, err := b.client.Delete(context.TODO(), b.bucket, param.Key, nil, "", "",
   438  		/*ifMatch=*/ "", "", "", "", "", nil, "")
   439  	err = mapADLv2Error(res.Response, err, false)
   440  	if err != nil {
   441  		return nil, err
   442  	}
   443  	return &DeleteBlobOutput{}, nil
   444  }
   445  
   446  func (b *ADLv2) DeleteBlobs(param *DeleteBlobsInput) (*DeleteBlobsOutput, error) {
   447  	return nil, syscall.ENOTSUP
   448  }
   449  
   450  func (b *ADLv2) RenameBlob(param *RenameBlobInput) (*RenameBlobOutput, error) {
   451  	var continuation string
   452  
   453  	renameDest := param.Destination
   454  	if strings.HasSuffix(renameDest, "/") {
   455  		renameDest = renameDest[:len(renameDest)-1]
   456  	}
   457  	renameSource := param.Source
   458  	if strings.HasSuffix(renameSource, "/") {
   459  		renameSource = renameSource[:len(renameSource)-1]
   460  	}
   461  	renameSource = "/" + b.bucket + "/" + url.PathEscape(renameSource)
   462  
   463  	var requestId string
   464  	for cont := true; cont; cont = continuation != "" {
   465  		res, err := b.client.Create(context.TODO(), b.bucket, renameDest,
   466  			"", continuation, "", "", "", "", "", "", "", "", "", "",
   467  			renameSource, "", "", "", "", "", "", "", "", "", "", "",
   468  			"", "", "", nil, "")
   469  		if err != nil {
   470  			return nil, mapADLv2Error(res.Response, err, false)
   471  		}
   472  
   473  		continuation = res.Header.Get("x-ms-continuation")
   474  		requestId = res.Header.Get(ADL2_REQUEST_ID)
   475  	}
   476  
   477  	return &RenameBlobOutput{requestId}, nil
   478  }
   479  
   480  func (b *ADLv2) CopyBlob(param *CopyBlobInput) (*CopyBlobOutput, error) {
   481  	if param.Source != param.Destination || param.Metadata == nil {
   482  		return nil, syscall.ENOTSUP
   483  	}
   484  
   485  	res, err := b.client.Update(context.TODO(), adl2.SetProperties, b.bucket, param.Source, nil,
   486  		nil, nil, nil, "", "", "", "", "", "", "", "", b.toADLProperties(param.Metadata),
   487  		"", "", "", "", "", "", "", "", nil, "", nil, "")
   488  	if err != nil {
   489  		return nil, mapADLv2Error(res.Response, err, false)
   490  	}
   491  
   492  	return &CopyBlobOutput{
   493  		RequestId: res.Response.Header.Get(ADL2_REQUEST_ID),
   494  	}, nil
   495  }
   496  
   497  func (b *ADLv2) GetBlob(param *GetBlobInput) (*GetBlobOutput, error) {
   498  	var bytes string
   499  	if param.Start != 0 || param.Count != 0 {
   500  		if param.Count != 0 {
   501  			bytes = fmt.Sprintf("bytes=%v-%v", param.Start, param.Start+param.Count-1)
   502  		} else {
   503  			bytes = fmt.Sprintf("bytes=%v-", param.Start)
   504  		}
   505  	}
   506  
   507  	res, err := b.client.Read(context.TODO(), b.bucket, param.Key, bytes,
   508  		"", nil, nilStr(param.IfMatch), "", "", "",
   509  		"", nil, "")
   510  	if err != nil {
   511  		return nil, mapADLv2Error(res.Response.Response, err, false)
   512  	}
   513  
   514  	metadata := make(map[string]*string)
   515  	for _, p := range res.Header["X-Ms-Properties"] {
   516  		csv := strings.Split(p, ",")
   517  		for _, kv := range csv {
   518  			kv = strings.TrimSpace(kv)
   519  			if len(kv) == 0 {
   520  				continue
   521  			}
   522  
   523  			s := strings.SplitN(kv, "=", 2)
   524  			if len(s) != 2 {
   525  				adl2Log.Warnf("Dropping property: %v: %v", param.Key, kv)
   526  				continue
   527  			}
   528  			key := strings.TrimSpace(s[0])
   529  			value := strings.TrimSpace(s[1])
   530  			buf, err := base64.StdEncoding.DecodeString(value)
   531  			if err != nil {
   532  				adl2Log.Warnf("Unable to decode property: %v: %v",
   533  					param.Key, key)
   534  				continue
   535  			}
   536  			metadata[key] = PString(string(buf))
   537  		}
   538  	}
   539  
   540  	return &GetBlobOutput{
   541  		HeadBlobOutput: HeadBlobOutput{
   542  			BlobItemOutput: adlv2ToBlobItem(res.Response.Response, param.Key),
   543  			ContentType:    getHeader(res.Response.Response, "Content-Type"),
   544  			IsDirBlob:      res.Header.Get("X-Ms-Resource-Type") == string(adl2.Directory),
   545  			Metadata:       metadata,
   546  		},
   547  		Body: *res.Value,
   548  	}, nil
   549  }
   550  
   551  func (b *ADLv2) toADLProperties(metadata map[string]*string) string {
   552  	var buf strings.Builder
   553  	for k, v := range metadata {
   554  		buf.WriteString(k)
   555  		buf.WriteString("=")
   556  		buf.WriteString(base64.StdEncoding.EncodeToString([]byte(*v)))
   557  		buf.WriteString(",")
   558  	}
   559  	var s = buf.String()
   560  	if len(s) != 0 {
   561  		// remove trailing comma
   562  		s = s[:len(s)-1]
   563  	}
   564  	return s
   565  }
   566  
   567  func (b *ADLv2) create(key string, pathType adl2.PathResourceType, contentType *string,
   568  	metadata map[string]*string, leaseId string) (resp autorest.Response, err error) {
   569  	resp, err = b.client.Create(context.TODO(), b.bucket, key,
   570  		pathType, "", "", "", "", "", "", "", nilStr(contentType),
   571  		"", "", "", "", leaseId, "", b.toADLProperties(metadata), "", "", "", "", "", "",
   572  		"", "", "", "", "", nil, "")
   573  	if err != nil {
   574  		err = mapADLv2Error(resp.Response, err, false)
   575  	}
   576  	return
   577  }
   578  
   579  func (b *ADLv2) append(key string, offset int64, size int64, body io.ReadSeeker,
   580  	leaseId string) (resp autorest.Response, err error) {
   581  	resp, err = b.client.Update(context.TODO(), adl2.Append, b.bucket,
   582  		key, &offset, nil, nil, &size, "", leaseId, "",
   583  		"", "", "", "", "", "", "", "", "", "",
   584  		"", "", "", "", &ReadSeekerCloser{body},
   585  		"", nil, "")
   586  	if err != nil {
   587  		err = mapADLv2Error(resp.Response, err, false)
   588  	}
   589  	return
   590  }
   591  
   592  func (b *ADLv2) flush(key string, offset int64, contentType string, leaseId string) (res autorest.Response, err error) {
   593  	res, err = b.client.Update(context.TODO(), adl2.Flush, b.bucket,
   594  		key, &offset, PBool(false), PBool(true), PInt64(0), "", leaseId, "",
   595  		contentType, "", "", "", "", "", "", "", "", "",
   596  		"", "", "", "", nil, "", nil, "")
   597  	if err != nil {
   598  		err = mapADLv2Error(res.Response, err, false)
   599  	}
   600  	return
   601  }
   602  
   603  func (b *ADLv2) PutBlob(param *PutBlobInput) (*PutBlobOutput, error) {
   604  	if param.DirBlob {
   605  		res, err := b.create(param.Key, adl2.Directory, param.ContentType,
   606  			param.Metadata, "")
   607  		if err != nil {
   608  			return nil, err
   609  		}
   610  		return &PutBlobOutput{
   611  			ETag: getHeader(res.Response, "ETag"),
   612  		}, nil
   613  	} else {
   614  		if param.Size == nil {
   615  			panic("size cannot be nil")
   616  		}
   617  
   618  		create, err := b.create(param.Key, adl2.File, param.ContentType,
   619  			param.Metadata, "")
   620  		if err != nil {
   621  			return nil, err
   622  		}
   623  
   624  		size := int64(*param.Size)
   625  		if size == 0 {
   626  			// nothing to write, we can return
   627  			// here. appending a 0-size buffer
   628  			// causes azure to fail with 400 bad
   629  			// request
   630  			return &PutBlobOutput{
   631  				ETag: getHeader(create.Response, "ETag"),
   632  			}, nil
   633  		}
   634  
   635  		// not doing a lease for these because append to 0
   636  		// would guarantee that we don't have concurrent
   637  		// appends, and flushing is safe to do
   638  		_, err = b.append(param.Key, 0, size, param.Body, "")
   639  		if err != nil {
   640  			return nil, err
   641  		}
   642  
   643  		flush, err := b.flush(param.Key, size, nilStr(param.ContentType), "")
   644  		if err != nil {
   645  			return nil, err
   646  		}
   647  
   648  		return &PutBlobOutput{
   649  			ETag: getHeader(flush.Response, "ETag"),
   650  		}, nil
   651  	}
   652  }
   653  
   654  // adlv2 doesn't have atomic multipart upload, instead we will hold a
   655  // lease, replace the object, then release the lease
   656  func (b *ADLv2) MultipartBlobBegin(param *MultipartBlobBeginInput) (*MultipartBlobCommitInput, error) {
   657  	leaseId := uuid.New().String()
   658  	err := b.lease(adl2.Acquire, param.Key, leaseId, 60, "")
   659  	if err == fuse.ENOENT {
   660  		// the file didn't exist, we will create the file
   661  		// first and then acquire the lease
   662  		create, err := b.create(param.Key, adl2.File, param.ContentType, param.Metadata, "")
   663  		if err != nil {
   664  			return nil, err
   665  		}
   666  
   667  		err = b.lease(adl2.Acquire, param.Key, leaseId, 60,
   668  			create.Response.Header.Get("ETag"))
   669  		if err != nil {
   670  			return nil, err
   671  		}
   672  	} else {
   673  		if err != nil {
   674  			return nil, err
   675  		}
   676  
   677  		defer func() {
   678  			if err != nil {
   679  				err2 := b.lease(adl2.Release, param.Key, leaseId, 0, "")
   680  				if err2 != nil {
   681  					adl2Log.Errorf("Unable to release lease for %v: %v",
   682  						param.Key, err2)
   683  				}
   684  			}
   685  		}()
   686  
   687  		_, err = b.create(param.Key, adl2.File, param.ContentType, param.Metadata, leaseId)
   688  		if err != nil {
   689  			return nil, err
   690  		}
   691  
   692  	}
   693  
   694  	commitData := &ADLv2MultipartBlobCommitInput{
   695  		ContentType:    nilStr(param.ContentType),
   696  		RenewLeaseStop: make(chan bool, 1),
   697  	}
   698  
   699  	go func() {
   700  		for {
   701  			select {
   702  			case <-commitData.RenewLeaseStop:
   703  				break
   704  			case <-time.After(30 * time.Second):
   705  				b.lease(adl2.Renew, param.Key, leaseId, 60, "")
   706  			}
   707  		}
   708  	}()
   709  
   710  	return &MultipartBlobCommitInput{
   711  		Key:         &param.Key,
   712  		Metadata:    param.Metadata,
   713  		UploadId:    &leaseId,
   714  		backendData: commitData,
   715  	}, nil
   716  }
   717  
   718  func (b *ADLv2) lease(action adl2.PathLeaseAction, key string, leaseId string, durationSec int32,
   719  	ifMatch string) error {
   720  	var proposeLeaseId string
   721  	var prevLeaseId string
   722  	if action == adl2.Acquire {
   723  		proposeLeaseId = leaseId
   724  	} else {
   725  		prevLeaseId = leaseId
   726  	}
   727  
   728  	var duration *int32
   729  	if durationSec != 0 {
   730  		duration = &durationSec
   731  	}
   732  
   733  	res, err := b.client.Lease(context.TODO(), action, b.bucket, key,
   734  		duration, nil, prevLeaseId, proposeLeaseId, ifMatch, "", "", "", "", nil, "")
   735  	if err != nil {
   736  		err = mapADLv2Error(res.Response, err, false)
   737  	}
   738  	return err
   739  }
   740  
   741  func (b *ADLv2) MultipartBlobAdd(param *MultipartBlobAddInput) (*MultipartBlobAddOutput, error) {
   742  	var commitData *ADLv2MultipartBlobCommitInput
   743  	var ok bool
   744  	if commitData, ok = param.Commit.backendData.(*ADLv2MultipartBlobCommitInput); !ok {
   745  		panic("Incorrect commit data type")
   746  	}
   747  
   748  	res, err := b.append(*param.Commit.Key, int64(param.Offset), int64(param.Size),
   749  		param.Body, *param.Commit.UploadId)
   750  	if err != nil {
   751  		return nil, err
   752  	}
   753  	atomic.AddUint64(&commitData.Size, param.Size)
   754  
   755  	return &MultipartBlobAddOutput{
   756  		res.Response.Header.Get(ADL2_REQUEST_ID),
   757  	}, nil
   758  }
   759  
   760  func (b *ADLv2) MultipartBlobAbort(param *MultipartBlobCommitInput) (*MultipartBlobAbortOutput, error) {
   761  	if param.UploadId != nil {
   762  		err := b.lease(adl2.Release, *param.Key, *param.UploadId, 0, "")
   763  		if err != nil {
   764  			return nil, err
   765  		}
   766  	}
   767  	return &MultipartBlobAbortOutput{}, nil
   768  }
   769  
   770  func (b *ADLv2) MultipartBlobCommit(param *MultipartBlobCommitInput) (*MultipartBlobCommitOutput, error) {
   771  	var commitData *ADLv2MultipartBlobCommitInput
   772  	var ok bool
   773  	if commitData, ok = param.backendData.(*ADLv2MultipartBlobCommitInput); !ok {
   774  		panic("Incorrect commit data type")
   775  	}
   776  
   777  	defer func() {
   778  		commitData.RenewLeaseStop <- true
   779  		leaseId := *param.UploadId
   780  		// if the commit failed, we don't need to release the
   781  		// lease during abort
   782  		param.UploadId = nil
   783  
   784  		err2 := b.lease(adl2.Release, *param.Key, leaseId, 0, "")
   785  		if err2 != nil {
   786  			adl2Log.Errorf("Unable to release lease for %v: %v",
   787  				*param.Key, err2)
   788  		}
   789  	}()
   790  
   791  	flush, err := b.flush(*param.Key, int64(commitData.Size), commitData.ContentType, *param.UploadId)
   792  	if err != nil {
   793  		return nil, err
   794  	}
   795  
   796  	return &MultipartBlobCommitOutput{
   797  		ETag:      nil,
   798  		RequestId: flush.Response.Header.Get(ADL2_REQUEST_ID),
   799  	}, nil
   800  }
   801  
   802  func (b *ADLv2) MultipartExpire(param *MultipartExpireInput) (*MultipartExpireOutput, error) {
   803  	return nil, syscall.ENOTSUP
   804  }
   805  
   806  func (b *ADLv2) RemoveBucket(param *RemoveBucketInput) (*RemoveBucketOutput, error) {
   807  	fs := adl2.FilesystemClient{b.client.BaseClient}
   808  	res, err := fs.Delete(context.TODO(), b.bucket, "", "", uuid.New().String(), nil, "")
   809  	if err != nil {
   810  		return nil, mapADLv2Error(res.Response, err, false)
   811  	}
   812  	return &RemoveBucketOutput{}, nil
   813  }
   814  
   815  func (b *ADLv2) MakeBucket(param *MakeBucketInput) (*MakeBucketOutput, error) {
   816  	fs := adl2.FilesystemClient{b.client.BaseClient}
   817  	res, err := fs.Create(context.TODO(), b.bucket, "", uuid.New().String(), nil, "")
   818  	if err != nil {
   819  		return nil, mapADLv2Error(res.Response, err, false)
   820  	}
   821  	return &MakeBucketOutput{}, nil
   822  }
   823  
   824  // hacked from azure-sdk-for-go
   825  // remove after these bugs are fixed:
   826  // https://github.com/Azure/azure-sdk-for-go/issues/5502
   827  // https://github.com/Azure/azure-sdk-for-go/issues/5550
   828  // https://github.com/Azure/azure-sdk-for-go/issues/5549
   829  type adl2PathClient struct {
   830  	adl2.BaseClient
   831  }
   832  
   833  func (client adl2PathClient) Create(ctx context.Context, filesystem string, pathParameter string, resource adl2.PathResourceType, continuation string, mode adl2.PathRenameMode, cacheControl string, contentEncoding string, contentLanguage string, contentDisposition string, xMsCacheControl string, xMsContentType string, xMsContentEncoding string, xMsContentLanguage string, xMsContentDisposition string, xMsRenameSource string, xMsLeaseID string, xMsSourceLeaseID string, xMsProperties string, xMsPermissions string, xMsUmask string, ifMatch string, ifNoneMatch string, ifModifiedSince string, ifUnmodifiedSince string, xMsSourceIfMatch string, xMsSourceIfNoneMatch string, xMsSourceIfModifiedSince string, xMsSourceIfUnmodifiedSince string, xMsClientRequestID string, timeout *int32, xMsDate string) (result autorest.Response, err error) {
   834  	req, err := client.CreatePreparer(ctx, filesystem, pathParameter, resource, continuation, mode, cacheControl, contentEncoding, contentLanguage, contentDisposition, xMsCacheControl, xMsContentType, xMsContentEncoding, xMsContentLanguage, xMsContentDisposition, xMsRenameSource, xMsLeaseID, xMsSourceLeaseID, xMsProperties, xMsPermissions, xMsUmask, ifMatch, ifNoneMatch, ifModifiedSince, ifUnmodifiedSince, xMsSourceIfMatch, xMsSourceIfNoneMatch, xMsSourceIfModifiedSince, xMsSourceIfUnmodifiedSince, xMsClientRequestID, timeout, xMsDate)
   835  	if err != nil {
   836  		err = autorest.NewErrorWithError(err, "storagedatalake.adl2PathClient", "Create", nil, "Failure preparing request")
   837  		return
   838  	}
   839  
   840  	resp, err := client.CreateSender(req)
   841  	if err != nil {
   842  		result.Response = resp
   843  		err = autorest.NewErrorWithError(err, "storagedatalake.adl2PathClient", "Create", resp, "Failure sending request")
   844  		return
   845  	}
   846  
   847  	result, err = client.CreateResponder(resp)
   848  	if err != nil {
   849  		err = autorest.NewErrorWithError(err, "storagedatalake.adl2PathClient", "Create", resp, "Failure responding to request")
   850  	}
   851  
   852  	return
   853  }
   854  
   855  // CreatePreparer prepares the Create request.
   856  func (client adl2PathClient) CreatePreparer(ctx context.Context, filesystem string, pathParameter string, resource adl2.PathResourceType, continuation string, mode adl2.PathRenameMode, cacheControl string, contentEncoding string, contentLanguage string, contentDisposition string, xMsCacheControl string, xMsContentType string, xMsContentEncoding string, xMsContentLanguage string, xMsContentDisposition string, xMsRenameSource string, xMsLeaseID string, xMsSourceLeaseID string, xMsProperties string, xMsPermissions string, xMsUmask string, ifMatch string, ifNoneMatch string, ifModifiedSince string, ifUnmodifiedSince string, xMsSourceIfMatch string, xMsSourceIfNoneMatch string, xMsSourceIfModifiedSince string, xMsSourceIfUnmodifiedSince string, xMsClientRequestID string, timeout *int32, xMsDate string) (*http.Request, error) {
   857  	urlParameters := map[string]interface{}{
   858  		"accountName": client.AccountName,
   859  		"dnsSuffix":   client.DNSSuffix,
   860  	}
   861  
   862  	pathParameters := map[string]interface{}{
   863  		"filesystem": autorest.Encode("path", filesystem),
   864  		//"path":       url.PathEscape(pathParameter),
   865  		"path": autorest.Encode("path", pathParameter),
   866  	}
   867  
   868  	queryParameters := map[string]interface{}{}
   869  	if len(string(resource)) > 0 {
   870  		queryParameters["resource"] = autorest.Encode("query", resource)
   871  	}
   872  	if len(continuation) > 0 {
   873  		queryParameters["continuation"] = autorest.Encode("query", continuation)
   874  	}
   875  	if len(string(mode)) > 0 {
   876  		queryParameters["mode"] = autorest.Encode("query", mode)
   877  	}
   878  	if timeout != nil {
   879  		queryParameters["timeout"] = autorest.Encode("query", *timeout)
   880  	}
   881  
   882  	preparer := autorest.CreatePreparer(
   883  		autorest.AsPut(),
   884  		autorest.WithCustomBaseURL("http://{accountName}.{dnsSuffix}", urlParameters),
   885  		autorest.WithPathParameters("/{filesystem}/{path}", pathParameters),
   886  		autorest.WithQueryParameters(queryParameters))
   887  	if len(cacheControl) > 0 {
   888  		preparer = autorest.DecoratePreparer(preparer,
   889  			autorest.WithHeader("Cache-Control", autorest.String(cacheControl)))
   890  	}
   891  	if len(contentEncoding) > 0 {
   892  		preparer = autorest.DecoratePreparer(preparer,
   893  			autorest.WithHeader("Content-Encoding", autorest.String(contentEncoding)))
   894  	}
   895  	if len(contentLanguage) > 0 {
   896  		preparer = autorest.DecoratePreparer(preparer,
   897  			autorest.WithHeader("Content-Language", autorest.String(contentLanguage)))
   898  	}
   899  	if len(contentDisposition) > 0 {
   900  		preparer = autorest.DecoratePreparer(preparer,
   901  			autorest.WithHeader("Content-Disposition", autorest.String(contentDisposition)))
   902  	}
   903  	if len(xMsCacheControl) > 0 {
   904  		preparer = autorest.DecoratePreparer(preparer,
   905  			autorest.WithHeader("x-ms-cache-control", autorest.String(xMsCacheControl)))
   906  	}
   907  	if len(xMsContentType) > 0 {
   908  		preparer = autorest.DecoratePreparer(preparer,
   909  			autorest.WithHeader("x-ms-content-type", autorest.String(xMsContentType)))
   910  	}
   911  	if len(xMsContentEncoding) > 0 {
   912  		preparer = autorest.DecoratePreparer(preparer,
   913  			autorest.WithHeader("x-ms-content-encoding", autorest.String(xMsContentEncoding)))
   914  	}
   915  	if len(xMsContentLanguage) > 0 {
   916  		preparer = autorest.DecoratePreparer(preparer,
   917  			autorest.WithHeader("x-ms-content-language", autorest.String(xMsContentLanguage)))
   918  	}
   919  	if len(xMsContentDisposition) > 0 {
   920  		preparer = autorest.DecoratePreparer(preparer,
   921  			autorest.WithHeader("x-ms-content-disposition", autorest.String(xMsContentDisposition)))
   922  	}
   923  	if len(xMsRenameSource) > 0 {
   924  		preparer = autorest.DecoratePreparer(preparer,
   925  			autorest.WithHeader("x-ms-rename-source", autorest.String(xMsRenameSource)))
   926  	}
   927  	if len(xMsLeaseID) > 0 {
   928  		preparer = autorest.DecoratePreparer(preparer,
   929  			autorest.WithHeader("x-ms-lease-id", autorest.String(xMsLeaseID)))
   930  	}
   931  	if len(xMsSourceLeaseID) > 0 {
   932  		preparer = autorest.DecoratePreparer(preparer,
   933  			autorest.WithHeader("x-ms-source-lease-id", autorest.String(xMsSourceLeaseID)))
   934  	}
   935  	if len(xMsProperties) > 0 {
   936  		preparer = autorest.DecoratePreparer(preparer,
   937  			autorest.WithHeader("x-ms-properties", autorest.String(xMsProperties)))
   938  	}
   939  	if len(xMsPermissions) > 0 {
   940  		preparer = autorest.DecoratePreparer(preparer,
   941  			autorest.WithHeader("x-ms-permissions", autorest.String(xMsPermissions)))
   942  	}
   943  	if len(xMsUmask) > 0 {
   944  		preparer = autorest.DecoratePreparer(preparer,
   945  			autorest.WithHeader("x-ms-umask", autorest.String(xMsUmask)))
   946  	}
   947  	if len(ifMatch) > 0 {
   948  		preparer = autorest.DecoratePreparer(preparer,
   949  			autorest.WithHeader("If-Match", autorest.String(ifMatch)))
   950  	}
   951  	if len(ifNoneMatch) > 0 {
   952  		preparer = autorest.DecoratePreparer(preparer,
   953  			autorest.WithHeader("If-None-Match", autorest.String(ifNoneMatch)))
   954  	}
   955  	if len(ifModifiedSince) > 0 {
   956  		preparer = autorest.DecoratePreparer(preparer,
   957  			autorest.WithHeader("If-Modified-Since", autorest.String(ifModifiedSince)))
   958  	}
   959  	if len(ifUnmodifiedSince) > 0 {
   960  		preparer = autorest.DecoratePreparer(preparer,
   961  			autorest.WithHeader("If-Unmodified-Since", autorest.String(ifUnmodifiedSince)))
   962  	}
   963  	if len(xMsSourceIfMatch) > 0 {
   964  		preparer = autorest.DecoratePreparer(preparer,
   965  			autorest.WithHeader("x-ms-source-if-match", autorest.String(xMsSourceIfMatch)))
   966  	}
   967  	if len(xMsSourceIfNoneMatch) > 0 {
   968  		preparer = autorest.DecoratePreparer(preparer,
   969  			autorest.WithHeader("x-ms-source-if-none-match", autorest.String(xMsSourceIfNoneMatch)))
   970  	}
   971  	if len(xMsSourceIfModifiedSince) > 0 {
   972  		preparer = autorest.DecoratePreparer(preparer,
   973  			autorest.WithHeader("x-ms-source-if-modified-since", autorest.String(xMsSourceIfModifiedSince)))
   974  	}
   975  	if len(xMsSourceIfUnmodifiedSince) > 0 {
   976  		preparer = autorest.DecoratePreparer(preparer,
   977  			autorest.WithHeader("x-ms-source-if-unmodified-since", autorest.String(xMsSourceIfUnmodifiedSince)))
   978  	}
   979  	if len(xMsClientRequestID) > 0 {
   980  		preparer = autorest.DecoratePreparer(preparer,
   981  			autorest.WithHeader("x-ms-client-request-id", autorest.String(xMsClientRequestID)))
   982  	}
   983  	if len(xMsDate) > 0 {
   984  		preparer = autorest.DecoratePreparer(preparer,
   985  			autorest.WithHeader("x-ms-date", autorest.String(xMsDate)))
   986  	}
   987  	if len(client.XMsVersion) > 0 {
   988  		preparer = autorest.DecoratePreparer(preparer,
   989  			autorest.WithHeader("x-ms-version", autorest.String(client.XMsVersion)))
   990  	}
   991  	return preparer.Prepare((client.defaultRequest()).WithContext(ctx))
   992  }
   993  
   994  // CreateSender sends the Create request. The method will close the
   995  // http.Response Body if it receives an error.
   996  func (client adl2PathClient) CreateSender(req *http.Request) (*http.Response, error) {
   997  	sd := autorest.GetSendDecorators(req.Context(), autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
   998  	return autorest.SendWithSender(client, req, sd...)
   999  }
  1000  
  1001  // CreateResponder handles the response to the Create request. The method always
  1002  // closes the http.Response Body.
  1003  func (client adl2PathClient) CreateResponder(resp *http.Response) (result autorest.Response, err error) {
  1004  	err = autorest.Respond(
  1005  		resp,
  1006  		client.ByInspecting(),
  1007  		azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated),
  1008  		autorest.ByClosing())
  1009  	result.Response = resp
  1010  	return
  1011  }
  1012  
  1013  func (client adl2PathClient) Delete(ctx context.Context, filesystem string, pathParameter string, recursive *bool, continuation string, xMsLeaseID string, ifMatch string, ifNoneMatch string, ifModifiedSince string, ifUnmodifiedSince string, xMsClientRequestID string, timeout *int32, xMsDate string) (result autorest.Response, err error) {
  1014  	req, err := client.DeletePreparer(ctx, filesystem, pathParameter, recursive, continuation, xMsLeaseID, ifMatch, ifNoneMatch, ifModifiedSince, ifUnmodifiedSince, xMsClientRequestID, timeout, xMsDate)
  1015  	if err != nil {
  1016  		err = autorest.NewErrorWithError(err, "storagedatalake.adl2PathClient", "Delete", nil, "Failure preparing request")
  1017  		return
  1018  	}
  1019  
  1020  	resp, err := client.DeleteSender(req)
  1021  	if err != nil {
  1022  		result.Response = resp
  1023  		err = autorest.NewErrorWithError(err, "storagedatalake.adl2PathClient", "Delete", resp, "Failure sending request")
  1024  		return
  1025  	}
  1026  
  1027  	result, err = client.DeleteResponder(resp)
  1028  	if err != nil {
  1029  		err = autorest.NewErrorWithError(err, "storagedatalake.adl2PathClient", "Delete", resp, "Failure responding to request")
  1030  	}
  1031  
  1032  	return
  1033  }
  1034  
  1035  // DeletePreparer prepares the Delete request.
  1036  func (client adl2PathClient) DeletePreparer(ctx context.Context, filesystem string, pathParameter string, recursive *bool, continuation string, xMsLeaseID string, ifMatch string, ifNoneMatch string, ifModifiedSince string, ifUnmodifiedSince string, xMsClientRequestID string, timeout *int32, xMsDate string) (*http.Request, error) {
  1037  	urlParameters := map[string]interface{}{
  1038  		"accountName": client.AccountName,
  1039  		"dnsSuffix":   client.DNSSuffix,
  1040  	}
  1041  
  1042  	pathParameters := map[string]interface{}{
  1043  		"filesystem": autorest.Encode("path", filesystem),
  1044  		"path":       autorest.Encode("path", pathParameter),
  1045  	}
  1046  
  1047  	queryParameters := map[string]interface{}{}
  1048  	if recursive != nil {
  1049  		queryParameters["recursive"] = autorest.Encode("query", *recursive)
  1050  	}
  1051  	if len(continuation) > 0 {
  1052  		queryParameters["continuation"] = autorest.Encode("query", continuation)
  1053  	}
  1054  	if timeout != nil {
  1055  		queryParameters["timeout"] = autorest.Encode("query", *timeout)
  1056  	}
  1057  
  1058  	preparer := autorest.CreatePreparer(
  1059  		autorest.AsDelete(),
  1060  		autorest.WithCustomBaseURL("http://{accountName}.{dnsSuffix}", urlParameters),
  1061  		autorest.WithPathParameters("/{filesystem}/{path}", pathParameters),
  1062  		autorest.WithQueryParameters(queryParameters))
  1063  	if len(xMsLeaseID) > 0 {
  1064  		preparer = autorest.DecoratePreparer(preparer,
  1065  			autorest.WithHeader("x-ms-lease-id", autorest.String(xMsLeaseID)))
  1066  	}
  1067  	if len(ifMatch) > 0 {
  1068  		preparer = autorest.DecoratePreparer(preparer,
  1069  			autorest.WithHeader("If-Match", autorest.String(ifMatch)))
  1070  	}
  1071  	if len(ifNoneMatch) > 0 {
  1072  		preparer = autorest.DecoratePreparer(preparer,
  1073  			autorest.WithHeader("If-None-Match", autorest.String(ifNoneMatch)))
  1074  	}
  1075  	if len(ifModifiedSince) > 0 {
  1076  		preparer = autorest.DecoratePreparer(preparer,
  1077  			autorest.WithHeader("If-Modified-Since", autorest.String(ifModifiedSince)))
  1078  	}
  1079  	if len(ifUnmodifiedSince) > 0 {
  1080  		preparer = autorest.DecoratePreparer(preparer,
  1081  			autorest.WithHeader("If-Unmodified-Since", autorest.String(ifUnmodifiedSince)))
  1082  	}
  1083  	if len(xMsClientRequestID) > 0 {
  1084  		preparer = autorest.DecoratePreparer(preparer,
  1085  			autorest.WithHeader("x-ms-client-request-id", autorest.String(xMsClientRequestID)))
  1086  	}
  1087  	if len(xMsDate) > 0 {
  1088  		preparer = autorest.DecoratePreparer(preparer,
  1089  			autorest.WithHeader("x-ms-date", autorest.String(xMsDate)))
  1090  	}
  1091  	if len(client.XMsVersion) > 0 {
  1092  		preparer = autorest.DecoratePreparer(preparer,
  1093  			autorest.WithHeader("x-ms-version", autorest.String(client.XMsVersion)))
  1094  	}
  1095  	return preparer.Prepare((client.defaultRequest()).WithContext(ctx))
  1096  }
  1097  
  1098  // DeleteSender sends the Delete request. The method will close the
  1099  // http.Response Body if it receives an error.
  1100  func (client adl2PathClient) DeleteSender(req *http.Request) (*http.Response, error) {
  1101  	sd := autorest.GetSendDecorators(req.Context(), autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
  1102  	return autorest.SendWithSender(client, req, sd...)
  1103  }
  1104  
  1105  // DeleteResponder handles the response to the Delete request. The method always
  1106  // closes the http.Response Body.
  1107  func (client adl2PathClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) {
  1108  	err = autorest.Respond(
  1109  		resp,
  1110  		client.ByInspecting(),
  1111  		azure.WithErrorUnlessStatusCode(http.StatusOK),
  1112  		autorest.ByClosing())
  1113  	result.Response = resp
  1114  	return
  1115  }
  1116  
  1117  func (client adl2PathClient) GetProperties(ctx context.Context, filesystem string, pathParameter string, action adl2.PathGetPropertiesAction, upn *bool, xMsLeaseID string, ifMatch string, ifNoneMatch string, ifModifiedSince string, ifUnmodifiedSince string, xMsClientRequestID string, timeout *int32, xMsDate string) (result autorest.Response, err error) {
  1118  	req, err := client.GetPropertiesPreparer(ctx, filesystem, pathParameter, action, upn, xMsLeaseID, ifMatch, ifNoneMatch, ifModifiedSince, ifUnmodifiedSince, xMsClientRequestID, timeout, xMsDate)
  1119  	if err != nil {
  1120  		err = autorest.NewErrorWithError(err, "storagedatalake.adl2PathClient", "GetProperties", nil, "Failure preparing request")
  1121  		return
  1122  	}
  1123  
  1124  	resp, err := client.GetPropertiesSender(req)
  1125  	if err != nil {
  1126  		result.Response = resp
  1127  		err = autorest.NewErrorWithError(err, "storagedatalake.adl2PathClient", "GetProperties", resp, "Failure sending request")
  1128  		return
  1129  	}
  1130  
  1131  	result, err = client.GetPropertiesResponder(resp)
  1132  	if err != nil {
  1133  		err = autorest.NewErrorWithError(err, "storagedatalake.adl2PathClient", "GetProperties", resp, "Failure responding to request")
  1134  	}
  1135  
  1136  	return
  1137  }
  1138  
  1139  // GetPropertiesPreparer prepares the GetProperties request.
  1140  func (client adl2PathClient) GetPropertiesPreparer(ctx context.Context, filesystem string, pathParameter string, action adl2.PathGetPropertiesAction, upn *bool, xMsLeaseID string, ifMatch string, ifNoneMatch string, ifModifiedSince string, ifUnmodifiedSince string, xMsClientRequestID string, timeout *int32, xMsDate string) (*http.Request, error) {
  1141  	urlParameters := map[string]interface{}{
  1142  		"accountName": client.AccountName,
  1143  		"dnsSuffix":   client.DNSSuffix,
  1144  	}
  1145  
  1146  	pathParameters := map[string]interface{}{
  1147  		"filesystem": autorest.Encode("path", filesystem),
  1148  		"path":       autorest.Encode("path", pathParameter),
  1149  	}
  1150  
  1151  	queryParameters := map[string]interface{}{}
  1152  	if len(string(action)) > 0 {
  1153  		queryParameters["action"] = autorest.Encode("query", action)
  1154  	}
  1155  	if upn != nil {
  1156  		queryParameters["upn"] = autorest.Encode("query", *upn)
  1157  	}
  1158  	if timeout != nil {
  1159  		queryParameters["timeout"] = autorest.Encode("query", *timeout)
  1160  	}
  1161  
  1162  	preparer := autorest.CreatePreparer(
  1163  		autorest.AsHead(),
  1164  		autorest.WithCustomBaseURL("http://{accountName}.{dnsSuffix}", urlParameters),
  1165  		autorest.WithPathParameters("/{filesystem}/{path}", pathParameters),
  1166  		autorest.WithQueryParameters(queryParameters))
  1167  	if len(xMsLeaseID) > 0 {
  1168  		preparer = autorest.DecoratePreparer(preparer,
  1169  			autorest.WithHeader("x-ms-lease-id", autorest.String(xMsLeaseID)))
  1170  	}
  1171  	if len(ifMatch) > 0 {
  1172  		preparer = autorest.DecoratePreparer(preparer,
  1173  			autorest.WithHeader("If-Match", autorest.String(ifMatch)))
  1174  	}
  1175  	if len(ifNoneMatch) > 0 {
  1176  		preparer = autorest.DecoratePreparer(preparer,
  1177  			autorest.WithHeader("If-None-Match", autorest.String(ifNoneMatch)))
  1178  	}
  1179  	if len(ifModifiedSince) > 0 {
  1180  		preparer = autorest.DecoratePreparer(preparer,
  1181  			autorest.WithHeader("If-Modified-Since", autorest.String(ifModifiedSince)))
  1182  	}
  1183  	if len(ifUnmodifiedSince) > 0 {
  1184  		preparer = autorest.DecoratePreparer(preparer,
  1185  			autorest.WithHeader("If-Unmodified-Since", autorest.String(ifUnmodifiedSince)))
  1186  	}
  1187  	if len(xMsClientRequestID) > 0 {
  1188  		preparer = autorest.DecoratePreparer(preparer,
  1189  			autorest.WithHeader("x-ms-client-request-id", autorest.String(xMsClientRequestID)))
  1190  	}
  1191  	if len(xMsDate) > 0 {
  1192  		preparer = autorest.DecoratePreparer(preparer,
  1193  			autorest.WithHeader("x-ms-date", autorest.String(xMsDate)))
  1194  	}
  1195  	if len(client.XMsVersion) > 0 {
  1196  		preparer = autorest.DecoratePreparer(preparer,
  1197  			autorest.WithHeader("x-ms-version", autorest.String(client.XMsVersion)))
  1198  	}
  1199  	return preparer.Prepare((client.defaultRequest()).WithContext(ctx))
  1200  }
  1201  
  1202  // GetPropertiesSender sends the GetProperties request. The method will close the
  1203  // http.Response Body if it receives an error.
  1204  func (client adl2PathClient) GetPropertiesSender(req *http.Request) (*http.Response, error) {
  1205  	sd := autorest.GetSendDecorators(req.Context(), autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
  1206  	return autorest.SendWithSender(client, req, sd...)
  1207  }
  1208  
  1209  // GetPropertiesResponder handles the response to the GetProperties request. The method always
  1210  // closes the http.Response Body.
  1211  func (client adl2PathClient) GetPropertiesResponder(resp *http.Response) (result autorest.Response, err error) {
  1212  	err = autorest.Respond(
  1213  		resp,
  1214  		client.ByInspecting(),
  1215  		azure.WithErrorUnlessStatusCode(http.StatusOK),
  1216  		autorest.ByClosing())
  1217  	result.Response = resp
  1218  	return
  1219  }
  1220  
  1221  func (client adl2PathClient) Lease(ctx context.Context, xMsLeaseAction adl2.PathLeaseAction, filesystem string, pathParameter string, xMsLeaseDuration *int32, xMsLeaseBreakPeriod *int32, xMsLeaseID string, xMsProposedLeaseID string, ifMatch string, ifNoneMatch string, ifModifiedSince string, ifUnmodifiedSince string, xMsClientRequestID string, timeout *int32, xMsDate string) (result autorest.Response, err error) {
  1222  	req, err := client.LeasePreparer(ctx, xMsLeaseAction, filesystem, pathParameter, xMsLeaseDuration, xMsLeaseBreakPeriod, xMsLeaseID, xMsProposedLeaseID, ifMatch, ifNoneMatch, ifModifiedSince, ifUnmodifiedSince, xMsClientRequestID, timeout, xMsDate)
  1223  	if err != nil {
  1224  		err = autorest.NewErrorWithError(err, "storagedatalake.adl2PathClient", "Lease", nil, "Failure preparing request")
  1225  		return
  1226  	}
  1227  
  1228  	resp, err := client.LeaseSender(req)
  1229  	if err != nil {
  1230  		result.Response = resp
  1231  		err = autorest.NewErrorWithError(err, "storagedatalake.adl2PathClient", "Lease", resp, "Failure sending request")
  1232  		return
  1233  	}
  1234  
  1235  	result, err = client.LeaseResponder(resp)
  1236  	if err != nil {
  1237  		err = autorest.NewErrorWithError(err, "storagedatalake.adl2PathClient", "Lease", resp, "Failure responding to request")
  1238  	}
  1239  
  1240  	return
  1241  }
  1242  
  1243  // LeasePreparer prepares the Lease request.
  1244  func (client adl2PathClient) LeasePreparer(ctx context.Context, xMsLeaseAction adl2.PathLeaseAction, filesystem string, pathParameter string, xMsLeaseDuration *int32, xMsLeaseBreakPeriod *int32, xMsLeaseID string, xMsProposedLeaseID string, ifMatch string, ifNoneMatch string, ifModifiedSince string, ifUnmodifiedSince string, xMsClientRequestID string, timeout *int32, xMsDate string) (*http.Request, error) {
  1245  	urlParameters := map[string]interface{}{
  1246  		"accountName": client.AccountName,
  1247  		"dnsSuffix":   client.DNSSuffix,
  1248  	}
  1249  
  1250  	pathParameters := map[string]interface{}{
  1251  		"filesystem": autorest.Encode("path", filesystem),
  1252  		"path":       autorest.Encode("path", pathParameter),
  1253  	}
  1254  
  1255  	queryParameters := map[string]interface{}{}
  1256  	if timeout != nil {
  1257  		queryParameters["timeout"] = autorest.Encode("query", *timeout)
  1258  	}
  1259  
  1260  	preparer := autorest.CreatePreparer(
  1261  		autorest.AsPost(),
  1262  		autorest.WithCustomBaseURL("http://{accountName}.{dnsSuffix}", urlParameters),
  1263  		autorest.WithPathParameters("/{filesystem}/{path}", pathParameters),
  1264  		autorest.WithQueryParameters(queryParameters),
  1265  		autorest.WithHeader("x-ms-lease-action", autorest.String(xMsLeaseAction)))
  1266  	if xMsLeaseDuration != nil {
  1267  		preparer = autorest.DecoratePreparer(preparer,
  1268  			autorest.WithHeader("x-ms-lease-duration", autorest.String(*xMsLeaseDuration)))
  1269  	}
  1270  	if xMsLeaseBreakPeriod != nil {
  1271  		preparer = autorest.DecoratePreparer(preparer,
  1272  			autorest.WithHeader("x-ms-lease-break-period", autorest.String(*xMsLeaseBreakPeriod)))
  1273  	}
  1274  	if len(xMsLeaseID) > 0 {
  1275  		preparer = autorest.DecoratePreparer(preparer,
  1276  			autorest.WithHeader("x-ms-lease-id", autorest.String(xMsLeaseID)))
  1277  	}
  1278  	if len(xMsProposedLeaseID) > 0 {
  1279  		preparer = autorest.DecoratePreparer(preparer,
  1280  			autorest.WithHeader("x-ms-proposed-lease-id", autorest.String(xMsProposedLeaseID)))
  1281  	}
  1282  	if len(ifMatch) > 0 {
  1283  		preparer = autorest.DecoratePreparer(preparer,
  1284  			autorest.WithHeader("If-Match", autorest.String(ifMatch)))
  1285  	}
  1286  	if len(ifNoneMatch) > 0 {
  1287  		preparer = autorest.DecoratePreparer(preparer,
  1288  			autorest.WithHeader("If-None-Match", autorest.String(ifNoneMatch)))
  1289  	}
  1290  	if len(ifModifiedSince) > 0 {
  1291  		preparer = autorest.DecoratePreparer(preparer,
  1292  			autorest.WithHeader("If-Modified-Since", autorest.String(ifModifiedSince)))
  1293  	}
  1294  	if len(ifUnmodifiedSince) > 0 {
  1295  		preparer = autorest.DecoratePreparer(preparer,
  1296  			autorest.WithHeader("If-Unmodified-Since", autorest.String(ifUnmodifiedSince)))
  1297  	}
  1298  	if len(xMsClientRequestID) > 0 {
  1299  		preparer = autorest.DecoratePreparer(preparer,
  1300  			autorest.WithHeader("x-ms-client-request-id", autorest.String(xMsClientRequestID)))
  1301  	}
  1302  	if len(xMsDate) > 0 {
  1303  		preparer = autorest.DecoratePreparer(preparer,
  1304  			autorest.WithHeader("x-ms-date", autorest.String(xMsDate)))
  1305  	}
  1306  	if len(client.XMsVersion) > 0 {
  1307  		preparer = autorest.DecoratePreparer(preparer,
  1308  			autorest.WithHeader("x-ms-version", autorest.String(client.XMsVersion)))
  1309  	}
  1310  	return preparer.Prepare((client.defaultRequest()).WithContext(ctx))
  1311  }
  1312  
  1313  // LeaseSender sends the Lease request. The method will close the
  1314  // http.Response Body if it receives an error.
  1315  func (client adl2PathClient) LeaseSender(req *http.Request) (*http.Response, error) {
  1316  	sd := autorest.GetSendDecorators(req.Context(), autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
  1317  	return autorest.SendWithSender(client, req, sd...)
  1318  }
  1319  
  1320  // LeaseResponder handles the response to the Lease request. The method always
  1321  // closes the http.Response Body.
  1322  func (client adl2PathClient) LeaseResponder(resp *http.Response) (result autorest.Response, err error) {
  1323  	err = autorest.Respond(
  1324  		resp,
  1325  		client.ByInspecting(),
  1326  		azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated, http.StatusAccepted),
  1327  		autorest.ByClosing())
  1328  	result.Response = resp
  1329  	return
  1330  }
  1331  
  1332  func (client adl2PathClient) List(ctx context.Context, recursive bool, filesystem string, directory string, continuation string, maxResults *int32, upn *bool, xMsClientRequestID string, timeout *int32, xMsDate string) (result adl2PathList, err error) {
  1333  	req, err := client.ListPreparer(ctx, recursive, filesystem, directory, continuation, maxResults, upn, xMsClientRequestID, timeout, xMsDate)
  1334  	if err != nil {
  1335  		err = autorest.NewErrorWithError(err, "storagedatalake.adl2PathClient", "List", nil, "Failure preparing request")
  1336  		return
  1337  	}
  1338  
  1339  	resp, err := client.ListSender(req)
  1340  	if err != nil {
  1341  		result.Response = autorest.Response{Response: resp}
  1342  		err = autorest.NewErrorWithError(err, "storagedatalake.adl2PathClient", "List", resp, "Failure sending request")
  1343  		return
  1344  	}
  1345  
  1346  	result, err = client.ListResponder(resp)
  1347  	if err != nil {
  1348  		err = autorest.NewErrorWithError(err, "storagedatalake.adl2PathClient", "List", resp, "Failure responding to request")
  1349  	}
  1350  
  1351  	return
  1352  }
  1353  
  1354  // ListPreparer prepares the List request.
  1355  func (client adl2PathClient) ListPreparer(ctx context.Context, recursive bool, filesystem string, directory string, continuation string, maxResults *int32, upn *bool, xMsClientRequestID string, timeout *int32, xMsDate string) (*http.Request, error) {
  1356  	urlParameters := map[string]interface{}{
  1357  		"accountName": client.AccountName,
  1358  		"dnsSuffix":   client.DNSSuffix,
  1359  	}
  1360  
  1361  	pathParameters := map[string]interface{}{
  1362  		"filesystem": autorest.Encode("path", filesystem),
  1363  	}
  1364  
  1365  	queryParameters := map[string]interface{}{
  1366  		"recursive": autorest.Encode("query", recursive),
  1367  		"resource":  autorest.Encode("query", "filesystem"),
  1368  	}
  1369  	if len(directory) > 0 {
  1370  		queryParameters["directory"] = autorest.Encode("query", directory)
  1371  	}
  1372  	if len(continuation) > 0 {
  1373  		queryParameters["continuation"] = autorest.Encode("query", continuation)
  1374  	}
  1375  	if maxResults != nil {
  1376  		queryParameters["maxresults"] = autorest.Encode("query", *maxResults)
  1377  	}
  1378  	if upn != nil {
  1379  		queryParameters["upn"] = autorest.Encode("query", *upn)
  1380  	}
  1381  	if timeout != nil {
  1382  		queryParameters["timeout"] = autorest.Encode("query", *timeout)
  1383  	}
  1384  
  1385  	preparer := autorest.CreatePreparer(
  1386  		autorest.AsGet(),
  1387  		autorest.WithCustomBaseURL("http://{accountName}.{dnsSuffix}", urlParameters),
  1388  		autorest.WithPathParameters("/{filesystem}", pathParameters),
  1389  		autorest.WithQueryParameters(queryParameters))
  1390  	if len(xMsClientRequestID) > 0 {
  1391  		preparer = autorest.DecoratePreparer(preparer,
  1392  			autorest.WithHeader("x-ms-client-request-id", autorest.String(xMsClientRequestID)))
  1393  	}
  1394  	if len(xMsDate) > 0 {
  1395  		preparer = autorest.DecoratePreparer(preparer,
  1396  			autorest.WithHeader("x-ms-date", autorest.String(xMsDate)))
  1397  	}
  1398  	if len(client.XMsVersion) > 0 {
  1399  		preparer = autorest.DecoratePreparer(preparer,
  1400  			autorest.WithHeader("x-ms-version", autorest.String(client.XMsVersion)))
  1401  	}
  1402  	return preparer.Prepare((client.defaultRequest()).WithContext(ctx))
  1403  }
  1404  
  1405  // ListSender sends the List request. The method will close the
  1406  // http.Response Body if it receives an error.
  1407  func (client adl2PathClient) ListSender(req *http.Request) (*http.Response, error) {
  1408  	sd := autorest.GetSendDecorators(req.Context(), autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
  1409  	return autorest.SendWithSender(client, req, sd...)
  1410  }
  1411  
  1412  // ListResponder handles the response to the List request. The method always
  1413  // closes the http.Response Body.
  1414  func (client adl2PathClient) ListResponder(resp *http.Response) (result adl2PathList, err error) {
  1415  	err = autorest.Respond(
  1416  		resp,
  1417  		client.ByInspecting(),
  1418  		azure.WithErrorUnlessStatusCode(http.StatusOK),
  1419  		autorest.ByUnmarshallingJSON(&result),
  1420  		autorest.ByClosing())
  1421  	result.Response = autorest.Response{Response: resp}
  1422  	return
  1423  }
  1424  
  1425  func (client adl2PathClient) Read(ctx context.Context, filesystem string, pathParameter string, rangeParameter string, xMsLeaseID string, xMsRangeGetContentMd5 *bool, ifMatch string, ifNoneMatch string, ifModifiedSince string, ifUnmodifiedSince string, xMsClientRequestID string, timeout *int32, xMsDate string) (result adl2.ReadCloser, err error) {
  1426  	req, err := client.ReadPreparer(ctx, filesystem, pathParameter, rangeParameter, xMsLeaseID, xMsRangeGetContentMd5, ifMatch, ifNoneMatch, ifModifiedSince, ifUnmodifiedSince, xMsClientRequestID, timeout, xMsDate)
  1427  	if err != nil {
  1428  		err = autorest.NewErrorWithError(err, "storagedatalake.adl2PathClient", "Read", nil, "Failure preparing request")
  1429  		return
  1430  	}
  1431  
  1432  	resp, err := client.ReadSender(req)
  1433  	if err != nil {
  1434  		result.Response = autorest.Response{Response: resp}
  1435  		err = autorest.NewErrorWithError(err, "storagedatalake.adl2PathClient", "Read", resp, "Failure sending request")
  1436  		return
  1437  	}
  1438  
  1439  	result, err = client.ReadResponder(resp)
  1440  	if err != nil {
  1441  		err = autorest.NewErrorWithError(err, "storagedatalake.adl2PathClient", "Read", resp, "Failure responding to request")
  1442  	}
  1443  
  1444  	return
  1445  }
  1446  
  1447  // ReadPreparer prepares the Read request.
  1448  func (client adl2PathClient) ReadPreparer(ctx context.Context, filesystem string, pathParameter string, rangeParameter string, xMsLeaseID string, xMsRangeGetContentMd5 *bool, ifMatch string, ifNoneMatch string, ifModifiedSince string, ifUnmodifiedSince string, xMsClientRequestID string, timeout *int32, xMsDate string) (*http.Request, error) {
  1449  	urlParameters := map[string]interface{}{
  1450  		"accountName": client.AccountName,
  1451  		"dnsSuffix":   client.DNSSuffix,
  1452  	}
  1453  
  1454  	pathParameters := map[string]interface{}{
  1455  		"filesystem": autorest.Encode("path", filesystem),
  1456  		"path":       autorest.Encode("path", pathParameter),
  1457  	}
  1458  
  1459  	queryParameters := map[string]interface{}{}
  1460  	if timeout != nil {
  1461  		queryParameters["timeout"] = autorest.Encode("query", *timeout)
  1462  	}
  1463  
  1464  	preparer := autorest.CreatePreparer(
  1465  		autorest.AsGet(),
  1466  		autorest.WithCustomBaseURL("http://{accountName}.{dnsSuffix}", urlParameters),
  1467  		autorest.WithPathParameters("/{filesystem}/{path}", pathParameters),
  1468  		autorest.WithQueryParameters(queryParameters))
  1469  	if len(rangeParameter) > 0 {
  1470  		preparer = autorest.DecoratePreparer(preparer,
  1471  			autorest.WithHeader("Range", autorest.String(rangeParameter)))
  1472  	}
  1473  	if len(xMsLeaseID) > 0 {
  1474  		preparer = autorest.DecoratePreparer(preparer,
  1475  			autorest.WithHeader("x-ms-lease-id", autorest.String(xMsLeaseID)))
  1476  	}
  1477  	if xMsRangeGetContentMd5 != nil {
  1478  		preparer = autorest.DecoratePreparer(preparer,
  1479  			autorest.WithHeader("x-ms-range-get-content-md5", autorest.String(*xMsRangeGetContentMd5)))
  1480  	}
  1481  	if len(ifMatch) > 0 {
  1482  		preparer = autorest.DecoratePreparer(preparer,
  1483  			autorest.WithHeader("If-Match", autorest.String(ifMatch)))
  1484  	}
  1485  	if len(ifNoneMatch) > 0 {
  1486  		preparer = autorest.DecoratePreparer(preparer,
  1487  			autorest.WithHeader("If-None-Match", autorest.String(ifNoneMatch)))
  1488  	}
  1489  	if len(ifModifiedSince) > 0 {
  1490  		preparer = autorest.DecoratePreparer(preparer,
  1491  			autorest.WithHeader("If-Modified-Since", autorest.String(ifModifiedSince)))
  1492  	}
  1493  	if len(ifUnmodifiedSince) > 0 {
  1494  		preparer = autorest.DecoratePreparer(preparer,
  1495  			autorest.WithHeader("If-Unmodified-Since", autorest.String(ifUnmodifiedSince)))
  1496  	}
  1497  	if len(xMsClientRequestID) > 0 {
  1498  		preparer = autorest.DecoratePreparer(preparer,
  1499  			autorest.WithHeader("x-ms-client-request-id", autorest.String(xMsClientRequestID)))
  1500  	}
  1501  	if len(xMsDate) > 0 {
  1502  		preparer = autorest.DecoratePreparer(preparer,
  1503  			autorest.WithHeader("x-ms-date", autorest.String(xMsDate)))
  1504  	}
  1505  	if len(client.XMsVersion) > 0 {
  1506  		preparer = autorest.DecoratePreparer(preparer,
  1507  			autorest.WithHeader("x-ms-version", autorest.String(client.XMsVersion)))
  1508  	}
  1509  	return preparer.Prepare((client.defaultRequest()).WithContext(ctx))
  1510  }
  1511  
  1512  // ReadSender sends the Read request. The method will close the
  1513  // http.Response Body if it receives an error.
  1514  func (client adl2PathClient) ReadSender(req *http.Request) (*http.Response, error) {
  1515  	sd := autorest.GetSendDecorators(req.Context(), autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
  1516  	return autorest.SendWithSender(client, req, sd...)
  1517  }
  1518  
  1519  // ReadResponder handles the response to the Read request. The method always
  1520  // closes the http.Response Body.
  1521  func (client adl2PathClient) ReadResponder(resp *http.Response) (result adl2.ReadCloser, err error) {
  1522  	result.Value = &resp.Body
  1523  	err = autorest.Respond(
  1524  		resp,
  1525  		client.ByInspecting(),
  1526  		azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusPartialContent))
  1527  	result.Response = autorest.Response{Response: resp}
  1528  	return
  1529  }
  1530  
  1531  func (client adl2PathClient) Update(ctx context.Context, action adl2.PathUpdateAction, filesystem string, pathParameter string, position *int64, retainUncommittedData *bool, closeParameter *bool, contentLength *int64, contentMD5 string, xMsLeaseID string, xMsCacheControl string, xMsContentType string, xMsContentDisposition string, xMsContentEncoding string, xMsContentLanguage string, xMsContentMd5 string, xMsProperties string, xMsOwner string, xMsGroup string, xMsPermissions string, xMsACL string, ifMatch string, ifNoneMatch string, ifModifiedSince string, ifUnmodifiedSince string, requestBody io.ReadCloser, xMsClientRequestID string, timeout *int32, xMsDate string) (result autorest.Response, err error) {
  1532  	req, err := client.UpdatePreparer(ctx, action, filesystem, pathParameter, position, retainUncommittedData, closeParameter, contentLength, contentMD5, xMsLeaseID, xMsCacheControl, xMsContentType, xMsContentDisposition, xMsContentEncoding, xMsContentLanguage, xMsContentMd5, xMsProperties, xMsOwner, xMsGroup, xMsPermissions, xMsACL, ifMatch, ifNoneMatch, ifModifiedSince, ifUnmodifiedSince, requestBody, xMsClientRequestID, timeout, xMsDate)
  1533  	if err != nil {
  1534  		err = autorest.NewErrorWithError(err, "storagedatalake.adl2PathClient", "Update", nil, "Failure preparing request")
  1535  		return
  1536  	}
  1537  
  1538  	resp, err := client.UpdateSender(req)
  1539  	if err != nil {
  1540  		result.Response = resp
  1541  		err = autorest.NewErrorWithError(err, "storagedatalake.adl2PathClient", "Update", resp, "Failure sending request")
  1542  		return
  1543  	}
  1544  
  1545  	result, err = client.UpdateResponder(resp)
  1546  	if err != nil {
  1547  		err = autorest.NewErrorWithError(err, "storagedatalake.adl2PathClient", "Update", resp, "Failure responding to request")
  1548  	}
  1549  
  1550  	return
  1551  }
  1552  
  1553  // UpdatePreparer prepares the Update request.
  1554  func (client adl2PathClient) UpdatePreparer(ctx context.Context, action adl2.PathUpdateAction, filesystem string, pathParameter string, position *int64, retainUncommittedData *bool, closeParameter *bool, contentLength *int64, contentMD5 string, xMsLeaseID string, xMsCacheControl string, xMsContentType string, xMsContentDisposition string, xMsContentEncoding string, xMsContentLanguage string, xMsContentMd5 string, xMsProperties string, xMsOwner string, xMsGroup string, xMsPermissions string, xMsACL string, ifMatch string, ifNoneMatch string, ifModifiedSince string, ifUnmodifiedSince string, requestBody io.ReadCloser, xMsClientRequestID string, timeout *int32, xMsDate string) (*http.Request, error) {
  1555  	urlParameters := map[string]interface{}{
  1556  		"accountName": client.AccountName,
  1557  		"dnsSuffix":   client.DNSSuffix,
  1558  	}
  1559  
  1560  	pathParameters := map[string]interface{}{
  1561  		"filesystem": autorest.Encode("path", filesystem),
  1562  		"path":       autorest.Encode("path", pathParameter),
  1563  	}
  1564  
  1565  	queryParameters := map[string]interface{}{
  1566  		"action": autorest.Encode("query", action),
  1567  	}
  1568  	if position != nil {
  1569  		queryParameters["position"] = autorest.Encode("query", *position)
  1570  	}
  1571  	if retainUncommittedData != nil {
  1572  		// query params need to be lower case otherwise azure-storage-blob-go's
  1573  		// SharedKeyCredential signing won't work:
  1574  		// https://github.com/Azure/azure-storage-blob-go/issues/146
  1575  		queryParameters["retainuncommitteddata"] = autorest.Encode("query", *retainUncommittedData)
  1576  	}
  1577  	if closeParameter != nil {
  1578  		queryParameters["close"] = autorest.Encode("query", *closeParameter)
  1579  	}
  1580  	if timeout != nil {
  1581  		queryParameters["timeout"] = autorest.Encode("query", *timeout)
  1582  	}
  1583  
  1584  	preparer := autorest.CreatePreparer(
  1585  		autorest.AsContentType("application/octet-stream"),
  1586  		autorest.AsPatch(),
  1587  		autorest.WithCustomBaseURL("http://{accountName}.{dnsSuffix}", urlParameters),
  1588  		autorest.WithPathParameters("/{filesystem}/{path}", pathParameters),
  1589  		autorest.WithQueryParameters(queryParameters))
  1590  	if requestBody != nil {
  1591  		preparer = autorest.DecoratePreparer(preparer,
  1592  			autorest.WithFile(requestBody))
  1593  	}
  1594  	if contentLength != nil {
  1595  		preparer = autorest.DecoratePreparer(preparer,
  1596  			autorest.WithHeader("Content-Length", autorest.String(*contentLength)))
  1597  	}
  1598  	if len(contentMD5) > 0 {
  1599  		preparer = autorest.DecoratePreparer(preparer,
  1600  			autorest.WithHeader("Content-MD5", autorest.String(contentMD5)))
  1601  	}
  1602  	if len(xMsLeaseID) > 0 {
  1603  		preparer = autorest.DecoratePreparer(preparer,
  1604  			autorest.WithHeader("x-ms-lease-id", autorest.String(xMsLeaseID)))
  1605  	}
  1606  	if len(xMsCacheControl) > 0 {
  1607  		preparer = autorest.DecoratePreparer(preparer,
  1608  			autorest.WithHeader("x-ms-cache-control", autorest.String(xMsCacheControl)))
  1609  	}
  1610  	if len(xMsContentType) > 0 {
  1611  		preparer = autorest.DecoratePreparer(preparer,
  1612  			autorest.WithHeader("x-ms-content-type", autorest.String(xMsContentType)))
  1613  	}
  1614  	if len(xMsContentDisposition) > 0 {
  1615  		preparer = autorest.DecoratePreparer(preparer,
  1616  			autorest.WithHeader("x-ms-content-disposition", autorest.String(xMsContentDisposition)))
  1617  	}
  1618  	if len(xMsContentEncoding) > 0 {
  1619  		preparer = autorest.DecoratePreparer(preparer,
  1620  			autorest.WithHeader("x-ms-content-encoding", autorest.String(xMsContentEncoding)))
  1621  	}
  1622  	if len(xMsContentLanguage) > 0 {
  1623  		preparer = autorest.DecoratePreparer(preparer,
  1624  			autorest.WithHeader("x-ms-content-language", autorest.String(xMsContentLanguage)))
  1625  	}
  1626  	if len(xMsContentMd5) > 0 {
  1627  		preparer = autorest.DecoratePreparer(preparer,
  1628  			autorest.WithHeader("x-ms-content-md5", autorest.String(xMsContentMd5)))
  1629  	}
  1630  	if len(xMsProperties) > 0 {
  1631  		preparer = autorest.DecoratePreparer(preparer,
  1632  			autorest.WithHeader("x-ms-properties", autorest.String(xMsProperties)))
  1633  	}
  1634  	if len(xMsOwner) > 0 {
  1635  		preparer = autorest.DecoratePreparer(preparer,
  1636  			autorest.WithHeader("x-ms-owner", autorest.String(xMsOwner)))
  1637  	}
  1638  	if len(xMsGroup) > 0 {
  1639  		preparer = autorest.DecoratePreparer(preparer,
  1640  			autorest.WithHeader("x-ms-group", autorest.String(xMsGroup)))
  1641  	}
  1642  	if len(xMsPermissions) > 0 {
  1643  		preparer = autorest.DecoratePreparer(preparer,
  1644  			autorest.WithHeader("x-ms-permissions", autorest.String(xMsPermissions)))
  1645  	}
  1646  	if len(xMsACL) > 0 {
  1647  		preparer = autorest.DecoratePreparer(preparer,
  1648  			autorest.WithHeader("x-ms-acl", autorest.String(xMsACL)))
  1649  	}
  1650  	if len(ifMatch) > 0 {
  1651  		preparer = autorest.DecoratePreparer(preparer,
  1652  			autorest.WithHeader("If-Match", autorest.String(ifMatch)))
  1653  	}
  1654  	if len(ifNoneMatch) > 0 {
  1655  		preparer = autorest.DecoratePreparer(preparer,
  1656  			autorest.WithHeader("If-None-Match", autorest.String(ifNoneMatch)))
  1657  	}
  1658  	if len(ifModifiedSince) > 0 {
  1659  		preparer = autorest.DecoratePreparer(preparer,
  1660  			autorest.WithHeader("If-Modified-Since", autorest.String(ifModifiedSince)))
  1661  	}
  1662  	if len(ifUnmodifiedSince) > 0 {
  1663  		preparer = autorest.DecoratePreparer(preparer,
  1664  			autorest.WithHeader("If-Unmodified-Since", autorest.String(ifUnmodifiedSince)))
  1665  	}
  1666  	if len(xMsClientRequestID) > 0 {
  1667  		preparer = autorest.DecoratePreparer(preparer,
  1668  			autorest.WithHeader("x-ms-client-request-id", autorest.String(xMsClientRequestID)))
  1669  	}
  1670  	if len(xMsDate) > 0 {
  1671  		preparer = autorest.DecoratePreparer(preparer,
  1672  			autorest.WithHeader("x-ms-date", autorest.String(xMsDate)))
  1673  	}
  1674  	if len(client.XMsVersion) > 0 {
  1675  		preparer = autorest.DecoratePreparer(preparer,
  1676  			autorest.WithHeader("x-ms-version", autorest.String(client.XMsVersion)))
  1677  	}
  1678  	return preparer.Prepare((client.defaultRequest()).WithContext(ctx))
  1679  }
  1680  
  1681  // UpdateSender sends the Update request. The method will close the
  1682  // http.Response Body if it receives an error.
  1683  func (client adl2PathClient) UpdateSender(req *http.Request) (*http.Response, error) {
  1684  
  1685  	sd := autorest.GetSendDecorators(req.Context(), autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
  1686  	return autorest.SendWithSender(client, req, sd...)
  1687  }
  1688  
  1689  // UpdateResponder handles the response to the Update request. The method always
  1690  // closes the http.Response Body.
  1691  func (client adl2PathClient) UpdateResponder(resp *http.Response) (result autorest.Response, err error) {
  1692  	err = autorest.Respond(
  1693  		resp,
  1694  		client.ByInspecting(),
  1695  		azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted),
  1696  		autorest.ByClosing())
  1697  	result.Response = resp
  1698  	return
  1699  }
  1700  
  1701  func (client adl2PathClient) defaultRequest() *http.Request {
  1702  	r := &http.Request{}
  1703  	r.GetBody = func() (io.ReadCloser, error) {
  1704  		if r.Body == nil {
  1705  			return http.NoBody, nil
  1706  		} else if seeker, ok := r.Body.(io.ReadSeeker); ok {
  1707  			// internally goofys always uses seekable
  1708  			// readers, so we can rewind on
  1709  			// retry. autorest makes a copy of the buffer
  1710  			// and this avoids that waste
  1711  			_, err := seeker.Seek(0, 0)
  1712  			return &ReadSeekerCloser{seeker}, err
  1713  		} else {
  1714  			panic(fmt.Sprintf("Wrong type: %T", r.Body))
  1715  		}
  1716  	}
  1717  	return r
  1718  }
  1719  
  1720  type adl2PathList struct {
  1721  	autorest.Response `json:"-"`
  1722  	Paths             *[]adl2Path `json:"paths,omitempty"`
  1723  }
  1724  
  1725  type adl2Path struct {
  1726  	Name          *string    `json:"name,omitempty"`
  1727  	IsDirectory   adl2Bool   `json:"isDirectory,omitempty"`
  1728  	LastModified  *string    `json:"lastModified,omitempty"`
  1729  	ETag          *string    `json:"eTag,omitempty"`
  1730  	ContentLength *adl2Int64 `json:"contentLength,omitempty"`
  1731  	Owner         *string    `json:"owner,omitempty"`
  1732  	Group         *string    `json:"group,omitempty"`
  1733  	Permissions   *string    `json:"permissions,omitempty"`
  1734  }
  1735  
  1736  func (p adl2Path) isDirectory() bool {
  1737  	return p.IsDirectory.boolValue()
  1738  }
  1739  
  1740  func (p adl2Path) contentLength() int64 {
  1741  	if p.ContentLength == nil {
  1742  		return 0
  1743  	} else {
  1744  		return p.ContentLength.intValue()
  1745  	}
  1746  }
  1747  
  1748  type adl2Bool struct {
  1749  	bool
  1750  }
  1751  
  1752  func (b adl2Bool) boolValue() bool {
  1753  	return b.bool
  1754  }
  1755  
  1756  func (b *adl2Bool) UnmarshalJSON(buf []byte) error {
  1757  	v := string(buf)
  1758  	b.bool = v == "true" || v == "\"true\"" || v == "'true'"
  1759  	return nil
  1760  }
  1761  
  1762  type adl2Int64 struct {
  1763  	int64
  1764  }
  1765  
  1766  func (b *adl2Int64) intValue() int64 {
  1767  	return b.int64
  1768  }
  1769  
  1770  func (b *adl2Int64) UnmarshalJSON(buf []byte) error {
  1771  	if len(buf) == 0 {
  1772  		return fmt.Errorf("no input")
  1773  	}
  1774  	if buf[0] == '"' {
  1775  		var v string
  1776  		err := json.Unmarshal(buf, &v)
  1777  		if err != nil {
  1778  			return err
  1779  		}
  1780  		b.int64, err = strconv.ParseInt(v, 10, 64)
  1781  		return err
  1782  	} else {
  1783  		err := json.Unmarshal(buf, &b.int64)
  1784  		return err
  1785  	}
  1786  }