Replace gleam_hackney with custom finch adapter
This commit is contained in:
parent
f469796260
commit
bcba4a92b3
7 changed files with 159 additions and 11 deletions
12
mix.exs
12
mix.exs
|
@ -38,7 +38,16 @@ defmodule GeoTherminator.MixProject do
|
|||
def application do
|
||||
[
|
||||
mod: {GeoTherminator.Application, []},
|
||||
extra_applications: [:logger, :runtime_tools, :logger, :ssl, :crypto, :sasl, :tools, :inets]
|
||||
extra_applications: [
|
||||
:logger,
|
||||
:runtime_tools,
|
||||
:logger,
|
||||
:ssl,
|
||||
:crypto,
|
||||
:sasl,
|
||||
:tools,
|
||||
:inets
|
||||
]
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -69,7 +78,6 @@ defmodule GeoTherminator.MixProject do
|
|||
{:cubdb, "~> 2.0"},
|
||||
{:gleam_stdlib, "~> 0.25"},
|
||||
{:gleam_http, "~> 3.1"},
|
||||
{:gleam_hackney, "~> 0.2.1"},
|
||||
{:gleam_erlang, "~> 0.17.1"},
|
||||
{:gleam_json, "~> 0.5.0"}
|
||||
]
|
||||
|
|
2
mix.lock
2
mix.lock
|
@ -18,7 +18,6 @@
|
|||
"floki": {:hex, :floki, "0.34.0", "002d0cc194b48794d74711731db004fafeb328fe676976f160685262d43706a8", [:mix], [], "hexpm", "9c3a9f43f40dde00332a589bd9d389b90c1f518aef500364d00636acc5ebc99c"},
|
||||
"gettext": {:hex, :gettext, "0.21.0", "15bbceb20b317b706a8041061a08e858b5a189654128618b53746bf36c84352b", [:mix], [{:expo, "~> 0.1.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "04a66db4103b6d1d18f92240bb2c73167b517229316b7bef84e4eebbfb2f14f6"},
|
||||
"gleam_erlang": {:hex, :gleam_erlang, "0.17.1", "40fff501e8ca39fa166f4c12ed13bb57e94fc5bb59a93b4446687d82d4a12ff9", [:gleam], [{:gleam_stdlib, "~> 0.22", [hex: :gleam_stdlib, repo: "hexpm", optional: false]}], "hexpm", "baaa84f5bcc4477e809ba3e03bb3009a3894a6544c1511626c44408e39db2ae6"},
|
||||
"gleam_hackney": {:hex, :gleam_hackney, "0.2.1", "ca3c5677b85f31885a4366c73a110803515d6d23a2e233e459dc164260315404", [:gleam], [{:gleam_http, "~> 3.0", [hex: :gleam_http, repo: "hexpm", optional: false]}, {:gleam_stdlib, "~> 0.18", [hex: :gleam_stdlib, repo: "hexpm", optional: false]}, {:hackney, "~> 1.18", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "ccaca00027c827436d8eb945651392b6e5798cfc9e69907a28be61832b0c02a4"},
|
||||
"gleam_http": {:hex, :gleam_http, "3.1.1", "609158240630e21fc70c69b21384e5ebbcd86f71bd378a6f7c2b87f910ab3561", [:gleam], [{:gleam_stdlib, "~> 0.18", [hex: :gleam_stdlib, repo: "hexpm", optional: false]}], "hexpm", "b66b7a1539ccb577119e4dc80dd3484c1a652cb032967954498eedbae3355763"},
|
||||
"gleam_json": {:hex, :gleam_json, "0.5.0", "aff4507ad7700ad794ada6671c6dfd0174696713659bd8782858135b19f41b58", [:gleam], [{:gleam_stdlib, "~> 0.19", [hex: :gleam_stdlib, repo: "hexpm", optional: false]}, {:thoas, "~> 0.2", [hex: :thoas, repo: "hexpm", optional: false]}], "hexpm", "e42443c98aa66e30143c24818f2cea801491c10ce6b1a5eddf3fc4abdc7601cb"},
|
||||
"gleam_stdlib": {:hex, :gleam_stdlib, "0.25.0", "656f39258dcc8772719e463bbe7d1d1c7800238a520b41558fad53ea206ee3ab", [:gleam], [], "hexpm", "ad0f89928e0b919c8f8edf640484633b28dbf88630a9e6ae504617a3e3e5b9a2"},
|
||||
|
@ -53,4 +52,5 @@
|
|||
"telemetry_poller": {:hex, :telemetry_poller, "1.0.0", "db91bb424e07f2bb6e73926fcafbfcbcb295f0193e0a00e825e589a0a47e8453", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b3a24eafd66c3f42da30fc3ca7dda1e9d546c12250a2d60d7b81d264fbec4f6e"},
|
||||
"thoas": {:hex, :thoas, "0.4.0", "86a72ccdc5ec388a13f9f843bcd6c1076640233b95440e47ffb8e3c0dbdb5a17", [:rebar3], [], "hexpm", "442296847aca11db8d25180693d7ca3073d6d7179f66952f07b16415306513b6"},
|
||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
|
||||
"wx": {:hex, :bridge, "1.0.10", "5051dfe881e498a0bc056603df97b734bfe5fdc084f5e56dc42fab8049247144", [:mix], [{:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "b30941e57a194e557a123c5246f123f8b13acdd5c580f75590a52e72bda15632"},
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
import gleam/json
|
||||
import gleam/base
|
||||
import gleam/hackney
|
||||
import gleam/uri
|
||||
import gleam/http
|
||||
import gleam/http/request
|
||||
|
@ -16,6 +15,8 @@ import gleam/list
|
|||
import gleam/result
|
||||
import gleam/int
|
||||
import azure/utils
|
||||
import helpers/config
|
||||
import helpers/finch
|
||||
import helpers/crypto
|
||||
import helpers/uri as uri_helpers
|
||||
import helpers/parsing
|
||||
|
@ -186,7 +187,8 @@ fn confirm(
|
|||
|
||||
try resp =
|
||||
req
|
||||
|> hackney.send()
|
||||
|> finch.build()
|
||||
|> finch.request(config.finch_server())
|
||||
|> b2c_error("Confirm HTTP request failed.")
|
||||
|
||||
try resp = case resp.status {
|
||||
|
@ -286,7 +288,8 @@ fn run_req(
|
|||
) -> Result(response.Response(String), B2CError) {
|
||||
try resp =
|
||||
req
|
||||
|> hackney.send()
|
||||
|> finch.build()
|
||||
|> finch.request(config.finch_server())
|
||||
|> b2c_error("HTTP request failed.")
|
||||
|
||||
case resp.status {
|
||||
|
|
|
@ -3,9 +3,8 @@ import gleam/dynamic
|
|||
import gleam/uri
|
||||
import helpers/application
|
||||
|
||||
fn app_name() -> atom.Atom {
|
||||
assert Ok(name) = atom.from_string("geo_therminator")
|
||||
name
|
||||
pub fn finch_server() -> atom.Atom {
|
||||
atom.create_from_string("Elixir.GeoTherminator.PumpAPI.HTTP")
|
||||
}
|
||||
|
||||
pub fn api_timeout() -> Int {
|
||||
|
@ -27,6 +26,11 @@ pub fn api_installations_url() -> uri.Uri {
|
|||
config_url("api_installations_url")
|
||||
}
|
||||
|
||||
fn app_name() -> atom.Atom {
|
||||
assert Ok(name) = atom.from_string("geo_therminator")
|
||||
name
|
||||
}
|
||||
|
||||
fn config_url(config_key: String) -> uri.Uri {
|
||||
let url =
|
||||
application.fetch_env_angry(app_name(), atom.create_from_string(config_key))
|
||||
|
|
120
src/helpers/finch.gleam
Normal file
120
src/helpers/finch.gleam
Normal file
|
@ -0,0 +1,120 @@
|
|||
import gleam/uri
|
||||
import gleam/erlang/atom.{Atom}
|
||||
import gleam/http
|
||||
import gleam/http/request as gleam_request
|
||||
import gleam/http/response as gleam_response
|
||||
import gleam/dynamic.{Dynamic}
|
||||
import helpers/keyword.{Keyword}
|
||||
import helpers/config
|
||||
|
||||
pub type Method {
|
||||
Head
|
||||
Get
|
||||
Put
|
||||
Post
|
||||
Patch
|
||||
Delete
|
||||
Options
|
||||
}
|
||||
|
||||
pub type Headers =
|
||||
List(#(String, String))
|
||||
|
||||
pub external type Request
|
||||
|
||||
pub external type Response
|
||||
|
||||
pub fn build(req: gleam_request.Request(String)) -> Request {
|
||||
let opts =
|
||||
keyword.init()
|
||||
|> keyword.put_int(atom.create_from_string("timeout"), config.api_timeout())
|
||||
|
||||
let url_str =
|
||||
req
|
||||
|> gleam_request.to_uri()
|
||||
|> uri.to_string()
|
||||
|
||||
build_ext(
|
||||
gleam_method_to_finch_method(req.method),
|
||||
url_str,
|
||||
req.headers,
|
||||
req.body,
|
||||
opts,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn request(
|
||||
req: Request,
|
||||
server: Atom,
|
||||
) -> Result(gleam_response.Response(String), Dynamic) {
|
||||
try resp = do_request(req, server)
|
||||
|
||||
Ok(gleam_response.Response(
|
||||
body: response_body(resp),
|
||||
headers: response_headers(resp),
|
||||
status: response_status(resp),
|
||||
))
|
||||
}
|
||||
|
||||
pub external fn build_ext(
|
||||
method: Method,
|
||||
url: String,
|
||||
headers: Headers,
|
||||
body: String,
|
||||
opts: Keyword,
|
||||
) -> Request =
|
||||
"Elixir.Finch" "build"
|
||||
|
||||
external fn do_request(req: Request, server: Atom) -> Result(Response, Dynamic) =
|
||||
"Elixir.Finch" "request"
|
||||
|
||||
pub fn response_body(resp: Response) -> String {
|
||||
get_response_body(resp, Body)
|
||||
}
|
||||
|
||||
pub fn response_headers(resp: Response) -> Headers {
|
||||
get_response_headers(resp, Headers)
|
||||
}
|
||||
|
||||
pub fn response_status(resp: Response) -> Int {
|
||||
get_response_status(resp, Status)
|
||||
}
|
||||
|
||||
fn gleam_method_to_finch_method(method: http.Method) -> Method {
|
||||
case method {
|
||||
http.Get -> Get
|
||||
http.Head -> Head
|
||||
http.Post -> Post
|
||||
http.Put -> Put
|
||||
http.Patch -> Patch
|
||||
http.Delete -> Delete
|
||||
http.Options -> Options
|
||||
|
||||
// This should never happen
|
||||
_other -> Get
|
||||
}
|
||||
}
|
||||
|
||||
type ResponseBodyKey {
|
||||
Body
|
||||
}
|
||||
|
||||
type ResponseHeadersKey {
|
||||
Headers
|
||||
}
|
||||
|
||||
type ResponseStatusKey {
|
||||
Status
|
||||
}
|
||||
|
||||
external fn get_response_body(resp: Response, key: ResponseBodyKey) -> String =
|
||||
"Elixir.Map" "fetch!"
|
||||
|
||||
external fn get_response_status(resp: Response, key: ResponseStatusKey) -> Int =
|
||||
"Elixir.Map" "fetch!"
|
||||
|
||||
external fn get_response_headers(
|
||||
resp: Response,
|
||||
key: ResponseHeadersKey,
|
||||
) -> Headers =
|
||||
"Elixir.Map" "fetch!"
|
12
src/helpers/keyword.gleam
Normal file
12
src/helpers/keyword.gleam
Normal file
|
@ -0,0 +1,12 @@
|
|||
import gleam/erlang/atom.{Atom}
|
||||
|
||||
pub external type Keyword
|
||||
|
||||
pub external fn init() -> Keyword =
|
||||
"Elixir.Keyword" "new"
|
||||
|
||||
pub external fn put_int(data: Keyword, key: Atom, value: Int) -> Keyword =
|
||||
"Elixir.Keyword" "put"
|
||||
|
||||
pub external fn put_string(data: Keyword, key: Atom, value: String) -> Keyword =
|
||||
"Elixir.Keyword" "put"
|
|
@ -1,6 +1,5 @@
|
|||
import gleam/http/request
|
||||
import gleam/json
|
||||
import gleam/hackney
|
||||
import gleam/result
|
||||
import gleam/dynamic
|
||||
import gleam/list
|
||||
|
@ -12,6 +11,7 @@ import pump_api/http
|
|||
import helpers/config
|
||||
import helpers/date_time
|
||||
import helpers/parsing
|
||||
import helpers/finch
|
||||
import azure/b2c.{B2CError}
|
||||
|
||||
pub type ApiError {
|
||||
|
@ -69,7 +69,8 @@ pub fn installation_info(user: User) -> Result(List(InstallationInfo), ApiError)
|
|||
fn run_req(req: request.Request(String)) {
|
||||
try resp =
|
||||
req
|
||||
|> hackney.send()
|
||||
|> finch.build()
|
||||
|> finch.request(config.finch_server())
|
||||
|> result.replace_error(ApiRequestFailed)
|
||||
|
||||
try body = case resp.status {
|
||||
|
|
Loading…
Reference in a new issue