Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add put_binary_blob, add timeout and recv_timeout options to put_binary_blob, fix warnings, update nimble_options #27

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ erl_crash.dump
# Ignore package tarball (built via "mix hex.build").
az-*.tar

.DS_Store
2 changes: 1 addition & 1 deletion config/test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ config :ex_azure_storage,
# config :ex_azure_storage, http_adapter: HttpClientMock

# Print only warnings and errors during test
config :logger, level: :warn
config :logger, level: :warning
Binary file added fixtures/2WE4HZPD57KVPL4RQKCB4PUG42SQ2RMJ.pdf
Binary file not shown.
Binary file added fixtures/2ZJG56HD3YEZGEQZL4RFOYNIMTZISHDX.pdf
Binary file not shown.
Binary file added fixtures/MYKPH7XVYJANM6NEUFMBWLHISDBHMI2C.pdf
Binary file not shown.
61 changes: 44 additions & 17 deletions lib/azure_storage/azure_blob.ex
Original file line number Diff line number Diff line change
Expand Up @@ -83,24 +83,32 @@ defmodule AzureStorage.Blob do
| {:error, String.t()}
def list_blobs(%Context{service: "blob"} = context, container, options \\ []) do
{:ok, opts} = NimbleOptions.validate(options, Schema.list_blobs_options())
max_results = opts[:max_results]

max_results =
case opts[:maxresults] do
nil -> ""
_ -> "&maxresults=#{opts[:maxresults]}"
end

prefix =
case String.length(opts[:prefix]) do
0 -> []
_ -> ["&prefix=", opts[:prefix]]
case opts[:prefix] do
nil -> ""
_ -> "&prefix=#{opts[:prefix]}"
end

delimiter =
case opts[:delimiter] do
nil -> ""
_ -> "&delimiter=#{opts[:delimiter]}"
end

query =
([
container,
"?restype=container",
container,
"&comp=list",
"&maxresults=",
max_results
] ++ prefix)
|> IO.iodata_to_binary()
marker =
case opts[:marker] do
nil -> ""
_ -> "&marker=#{opts[:marker]}"
end

query = "#{container}?restype=container&comp=list#{max_results}#{prefix}#{delimiter}#{marker}"

context
|> build(method: :get, path: query)
Expand Down Expand Up @@ -157,8 +165,8 @@ defmodule AzureStorage.Blob do
```
{:ok, context} = AzureStorage.create_blob_service("account_name", "account_key")
context |> put_blob("blobs",
"cache-key-1.json",
"{\\"data\\": []}",
"cache-key-1.json",
"{\\"data\\": []}",
content_type: "application/json;charset=\\"utf-8\\""
)
```
Expand All @@ -185,6 +193,25 @@ defmodule AzureStorage.Blob do
|> parse_body_response()
end

def put_binary_blob(
%Context{service: "blob"} = context,
container,
filename,
bytes,
options \\ []
) do
{:ok, opts} = NimbleOptions.validate(options, Schema.put_blob_options())
query = "#{container}/#{filename}"
headers = %{
"x-ms-blob-type" => "BlockBlob",
:"Content-Type" => "application/octet-stream"
}
context
|> build(method: :put, path: query, body: bytes, headers: headers)
|> request(recv_timeout: opts[:recv_timeout], timeout: opts[:timeout])
|> parse_body_response()
end

@doc """
Acquires a new lease. If container and blob are specified, acquires a blob lease. Otherwise, if only container is specified and blob is null, acquires a container lease.

Expand Down Expand Up @@ -309,7 +336,7 @@ defmodule AzureStorage.Blob do

path =
case String.starts_with?(opts[:path], "/") do
true -> String.slice(opts[:path], 1..-1)
true -> String.slice(opts[:path], 1..-1//-1)
false -> opts[:path]
end

Expand Down
10 changes: 10 additions & 0 deletions lib/azure_storage/blob/schema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ defmodule AzureStorage.Blob.Schema do
type: :string,
doc: "Content-Type",
default: "text/plain;charset=\"utf-8\""
],
recv_timeout: [
type: :pos_integer,
default: 30_000,
required: false
],
timeout: [
type: :pos_integer,
default: 30_000,
required: false
]
]

Expand Down
1 change: 0 additions & 1 deletion lib/azure_storage/http_client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ defmodule Http.Client do

def request(method, url, body, headers, options) do
http_options = get_http_request_options(options)

http_adapter().request(method, url, body, headers, http_options)
|> process_response
end
Expand Down
24 changes: 17 additions & 7 deletions lib/azure_storage/request/context.ex
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,24 @@ defmodule AzureStorage.Request.Context do
headers_cfg = options[:headers]

# TODO: improve headers
content_length =
case String.length(body) do
0 ->
%{}
content_length = case headers_cfg[:"Content-Type"] do
"application/octet-stream" ->
case Kernel.byte_size(body) do
0 ->
%{}

value ->
%{:"content-length" => "#{value}"}
end
_ ->
case String.length(body) do
0 ->
%{}

value ->
%{:"content-length" => "#{value}"}
end
value ->
%{:"content-length" => "#{value}"}
end
end

headers =
default_headers
Expand Down
8 changes: 8 additions & 0 deletions lib/azure_storage/request/schema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ defmodule AzureStorage.Request.Schema do
response_body: [
type: {:in, [:full, :json]},
default: :json
],
recv_timeout: [
type: :pos_integer,
default: 30_000
],
timeout: [
type: :pos_integer,
default: 30_000
]
]
end
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ defmodule AzureStorage.MixProject do
{:elixir_xml_to_map, "~> 2.0"},
{:jason, "~> 1.2"},
{:httpoison, "~> 1.8.0"},
{:nimble_options, "~> 0.3.5"},
{:nimble_options, "~> 1.1.1"},
{:uuid, "~> 1.1", only: :test, runtime: false},
{:ex_doc, "~> 0.23", only: :dev, runtime: false},
{:credo, "~> 1.4", only: [:dev, :test], runtime: false}
Expand Down
4 changes: 2 additions & 2 deletions mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
"nimble_options": {:hex, :nimble_options, "0.3.5", "a4f6820cdcb4ee444afd78635f323e58e8a5ddf2fbbe9b9d283a99f972034bae", [:mix], [], "hexpm", "f5507cc90033a8d12769522009c80aa9164af6bab245dbd4ad421d008455f1e1"},
"nimble_options": {:hex, :nimble_options, "1.1.1", "e3a492d54d85fc3fd7c5baf411d9d2852922f66e69476317787a7b2bb000a61b", [:mix], [], "hexpm", "821b2470ca9442c4b6984882fe9bb0389371b8ddec4d45a9504f00a66f650b44"},
"nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"},
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
"uuid": {:hex, :uuid, "1.1.8", "e22fc04499de0de3ed1116b770c7737779f226ceefa0badb3592e64d5cfb4eb9", [:mix], [], "hexpm", "c790593b4c3b601f5dc2378baae7efaf5b3d73c4c6456ba85759905be792f2ac"},
}
31 changes: 31 additions & 0 deletions test/list_blobs_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
defmodule TestExAzureStorage do
use ExUnit.Case
alias AzureStorage.Blob

@account_name Application.compile_env(:ex_azure_storage, :account_name, "")
@account_key Application.compile_env(:ex_azure_storage, :account_key, "")
@container "tmp"

setup_all do
{:ok, context} = AzureStorage.create_blob_service(@account_name, @account_key)
%{context: context}
end

test "can paginate", %{context: context} do
first_page = Blob.list_blobs(context, @container, maxresults: 1)
{:ok, %{items: %{
"Name" => name,
"Properties" => properties
}, marker: marker}} = first_page
assert is_binary(name)
assert is_map(properties)

second_page = Blob.list_blobs(context, @container, marker: marker, maxresults: 1)
{:ok, %{items: %{
"Name" => name,
"Properties" => properties
}}} = second_page
assert is_binary(name)
assert is_map(properties)
end
end
41 changes: 41 additions & 0 deletions test/put_blob_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
defmodule TestExAzureStorage do
use ExUnit.Case
alias AzureStorage.Blob

@account_name Application.compile_env(:ex_azure_storage, :account_name, "")
@account_key Application.compile_env(:ex_azure_storage, :account_key, "")
@container "tmp"

setup_all do
{:ok, context} = AzureStorage.create_blob_service(@account_name, @account_key)
%{context: context}
end

test "can put binary blob 1", %{context: context} do
file_path = "fixtures/MYKPH7XVYJANM6NEUFMBWLHISDBHMI2C.pdf"
put_binary_blob(file_path, context)
end

test "can put binary blob 2", %{context: context} do
file_path = "fixtures/2ZJG56HD3YEZGEQZL4RFOYNIMTZISHDX.pdf"
put_binary_blob(file_path, context)
end

test "can put binary blob 3", %{context: context} do
file_path = "fixtures/2WE4HZPD57KVPL4RQKCB4PUG42SQ2RMJ.pdf"
put_binary_blob(file_path, context)
end

test "can put with timeout", %{context: context} do
file_path = "fixtures/2WE4HZPD57KVPL4RQKCB4PUG42SQ2RMJ.pdf"
put_binary_blob(file_path, context, timeout: 60000, recv_timeout: 60000)
end

defp put_binary_blob(file_path, context, options \\ []) do
file = File.open!(file_path)
content = IO.binread(file, :eof)
[file_name | _] = file_path |> String.split("/") |> Enum.reverse()
remote_file_path = "test/#{file_name}"
{:ok, _} = Blob.put_binary_blob(context, @container, remote_file_path, content, options)
end
end