Packages
ndc_ex_sdk
0.2.21
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
NDCProviderConfig.check_mandatory_config(config)
NDCEx.Message.Base.build_document(method, data, config)
|> rest_call_with_message(method, data, config)
end
def rest_call_with_message({:ok, request_xml}, method, data, config) do
url = NDCEx.Message.Base.build_url(config[:server][:url], method)
headers = config[:rest][:generic_headers]
|> get_method_headers(config[:rest][method])
|> get_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_declaration
|> 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)
{: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)
{:error, %HTTPoison.Error{id: id, reason: reason}}->
process_response({:error, "<#{Atom.to_string(method)}RS><Errors><Error>#{reason}</Error></Errors></#{Atom.to_string(method)}RS>"}, method, request_xml, data, config)
end
# catch _ , _ ->
# {:error, error_message("Exception while HTTP request")}
# end
end
defp get_mix_config(key) when is_atom(key), do: Application.get_env(:ndc_ex_sdk, key)
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, "")
defp get_method_headers(generic_h, method_h) when is_nil(method_h), do: generic_h
defp get_method_headers(generic_h, method_h), do: generic_h ++ method_h
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) do
NDCLogger.event(config[:label], method, data, request, response)
{status, response}
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.upcase(provider)}/keys/"
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)
if gzipped do
:zlib.gunzip(body)
else
body
end
end
end