Packages
ndc_ex_sdk
0.2.17
0.2.30
0.2.29
0.2.27
0.2.26
0.2.25
0.2.24
0.2.23
0.2.22
0.2.21
0.2.20
0.2.19
0.2.18
0.2.17
0.2.16
0.2.15
0.2.14
0.2.13
0.2.12
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
0.0.10
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1
This is an Elixir package that wrapps any NDC-compliant API. It's host-agnostic and quite flexible-through-configuration so that it can reach NDC hosts with a certain flexibility
Current section
Files
Jump to
Current section
Files
lib/ndc_ex.ex
defmodule NDCEx do
require HTTPoison
require NDCLogger
use Timex
def request(method, data, config) do
request_start_time = Time.now
NDCEx.Message.Base.build_document(method, data, config)
|> rest_call_with_message(method, data, config, request_start_time)
end
def rest_call_with_message({:ok, request_xml}, method, data, config, request_start_time) do
url = NDCEx.Message.Base.build_url(config[:server][:url], method)
headers = get_headers(config[:rest][:headers], method)
#processing_end = Time.now
#TODO Handle different exceptions during request and return different errors
# try do
case HTTPoison.post(url, request_xml, headers, is_ssl(config[:ssl], config[:label])) do
{:ok, %HTTPoison.Response{body: response_xml, headers: headers, status_code: 200 }} ->
decode_response(response_xml, headers)
|> NDCNormalize.remove_soap_header(config[:soap][:soap_header])
|> NDCNormalize.remove_soap_tags(config[:soap][:response_namespace_tags])
|> NDCNormalize.remove_namespace(config[:soap][:response_namespace])
|> NDCNormalize.remove_message_wrapper(config[:message])
|> NDCNormalize.check_ndc_errors() ## This function returns a tuple including the xml and the atom :error or :ok depending if there are any error on the response or not.
|> process_response(method, request_xml, data, config, request_start_time)
{:ok, %HTTPoison.Response{body: response_xml, headers: _headers, status_code: _status_code }} ->
process_response({:error, NDCNormalize.remove_soap_tags(response_xml, config[:soap][:response_namespace])}, method, request_xml, data, config, request_start_time)
{:error, %HTTPoison.Error{id: id, reason: reason}}->
IO.inspect reason
process_response({:error, "Error. Reason of error"}, method, request_xml, data, config, request_start_time)
#{:ok, %HTTPoison.Response{status_code: 404}} ->
#{:error, error_message("NDC host/URL invalid or missing")}
{:error, reason} ->
IO.inspect reason
{:error, reason}
reason ->
IO.inspect reason
{:error, error_message("Unknown HTTP response error")}
end
# catch _ , _ ->
# {:error, error_message("Exception while HTTP request")}
# end
end
defp build_url(url, method), do: String.replace(url, "{{NDC-method}}", Atom.to_string(method))
defp error_message(message), do: "<Error><Message>#{message}</Message></Error>"
defp remove_tag(doc, tag), do: String.replace(doc, tag, "")
def get_mix_config(key) when is_atom(key), do: Application.get_env(:ndc_ex_sdk, key)
defp get_headers(headers, method) do
Enum.map(headers, fn ({key, value}) ->
{key, String.replace(value, "{{NDC-method}}", Atom.to_string(method))}
end)
end
defp process_response({status, response}, method, request, data, config, request_start_time) do
response_time = Time.diff(Time.now, request_start_time, :milliseconds)
request_xml = request
response_xml = "<!-- AG-Info: ProviderName: #{config[:label]} | NDCMethod: #{method} | ResponseTime: #{response_time} | ProcessingTime: - -->\n\n\n#{response}"
NDCLogger.event(config[:label], method, data, request_xml, response_xml)
{status, response_xml}
end
defp is_ssl(config, _) when config == nil, do: [timeout: 60000, recv_timeout: 60000]
defp is_ssl(ssl_config, provider) when ssl_config != nil do
dir = "ndc_providers/#{String.downcase(provider)}/"
path = if File.exists?(Path.expand(File.cwd! <> "../../../config/#{dir}/#{ssl_config[:certfile]}")) do
Path.expand(File.cwd! <> "../../../config/#{dir}")
else
"test/#{dir}"
end
[
hackney: [ # :hackney options
ssl_options: [ # :ssl options
cacertfile: path <> "/" <> ssl_config[:cacertfile], # CA certificate used to validate server cert; path(), "string" is ok
certfile: path <> "/" <> ssl_config[:certfile], # client certificate, signed by CA; path(), "string" is ok
keyfile: path <> "/" <> ssl_config[:keyfile], # private key for client.crt; path(). "string" is ok
password: ssl_config[:password] # password for keyfile; string(), "string" not ok, use 'char list'
]
],
timeout: 60000, recv_timeout: 60000
]
end
defp decode_response(body, headers) do
gzipped = Enum.any?(headers, fn (kv) ->
case kv do
{"Content-Encoding", "gzip"} -> true
_ -> false
end
end)
# body is an Elixir string
if gzipped do
:zlib.gunzip(body)
else
body
end
end
end