Skip to content

Commit 2946f14

Browse files
authored
Merge pull request #90 from ChevronETC/tiers
add access tier methods
2 parents 592c1dc + 539dc7c commit 2946f14

File tree

3 files changed

+183
-5
lines changed

3 files changed

+183
-5
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "AzStorage"
22
uuid = "c6697862-1611-5eae-9ef8-48803c85c8d6"
3-
version = "2.7.3"
3+
version = "2.8.0"
44

55
[deps]
66
AbstractStorage = "14dbef02-f468-5f15-853e-5ec8dee7b899"

src/AzStorage.jl

Lines changed: 120 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -534,17 +534,43 @@ Serialize and write data to `io::AzObject`. See serialize(conainer, blobname, d
534534
Serialization.serialize(o::AzObject, data) = serialize(o.container, o.name, data)
535535

536536
"""
537-
touch(container, "blobname")
537+
touch(c, b)
538538
539-
Create a zero-byte object with name `blobname` in `container::AzContainer`.
539+
Update the metadata of a blob `b::AbstractString` in container `c::AzContainer`, changing
540+
the datset's 'LAST MODIFIED' date. If the blob does not exist, then a zero-byte blob is
541+
created.
540542
541543
# Example
542544
```
543545
container = AzContainer("mycontainer";storageaccount="mystorageaccount")
544546
touch(container, "foo")
545547
```
546548
"""
547-
Base.touch(c::AzContainer, o::AbstractString) = write(c, o, "\0")
549+
function Base.touch(c::AzContainer, o::AbstractString)
550+
if !isfile(c, o)
551+
write(c, o, "\0")
552+
else
553+
@retry c.nretry HTTP.request(
554+
"PUT",
555+
"https://$(c.storageaccount).blob.core.windows.net/$(c.containername)/$(addprefix(c,o))?comp=metadata",
556+
[
557+
"Authorization" => "Bearer $(token(c.session))",
558+
"x-ms-version" => API_VERSION,
559+
"x-ms-meta-touched" => string(Dates.now(UTC))
560+
];
561+
retry = false,
562+
verbose = c.verbose,
563+
connect_timeout = c.connect_timeout,
564+
readtimeout = c.read_timeout)
565+
end
566+
end
567+
568+
"""
569+
touch(o)
570+
571+
Update the metadata of a blob `o::AzObject`, changing the dataset's 'LAST MODIFIED' date.
572+
"""
573+
Base.touch(o::AzObject) = touch(o.container, o.name)
548574

549575
"""
550576
touch(io::AzObject)
@@ -1416,6 +1442,96 @@ Note that the information stored is global, and not specfic to any one given IO
14161442
"""
14171443
getperf_counters() = @ccall libAzStorage.getperf_counters()::PerfCounters
14181444

1419-
export AzContainer, containers, readdlm, status, writedlm
1445+
"""
1446+
tier!(c, b[; tier="Hot"])
1447+
1448+
Change the storage tier of a blob where `b::AbstractString` is the blob within a
1449+
container `c::AzContainer`, and `tier` is the target access tier which can be one
1450+
of `"Hot"`, `"Cool"`, `"Cold"` and `"Archive"`.
1451+
1452+
Notes:
1453+
1454+
* `tier!` throws an HTTP exception as appropriate. For example an HTTP exception
1455+
with a 409 error code is thrown when a blob has a pending tier change operation.
1456+
"""
1457+
function tier!(c::AzContainer, o::AbstractString; tier="Hot")
1458+
tier ("Hot", "Cool", "Cold", "Archive") || error("'tier' must be one of 'Hot','Cool','Cold','Archive'")
1459+
1460+
@retry c.nretry HTTP.request(
1461+
"PUT",
1462+
"https://$(c.storageaccount).blob.core.windows.net/$(c.containername)/$(addprefix(c,o))?comp=tier",
1463+
[
1464+
"Authorization" => "Bearer $(token(c.session))",
1465+
"x-ms-access-tier" => tier,
1466+
"x-ms-version" => API_VERSION
1467+
];
1468+
retry = false,
1469+
verbose = c.verbose,
1470+
connect_timeout = c.connect_timeout,
1471+
readtimeout = c.read_timeout)
1472+
1473+
# if we don't touch the blob, then existing lifecycle rules in the container might immediately change its tier back to what it was
1474+
touch(c, o)
1475+
1476+
nothing
1477+
end
1478+
1479+
"""
1480+
tier!(o[; tier="Hot"])
1481+
1482+
Change the storage tier for a blob `o::AzObject`, and `tier` is the target
1483+
access tier which can be one of `"Hot"`, `"Cool"` and `"Archive"`.
1484+
1485+
Notes:
1486+
1487+
* `tier!` throws an HTTP exception as appropriate. For example an HTTP exception
1488+
with a 409 error code is thrown when a blob has a pending tier change operation.
1489+
"""
1490+
tier!(o::AzObject; tier="Hot") = tier!(o.container, o.name; tier)
1491+
1492+
"""
1493+
tier!(c[; tier="Hot", ntasks=100])
1494+
1495+
Change the storage tier for all blobs within a container `c::AzContainer`. The
1496+
request for each blob in the container will be done asynchronously in batches
1497+
with `ntasks` tasks within each batch.
1498+
1499+
Notes:
1500+
1501+
* `tier!` throws an HTTP exception as appropriate. For example an HTTP exception
1502+
with a 409 error code is thrown when a blob has a pending tier change operation.
1503+
"""
1504+
tier!(c::AzContainer; tier="Hot", ntasks=100) = asyncmap(b->tier!(c, b; tier), readdir(c); ntasks)
1505+
1506+
"""
1507+
tier(c, o)
1508+
1509+
Returns the access tier for a blob `o::AbstractArray` in container `c::AzContainer`.
1510+
"""
1511+
function tier(c::AzContainer, o::AbstractString)
1512+
r = HTTP.request(
1513+
"HEAD",
1514+
"https://$(c.storageaccount).blob.core.windows.net/$(c.containername)/$(addprefix(c,o))",
1515+
[
1516+
"Authorization" => "Bearer $(token(c.session))",
1517+
"x-ms-access-tier" => tier,
1518+
"x-ms-version" => API_VERSION
1519+
];
1520+
retry = false,
1521+
verbose = c.verbose,
1522+
connect_timeout = c.connect_timeout,
1523+
readtimeout = c.read_timeout)
1524+
1525+
HTTP.header(r.headers, "x-ms-access-tier")
1526+
end
1527+
1528+
"""
1529+
tier(o)
1530+
1531+
Returns the access tier for a blob `o::AzObject`.
1532+
"""
1533+
tier(o::AzObject) = tier(o.container, o.name)
1534+
1535+
export AzContainer, containers, readdlm, status, tier, tier!, writedlm
14201536

14211537
end

test/runtests.jl

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,34 @@ end
302302
rm(c)
303303
end
304304

305+
@testset "Containers and Objects, touch" begin
306+
r = uuid4()
307+
c = AzContainer("foo-$r"; storageaccount, session)
308+
mkpath(c)
309+
write(c, "test.txt", "Hello")
310+
311+
r1 = HTTP.request("HEAD", "https://$(c.storageaccount).blob.core.windows.net/$(c.containername)/test.txt", ["Authorization" => "Bearer $(token(c.session))", "x-ms-version" => AzStorage.API_VERSION])
312+
t1 = HTTP.header(r1, "Last-Modified")
313+
314+
sleep(5)
315+
316+
touch(c, "test.txt")
317+
r2 = HTTP.request("HEAD", "https://$(c.storageaccount).blob.core.windows.net/$(c.containername)/test.txt", ["Authorization" => "Bearer $(token(c.session))", "x-ms-version" => AzStorage.API_VERSION])
318+
t2 = HTTP.header(r2, "Last-Modified")
319+
320+
@test t1 != t2
321+
322+
sleep(5)
323+
324+
touch(joinpath(c, "test.txt"))
325+
r3 = HTTP.request("HEAD", "https://$(c.storageaccount).blob.core.windows.net/$(c.containername)/test.txt", ["Authorization" => "Bearer $(token(c.session))", "x-ms-version" => AzStorage.API_VERSION])
326+
t3 = HTTP.header(r3, "Last-Modified")
327+
328+
@test t3 != t2
329+
330+
rm(c)
331+
end
332+
305333
@testset "isdir, edge case" begin
306334
c = AzContainer(""; storageaccount="", session=session)
307335
@test isdir(c) == false
@@ -693,6 +721,40 @@ end
693721
@test x y
694722
end
695723

724+
@testset "get access tier, blob" begin
725+
r = uuid4()
726+
c = AzContainer("foo-$r"; storageaccount, session)
727+
mkpath(c)
728+
write(c, "test.txt", "Hello")
729+
@test tier(c, "test.txt") == "Hot"
730+
@test tier(joinpath(c, "test.txt")) == "Hot"
731+
rm(c)
732+
end
733+
734+
@testset "set access tier, blob" begin
735+
r = uuid4()
736+
c = AzContainer("foo-$r"; storageaccount, session)
737+
mkpath(c)
738+
write(c, "test.txt", "Hello")
739+
tier!(c, "test.txt"; tier="Cold")
740+
@test tier(c, "test.txt") == "Cold"
741+
tier!(joinpath(c, "test.txt"); tier="Hot")
742+
@test tier(c, "test.txt") == "Hot"
743+
rm(c)
744+
end
745+
746+
@testset "set access tier, container" begin
747+
r = uuid4()
748+
c = AzContainer("foo-$r"; storageaccount, session)
749+
mkpath(c)
750+
write(c, "test1.txt", "Hello")
751+
write(c, "test2.txt", "Goodbye")
752+
tier!(c; tier="Cold")
753+
@test tier(c, "test1.txt") == "Cold"
754+
@test tier(c, "test2.txt") == "Cold"
755+
rm(c)
756+
end
757+
696758
# TODO: CI is showing a seg-fault on Apple, but I do not have an Apple machine to help debug.
697759
if !Sys.iswindows() && !Sys.isapple()
698760
@testset "C token refresh, write" begin

0 commit comments

Comments
 (0)