Current section

Files

Jump to
ndc_ex_sdk lib ndc_ex.ex
Raw

lib/ndc_ex.ex

defmodule NDCEx do
require HTTPoison
require NDCLogger
use Timex
def request(method, data, path) when is_bitstring(path) do
config = NDCConfig.load_provider(path)
NDCConfig.check_mandatory_provider_config(config)
NDCEx.Message.Base.build_document(method, data, config)
|> rest_call_with_message(method, data, config)
end
def request(method, data, config) do
NDCConfig.check_mandatory_provider_config(config)
NDCEx.Message.Base.build_document(method, data, config)
|> rest_call_with_message(method, data, config)
end
def request(method, data, config_path, credentials) when is_bitstring(config_path) and is_list(credentials) do
config = NDCConfig.load_provider(config_path)
credentials = NDCConfig.load_consumer(credentials[:consumer])
NDCConfig.check_mandatory_provider_config(config)
NDCEx.Message.Base.build_document(method, data, config, credentials)
|> rest_call_with_message(method, data, config, credentials)
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]
|> NDCMerge.get_method_headers(config[:rest][method])
|> NDCMerge.get_headers(method)
make_the_post(url, data, method, request_xml, headers, config)
end
def rest_call_with_message({:ok, request_xml}, method, data, config, credentials) do
url = NDCEx.Message.Base.build_url(config[:server][:url], method)
headers = config[:rest][:generic_headers]
|> NDCMerge.get_method_headers(config[:rest][method])
|> NDCMerge.get_headers(method)
|> NDCMerge.get_headers_consumer(credentials[:"#{config[:label]}"][:Head])
make_the_post(url, data, method, request_xml, headers, config)
end
defp make_the_post(url, data, method, request_xml, headers, config) do
#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 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(System.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