-
Notifications
You must be signed in to change notification settings - Fork 2
/
client.ex
142 lines (112 loc) · 4.82 KB
/
client.ex
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
defmodule ExOvh.Client do
@moduledoc ~s"""
A behaviour for setting up an OVH client.
## Example setting up the `ExOvh` Client
Defining a client:
defmodule ExOvh do
@moduledoc :false
use ExOvh.Client, otp_app: :ex_ovh, client: __MODULE__
end
Configuring a client:
config :ex_ovh,
ovh: [
application_key: System.get_env("EX_OVH_APPLICATION_KEY"),
application_secret: System.get_env("EX_OVH_APPLICATION_SECRET"),
consumer_key: System.get_env("EX_OVH_CONSUMER_KEY"),
endpoint: "ovh-eu",
api_version: "1.0"
],
# default hackney options to each request (optional)
hackney: [
connect_timeout: 20000,
recv_timeout: 100000
]
## Example using the `ExOvh` client
%HTTPipe.Request{ method: :get, url: "/me", params: %{}} |> ExOvh.request!()
%HTTPipe.Request{ method: :get, url: "/cloud/project", params: %{}} |> ExOvh.request!()
## Example (2): Setting up an additional `MyApp.MyClient` client.
Defining the `MyApp.MyClient`
defmodule MyApp.MyClient do
@moduledoc :false
use ExOvh.Client, otp_app: :my_app
end
Configuring the `MyApp.MyClient`
config :my_app, MyApp.MyClient,
ovh: [
application_key: System.get_env("MY_APP_MY_CLIENT_APPLICATION_KEY"),
application_secret: System.get_env("MY_APP_MY_CLIENT_APPLICATION_SECRET"),
consumer_key: System.get_env("MY_APP_MY_CLIENT_CONSUMER_KEY")
],
# default hackney options to each request (optional)
hackney: [
connect_timeout: 20000,
recv_timeout: 100000
]
## Example using the `MyApp.MyClient` client
%HTTPipe.Request{ method: :get, url: "/me", params: %{}} |> MyApp.MyClient.request!()
%ExOvh.Query{ method: :get, url: "/cloud/project", params: %{}} |> MyApp.MyClient.request!()
"""
defmacro __using__(opts) do
quote bind_quoted: [opts: opts] do
@moduledoc ~s"""
A default client for sending requests to the [OVH API](https://api.ovh.com/console/).
`ExOvh` is the default client. Additional clients such as `MyApp.MyClient.Ovh` can be created - see `PAGES`.
"""
alias ExOvh.{Defaults, ResponseError}
@behaviour ExOvh.Client
# public callback functions
@doc "Starts the client supervision tree"
def start_link(sup_opts \\ []) do
client = unquote(opts) |> Keyword.fetch!(:client)
otp_app = unquote(opts) |> Keyword.fetch!(:otp_app)
ExOvh.Supervisor.start_link(client, [otp_app: otp_app])
end
@doc "Gets all the application configuration settings"
@spec config() :: Keyword.t
def config() do
client = unquote(opts) |> Keyword.fetch!(:client)
unless agent_exists?(client), do: __MODULE__.start_link([])
ExOvh.Config.config(client)
end
@doc "Gets all the `:ovh` configuration settings"
@spec ovh_config() :: Keyword.t
def ovh_config(), do: config() |> Keyword.fetch!(:ovh)
@doc "Gets all the default `:hackney` options to be sent with each request"
@spec hackney_opts() :: Keyword.t
def hackney_opts(), do: config() |> Keyword.fetch!(:hackney)
@doc "Prepares a request prior to sending by applying standard transformations to the request"
@spec prepare_request(HTTPipe.Conn.t | HTTPipe.Request.t) :: HTTPipe.Conn.t
def prepare_request(conn) do
client = unquote(opts) |> Keyword.fetch!(:client)
ExOvh.Request.apply_transformations(conn, client)
end
@doc "Sends a request to the ovh api using [httpipe](https://hex.pm/packages/httpipe)."
@spec request(HTTPipe.Conn.t) :: {:ok, HTTPipe.Conn.t} | {:error, HTTPipe.Conn.t}
def request(conn) do
client = unquote(opts) |> Keyword.fetch!(:client)
ExOvh.Request.request(conn, client)
end
@doc "Sends a request to the ovh api using [httpipe](https://hex.pm/packages/httpipe)."
@spec request!(HTTPipe.Conn.t) :: HTTPipe.Conn.t | no_return
def request!(conn) do
case request(conn) do
{:ok, conn} -> conn
{:error, conn} -> raise(ResponseError, conn: conn)
end
end
defp agent_name(client) do
Module.concat(ExOvh.Config, client)
end
defp agent_exists?(client) do
agent_name(client) in Process.registered()
end
end
end
@callback start_link(sup_opts :: list) :: {:ok, pid} | {:error, atom}
@callback config() :: Keyword.t
@callback ovh_config() :: Keyword.t
@callback hackney_opts() :: Keyword.t
@callback prepare_request(HTTPipe.Conn.t | HTTPipe.Request.t) :: HTTPipe.Conn.t
@callback request(conn :: HTTPipe.Conn.t) :: {:ok, HTTPipe.Conn.t} | {:error, HTTPipe.Conn.t}
@callback request!(conn :: HTTPipe.Conn.t) :: HTTPipe.Conn.t | no_return
end