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_nil(credentials) do request(method, data, config_path) end def request(method, data, config_path, credentials) when is_nil(credentials) do request(method, data, config_path) 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, NDCMerge.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>#{reason}"}, 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: "#{message}" 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 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