defmodule Aliyun.Oss.Bucket do
@moduledoc """
Bucket operations - basic operations.
Other operations can be found in:
- `Aliyun.Oss.Bucket.WORM`
- `Aliyun.Oss.Bucket.ACL`
- `Aliyun.Oss.Bucket.Lifecycle`
- `Aliyun.Oss.Bucket.Versioning`
- `Aliyun.Oss.Bucket.Replication`
- `Aliyun.Oss.Bucket.Policy`
- `Aliyun.Oss.Bucket.Inventory`
- `Aliyun.Oss.Bucket.Logging`
- `Aliyun.Oss.Bucket.Website`
- `Aliyun.Oss.Bucket.Referer`
- `Aliyun.Oss.Bucket.Tags`
- `Aliyun.Oss.Bucket.Encryption`
- `Aliyun.Oss.Bucket.RequestPayment`
- `Aliyun.Oss.Bucket.CORS`
"""
alias Aliyun.Oss.Config
alias Aliyun.Oss.Service
alias Aliyun.Oss.Client.{Response, Error}
@type error() ::
%Error{body: String.t(), status_code: integer(), parsed_details: map()} | atom()
@doc """
ListBuckets - lists the information about all buckets.
## Examples
iex> Aliyun.Oss.Bucket.list_buckets(config, %{"max-keys" => 5})
{:ok, %Aliyun.Oss.Client.Response{
data: %{
"Buckets" => %{
"Bucket" => [
%{
"CreationDate" => "2018-10-12T07:57:51.000Z",
"ExtranetEndpoint" => "oss-cn-shenzhen.aliyuncs.com",
"IntranetEndpoint" => "oss-cn-shenzhen-internal.aliyuncs.com",
"Location" => "oss-cn-shenzhen",
"Name" => "XXXXX",
"StorageClass" => "Standard"
},
...
]
},
"IsTruncated" => true,
"Marker" => nil,
"MaxKeys" => 5,
"NextMarker" => "XXXXX",
"Owner" => %{"DislayName" => "11111111", "ID" => "11111111"},
"Prefix" => nil
},
headers: [
{"Date", "Wed, 05 Dec 2018 02:34:57 GMT"},
...
]
}
}
iex> Aliyun.Oss.Bucket.list_buckets(config, %{"max-keys" => 100000})
{:error,
%Aliyun.Oss.Client.Error{
status_code: 400,
parsed_details: %{
"ArgumentName" => "max-keys",
"ArgumentValue" => "100000",
"Code" => "InvalidArgument",
"HostId" => "oss-cn-shenzhen.aliyuncs.com",
"Message" => "Argument max-keys must be an integer between 1 and 1000.",
"RequestId" => "5BFF8912332CCD8D560F65D9"
},
body: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>...</xml>"
}
}
"""
@spec list_buckets(Config.t(), map()) :: {:error, error()} | {:ok, Response.t()}
def list_buckets(%Config{} = config, query_params \\ %{}) do
Service.get(config, nil, nil, query_params: query_params)
end
@doc """
GetBucket (ListObjects) - lists the information about all objects in a bucket.
## Examples
iex> Aliyun.Oss.Bucket.get_bucket(config, "some-bucket", %{"prefix" => "foo/"})
{:ok, %Aliyun.Oss.Client.Response{
data: %{
"ListBucketResult" => %{
"Contents" => [
%{
"ETag" => "\"D410293F000B000D00D\"",
"key" => "foo/bar",
"LastModified" => "2018-09-12T02:59:41.000Z",
"Owner" => %{"DislayName" => "11111111", "ID" => "11111111"},
"Size" => "12345",
"StorageClass" => "IA",
"Type" => "Normal"
},
...
],
"Delimiter" => nil,
"IsTruncated" => true,
"Marker" => nil,
"MaxKeys" => 100,
"Name" => "some-bucket",
"NextMarker" => "XXXXX",
"Prefix" => "foo/"
}
},
headers: [
{"Date", "Wed, 05 Dec 2018 02:34:57 GMT"},
...
]
}
}
iex> Aliyun.Oss.Bucket.get_bucket(config, "unknown-bucket")
{:error,
%Aliyun.Oss.Client.Error{
status_code: 404,
parsed_details: %{
"ListBucketResult" => %{
"BucketName" => "unknown-bucket",
"Code" => "NoSuchBucket",
"HostId" => "unknown-bucket.oss-cn-shenzhen.aliyuncs.com",
"Message" => "The specified bucket does not exist.",
"RequestId" => "5BFF89955E29FF66F10B9763"
}
},
body: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>...</xml>"
}
}
"""
@spec get_bucket(Config.t(), String.t(), map(), map()) ::
{:error, error()} | {:ok, Response.t()}
def get_bucket(%Config{} = config, bucket, query_params \\ %{}, sub_resources \\ %{}) do
Service.get(config, bucket, nil, query_params: query_params, sub_resources: sub_resources)
end
@doc """
GetBucketV2 (ListObjectsV2) - lists the information about all objects in a bucket.
## Examples
iex> Aliyun.Oss.Bucket.list_objects(config, "some-bucket", %{"prefix" => "foo/"})
{:ok, %Aliyun.Oss.Client.Response{
data: %{
"ListBucketResult" => %{
"Contents" => [
%{
"ETag" => "\"D410293F000B000D00D\"",
"key" => "foo/bar",
"LastModified" => "2018-09-12T02:59:41.000Z",
"Owner" => %{"DislayName" => "11111111", "ID" => "11111111"},
"Size" => "12345",
"StorageClass" => "IA",
"Type" => "Normal"
},
...
],
"Delimiter" => nil,
"IsTruncated" => true,
"Marker" => nil,
"KeyCount" => 100,
"MaxKeys" => 100,
"Name" => "some-bucket",
"NextContinuationToken" => "XXXXX",
"Prefix" => "foo/"
}
},
headers: [
{"Date", "Wed, 05 Dec 2018 02:34:57 GMT"},
...
]
}
}
iex> Aliyun.Oss.Bucket.list_objects(config, "unknown-bucket")
{:error,
%Aliyun.Oss.Client.Error{
status_code: 404,
parsed_details: %{
"ListBucketResult" => %{
"BucketName" => "unknown-bucket",
"Code" => "NoSuchBucket",
"HostId" => "unknown-bucket.oss-cn-shenzhen.aliyuncs.com",
"Message" => "The specified bucket does not exist.",
"RequestId" => "5BFF89955E29FF66F10B9763"
}
},
body: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>...</xml>"
}
}
"""
@spec list_objects(Config.t(), String.t(), map(), map()) ::
{:error, error()} | {:ok, Response.t()}
def list_objects(%Config{} = config, bucket, query_params \\ %{}, sub_resources \\ %{}) do
get_bucket(config, bucket, Map.merge(query_params, %{"list-type" => 2}), sub_resources)
end
@doc """
GetBucketInfo - gets the information about a bucket.
## Examples
iex> Aliyun.Oss.Bucket.get_bucket_info(config, "some-bucket")
{:ok, %Aliyun.Oss.Client.Response{
data: %{
"BucketInfo" => %{
"Bucket" => %{
"AccessControlList" => %{"Grant" => "private"},
"Comment" => nil,
"CreationDate" => "2018-08-29T01:52:03.000Z",
"DataRedundancyType" => "LRS",
"ExtranetEndpoint" => "oss-cn-shenzhen.aliyuncs.com",
"IntranetEndpoint" => "oss-cn-shenzhen-internal.aliyuncs.com",
"Location" => "oss-cn-shenzhen",
"Name" => "some-bucket",
"Owner" => %{
"DisplayName" => "11111111",
"ID" => "11111111"
},
"StorageClass" => "IA"
}
}
},
headers: [
{"Date", "Wed, 05 Dec 2018 02:34:57 GMT"}
]
}
"""
@spec get_bucket_info(Config.t(), String.t()) :: {:error, error()} | {:ok, Response.t()}
def get_bucket_info(%Config{} = config, bucket) do
get_bucket(config, bucket, %{}, %{"bucketInfo" => nil})
end
@doc """
GetBucketLocation - views the location information of a bucket.
## Examples
iex> Aliyun.Oss.Bucket.get_bucket_location(config, "some-bucket")
{:ok, %Aliyun.Oss.Client.Response{
data: %{"LocationConstraint" => "oss-cn-shenzhen"},
headers: [
{"Date", "Wed, 05 Dec 2018 02:34:57 GMT"}
]
}
}
"""
@spec get_bucket_location(Config.t(), String.t()) :: {:error, error()} | {:ok, Response.t()}
def get_bucket_location(%Config{} = config, bucket) do
get_bucket(config, bucket, %{}, %{"location" => nil})
end
@doc """
PutBucket - creates a bucket.
## Examples
iex> Aliyun.Oss.Bucket.put_bucket(config, "new-bucket", %{"x-oss-acl" => "private"})
{:ok,
%Aliyun.Oss.Client.Response{
data: "",
headers: [
{"Server", "AliyunOSS"},
{"Date", "Fri, 11 Jan 2019 04:35:39 GMT"},
{"Content-Length", "0"},
{"Connection", "keep-alive"},
{"x-oss-request-id", "5C381D000000000000000000"},
{"Location", "/new-bucket"},
{"x-oss-server-time", "438"}
]
}}
iex> Aliyun.Oss.Bucket.put_bucket(config, "new-bucket", %{"x-oss-acl" => "invalid-permission"}) # get error
{:error,
%Aliyun.Oss.Client.Error{
parsed_details: %{
"ArgumentName" => "x-oss-acl",
"ArgumentValue" => "invalid-permission",
"Code" => "InvalidArgument",
"HostId" => "new-bucket.oss-cn-shenzhen.aliyuncs.com",
"Message" => "no such bucket access control exists",
"RequestId" => "5C3000000000000000000000"
},
body: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>...</xml>",
status_code: 400
}}
"""
@body """
<?xml version="1.0" encoding="UTF-8"?>
<CreateBucketConfiguration>
<StorageClass>Standard</StorageClass>
</CreateBucketConfiguration>
"""
@spec put_bucket(Config.t(), String.t(), map(), map(), String.t()) ::
{:error, error()} | {:ok, Aliyun.Oss.Client.Response.t()}
def put_bucket(
%Config{} = config,
bucket,
headers = %{} \\ %{},
sub_resources = %{} \\ %{},
body \\ @body
)
when is_binary(body) do
Service.put(config, bucket, nil, body, headers: headers, sub_resources: sub_resources)
end
@doc """
DeleteBucket - deletes a bucket.
## Examples
iex> Aliyun.Oss.Bucket.delete_bucket(config, "some-bucket")
{:ok,
%Aliyun.Oss.Client.Response{
data: "",
headers: [
{"Server", "AliyunOSS"},
{"Date", "Fri, 11 Jan 2019 05:26:36 GMT"},
{"Content-Length", "0"},
{"Connection", "keep-alive"},
{"x-oss-request-id", "5C38290C41F2DE32412A3A88"},
{"x-oss-server-time", "230"}
]
}}
iex> Aliyun.Oss.Bucket.delete_bucket(config, "unknown-bucket")
{:error,
%Aliyun.Oss.Client.Error{
body: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<Error>\n\
<Code>NoSuchBucket</Code>\n\
<Message>The specified bucket does not exist.</Message>\n\
<RequestId>5C3829B29BF380354CF9C2E8</RequestId>\n\
<HostId>unknown-bucket.oss-cn-shenzhen.aliyuncs.com</HostId>\n\
<BucketName>unknown-bucket</BucketName>\n\
</Error>",
parsed_details: %{
"BucketName" => "unknown-bucket",
"Code" => "NoSuchBucket",
"HostId" => "unknown-bucket.oss-cn-shenzhen.aliyuncs.com",
"Message" => "The specified bucket does not exist.",
"RequestId" => "5C3000000000000000000000"
},
status_code: 404
}}
"""
@spec delete_bucket(Config.t(), String.t(), map()) ::
{:error, error()} | {:ok, Aliyun.Oss.Client.Response.t()}
def delete_bucket(%Config{} = config, bucket, sub_resources \\ %{}) do
Service.delete(config, bucket, nil, sub_resources: sub_resources)
end
end