File: properties_get.go

package info (click to toggle)
golang-github-tombuildsstuff-giovanni 0.20.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 15,908 kB
  • sloc: makefile: 3
file content (310 lines) | stat: -rw-r--r-- 13,004 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
package blobs

import (
	"context"
	"fmt"
	"net/http"
	"strconv"
	"strings"

	"github.com/Azure/go-autorest/autorest"
	"github.com/Azure/go-autorest/autorest/azure"
	"github.com/Azure/go-autorest/autorest/validation"
	"github.com/tombuildsstuff/giovanni/storage/internal/endpoints"
	"github.com/tombuildsstuff/giovanni/storage/internal/metadata"
)

type GetPropertiesInput struct {
	// The ID of the Lease
	// This must be specified if a Lease is present on the Blob, else a 403 is returned
	LeaseID *string
}

type GetPropertiesResult struct {
	autorest.Response

	// The tier of page blob on a premium storage account or tier of block blob on blob storage or general purpose v2 account.
	AccessTier AccessTier

	// This gives the last time tier was changed on the object.
	// This header is returned only if tier on block blob was ever set.
	// The date format follows RFC 1123
	AccessTierChangeTime string

	// For page blobs on a premium storage account only.
	// If the access tier is not explicitly set on the blob, the tier is inferred based on its content length
	// and this header will be returned with true value.
	// For block blobs on Blob Storage or general purpose v2 account, if the blob does not have the access tier
	// set then we infer the tier from the storage account properties. This header is set only if the block blob
	// tier is inferred
	AccessTierInferred bool

	// For blob storage or general purpose v2 account.
	// If the blob is being rehydrated and is not complete then this header is returned indicating
	// that rehydrate is pending and also tells the destination tier
	ArchiveStatus ArchiveStatus

	// The number of committed blocks present in the blob.
	// This header is returned only for append blobs.
	BlobCommittedBlockCount string

	// The current sequence number for a page blob.
	// This header is not returned for block blobs or append blobs.
	// This header is not returned for block blobs.
	BlobSequenceNumber string

	// The blob type.
	BlobType BlobType

	// If the Cache-Control request header has previously been set for the blob, that value is returned in this header.
	CacheControl string

	// The Content-Disposition response header field conveys additional information about how to process
	// the response payload, and also can be used to attach additional metadata.
	// For example, if set to attachment, it indicates that the user-agent should not display the response,
	// but instead show a Save As dialog.
	ContentDisposition string

	// If the Content-Encoding request header has previously been set for the blob,
	// that value is returned in this header.
	ContentEncoding string

	// If the Content-Language request header has previously been set for the blob,
	// that value is returned in this header.
	ContentLanguage string

	// The size of the blob in bytes.
	// For a page blob, this header returns the value of the x-ms-blob-content-length header stored with the blob.
	ContentLength int64

	// The content type specified for the blob.
	// If no content type was specified, the default content type is `application/octet-stream`.
	ContentType string

	// If the Content-MD5 header has been set for the blob, this response header is returned so that
	// the client can check for message content integrity.
	ContentMD5 string

	// Conclusion time of the last attempted Copy Blob operation where this blob was the destination blob.
	// This value can specify the time of a completed, aborted, or failed copy attempt.
	// This header does not appear if a copy is pending, if this blob has never been the
	// destination in a Copy Blob operation, or if this blob has been modified after a concluded Copy Blob
	// operation using Set Blob Properties, Put Blob, or Put Block List.
	CopyCompletionTime string

	// Included if the blob is incremental copy blob or incremental copy snapshot, if x-ms-copy-status is success.
	// Snapshot time of the last successful incremental copy snapshot for this blob
	CopyDestinationSnapshot string

	// String identifier for the last attempted Copy Blob operation where this blob was the destination blob.
	// This header does not appear if this blob has never been the destination in a Copy Blob operation,
	// or if this blob has been modified after a concluded Copy Blob operation using Set Blob Properties,
	// Put Blob, or Put Block List.
	CopyID string

	// Contains the number of bytes copied and the total bytes in the source in the last attempted
	// Copy Blob operation where this blob was the destination blob.
	// Can show between 0 and Content-Length bytes copied.
	// This header does not appear if this blob has never been the destination in a Copy Blob operation,
	// or if this blob has been modified after a concluded Copy Blob operation using Set Blob Properties,
	// Put Blob, or Put Block List.
	CopyProgress string

	// URL up to 2 KB in length that specifies the source blob used in the last attempted Copy Blob operation
	// where this blob was the destination blob.
	// This header does not appear if this blob has never been the destination in a Copy Blob operation,
	// or if this blob has been modified after a concluded Copy Blob operation using Set Blob Properties,
	// Put Blob, or Put Block List
	CopySource string

	// State of the copy operation identified by x-ms-copy-id, with these values:
	// - success: Copy completed successfully.
	// - pending: Copy is in progress.
	//            Check x-ms-copy-status-description if intermittent, non-fatal errors
	//            impede copy progress but don’t cause failure.
	// - aborted: Copy was ended by Abort Copy Blob.
	// - failed: Copy failed. See x-ms- copy-status-description for failure details.
	// This header does not appear if this blob has never been the destination in a Copy Blob operation,
	// or if this blob has been modified after a completed Copy Blob operation using Set Blob Properties,
	// Put Blob, or Put Block List.
	CopyStatus CopyStatus

	// Describes cause of fatal or non-fatal copy operation failure.
	// This header does not appear if this blob has never been the destination in a Copy Blob operation,
	// or if this blob has been modified after a concluded Copy Blob operation using Set Blob Properties,
	// Put Blob, or Put Block List.
	CopyStatusDescription string

	// The date/time at which the blob was created. The date format follows RFC 1123
	CreationTime string

	// The ETag contains a value that you can use to perform operations conditionally
	ETag string

	// Included if the blob is incremental copy blob.
	IncrementalCopy bool

	// The date/time that the blob was last modified. The date format follows RFC 1123.
	LastModified string

	// When a blob is leased, specifies whether the lease is of infinite or fixed duration
	LeaseDuration LeaseDuration

	// The lease state of the blob
	LeaseState LeaseState

	LeaseStatus LeaseStatus

	// A set of name-value pairs that correspond to the user-defined metadata associated with this blob
	MetaData map[string]string

	// Is the Storage Account encrypted using server-side encryption? This should always return true
	ServerEncrypted bool
}

// GetProperties returns all user-defined metadata, standard HTTP properties, and system properties for the blob
func (client Client) GetProperties(ctx context.Context, accountName, containerName, blobName string, input GetPropertiesInput) (result GetPropertiesResult, err error) {
	if accountName == "" {
		return result, validation.NewError("blobs.Client", "GetProperties", "`accountName` cannot be an empty string.")
	}
	if containerName == "" {
		return result, validation.NewError("blobs.Client", "GetProperties", "`containerName` cannot be an empty string.")
	}
	if strings.ToLower(containerName) != containerName {
		return result, validation.NewError("blobs.Client", "GetProperties", "`containerName` must be a lower-cased string.")
	}
	if blobName == "" {
		return result, validation.NewError("blobs.Client", "GetProperties", "`blobName` cannot be an empty string.")
	}

	req, err := client.GetPropertiesPreparer(ctx, accountName, containerName, blobName, input)
	if err != nil {
		err = autorest.NewErrorWithError(err, "blobs.Client", "GetProperties", nil, "Failure preparing request")
		return
	}

	resp, err := client.GetPropertiesSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "blobs.Client", "GetProperties", resp, "Failure sending request")
		return
	}

	result, err = client.GetPropertiesResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "blobs.Client", "GetProperties", resp, "Failure responding to request")
		return
	}

	return
}

// GetPropertiesPreparer prepares the GetProperties request.
func (client Client) GetPropertiesPreparer(ctx context.Context, accountName, containerName, blobName string, input GetPropertiesInput) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"containerName": autorest.Encode("path", containerName),
		"blobName":      autorest.Encode("path", blobName),
	}

	headers := map[string]interface{}{
		"x-ms-version": APIVersion,
	}

	if input.LeaseID != nil {
		headers["x-ms-lease-id"] = *input.LeaseID
	}

	preparer := autorest.CreatePreparer(
		autorest.AsHead(),
		autorest.WithBaseURL(endpoints.GetBlobEndpoint(client.BaseURI, accountName)),
		autorest.WithPathParameters("/{containerName}/{blobName}", pathParameters),
		autorest.WithHeaders(headers))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// GetPropertiesSender sends the GetProperties request. The method will close the
// http.Response Body if it receives an error.
func (client Client) GetPropertiesSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req,
		azure.DoRetryWithRegistration(client.Client))
}

// GetPropertiesResponder handles the response to the GetProperties request. The method always
// closes the http.Response Body.
func (client Client) GetPropertiesResponder(resp *http.Response) (result GetPropertiesResult, err error) {
	if resp != nil && resp.Header != nil {
		result.AccessTier = AccessTier(resp.Header.Get("x-ms-access-tier"))
		result.AccessTierChangeTime = resp.Header.Get(" x-ms-access-tier-change-time")
		result.ArchiveStatus = ArchiveStatus(resp.Header.Get(" x-ms-archive-status"))
		result.BlobCommittedBlockCount = resp.Header.Get("x-ms-blob-committed-block-count")
		result.BlobSequenceNumber = resp.Header.Get("x-ms-blob-sequence-number")
		result.BlobType = BlobType(resp.Header.Get("x-ms-blob-type"))
		result.CacheControl = resp.Header.Get("Cache-Control")
		result.ContentDisposition = resp.Header.Get("Content-Disposition")
		result.ContentEncoding = resp.Header.Get("Content-Encoding")
		result.ContentLanguage = resp.Header.Get("Content-Language")
		result.ContentMD5 = resp.Header.Get("Content-MD5")
		result.ContentType = resp.Header.Get("Content-Type")
		result.CopyCompletionTime = resp.Header.Get("x-ms-copy-completion-time")
		result.CopyDestinationSnapshot = resp.Header.Get("x-ms-copy-destination-snapshot")
		result.CopyID = resp.Header.Get("x-ms-copy-id")
		result.CopyProgress = resp.Header.Get("x-ms-copy-progress")
		result.CopySource = resp.Header.Get("x-ms-copy-source")
		result.CopyStatus = CopyStatus(resp.Header.Get("x-ms-copy-status"))
		result.CopyStatusDescription = resp.Header.Get("x-ms-copy-status-description")
		result.CreationTime = resp.Header.Get("x-ms-creation-time")
		result.ETag = resp.Header.Get("Etag")
		result.LastModified = resp.Header.Get("Last-Modified")
		result.LeaseDuration = LeaseDuration(resp.Header.Get("x-ms-lease-duration"))
		result.LeaseState = LeaseState(resp.Header.Get("x-ms-lease-state"))
		result.LeaseStatus = LeaseStatus(resp.Header.Get("x-ms-lease-status"))
		result.MetaData = metadata.ParseFromHeaders(resp.Header)

		if v := resp.Header.Get("x-ms-access-tier-inferred"); v != "" {
			b, innerErr := strconv.ParseBool(v)
			if innerErr != nil {
				err = fmt.Errorf("Error parsing %q as a bool: %s", v, innerErr)
				return
			}

			result.AccessTierInferred = b
		}

		if v := resp.Header.Get("Content-Length"); v != "" {
			i, innerErr := strconv.Atoi(v)
			if innerErr != nil {
				err = fmt.Errorf("Error parsing %q as an integer: %s", v, innerErr)
			}

			result.ContentLength = int64(i)
		}

		if v := resp.Header.Get("x-ms-incremental-copy"); v != "" {
			b, innerErr := strconv.ParseBool(v)
			if innerErr != nil {
				err = fmt.Errorf("Error parsing %q as a bool: %s", v, innerErr)
				return
			}

			result.IncrementalCopy = b
		}

		if v := resp.Header.Get("x-ms-server-encrypted"); v != "" {
			b, innerErr := strconv.ParseBool(v)
			if innerErr != nil {
				err = fmt.Errorf("Error parsing %q as a bool: %s", v, innerErr)
				return
			}

			result.IncrementalCopy = b
		}
	}

	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}