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