Module: NFGClient::Utils

Included in:
Client
Defined in:
lib/nfg-client/utils.rb

Constant Summary collapse

@@nfg_urls =
{
  'sandbox' => {
    'host' => 'api-sandbox.networkforgood.org',
    'url' => 'https://api-sandbox.networkforgood.org/PartnerDonationService/DonationServices.asmx',
    'wsdl' => 'https://api-sandbox.networkforgood.org/PartnerDonationService/DonationServices.asmx?wsdl'
  },
  'production' => {
    'host' => 'api.networkforgood.org',
    'url' => 'https://api.networkforgood.org/PartnerDonationService/DonationServices.asmx',
    'wsdl' => 'https://api.networkforgood.org/PartnerDonationService/DonationServices.asmx?wsdl'
  }
}

Instance Method Summary collapse

Instance Method Details

#build_nfg_soap_request(nfg_method, params) ⇒ Object

Returns a complete NFG SOAP request based on the provided target method and params



66
67
68
# File 'lib/nfg-client/utils.rb', line 66

def build_nfg_soap_request(nfg_method, params)
  get_nfg_soap_request_template.gsub('|body|',"<#{nfg_method} xmlns=\"http://api.networkforgood.org/partnerdonationservice\">#{hash_to_xml(params)}</#{nfg_method}>")
end

#format_headers(nfg_method, soap_request) ⇒ Object

Returns NFG friendly headers hash for HTTPS post

Arguments:

nfg_method: (String)
soap_request: (String)


92
93
94
95
96
97
98
99
# File 'lib/nfg-client/utils.rb', line 92

def format_headers(nfg_method, soap_request)
  {
    'Host' => host,
    'Content-Type' => 'application/soap+xml; charset=utf-8',
    'Content-Length' => soap_request.length.to_s,
    'SOAPAction' => "#{url}/#{nfg_method}".gsub('.asmx','')
  }
end

#get_nfg_soap_request_templateObject

Returns a SOAP template with no body



71
72
73
# File 'lib/nfg-client/utils.rb', line 71

def get_nfg_soap_request_template
  "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\"><soap12:Body>|body|</soap12:Body></soap12:Envelope>"
end

#hash_to_xml(hash) ⇒ Object

Returns a string containing an XML representation of the given hash

Arguments:

hash: (Hash)


117
118
119
120
121
122
123
124
# File 'lib/nfg-client/utils.rb', line 117

def hash_to_xml(hash)
  hash.map do |k, v|
    text = (v.is_a? Hash) ? hash_to_xml(v) : v
    # It removes the digits at the end of each "DonationItem" hash key
    xml_elem = (v.is_a? Hash) ? k.to_s.gsub(/(\d)/, "") : k
    "<%s>%s</%s>" % [xml_elem, text, xml_elem]
  end.join
end

#hostObject

Returns NFG target host



102
103
104
105
# File 'lib/nfg-client/utils.rb', line 102

def host
  return @@nfg_urls['sandbox']['host'] if @use_sandbox
  @@nfg_urls['production']['host']
end

#nfg_soap_request(nfg_method, params) ⇒ Object

Makes HTTP POST request to NFG server (sandbox or production) and returns parsed XML response.

Arguments:

nfg_method: (String)
params: (Hash)


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/nfg-client/utils.rb', line 24

def nfg_soap_request(nfg_method, params)
  if (nfg_method.is_a? String) && (params.is_a? Hash)
    
    # Build SOAP 1.2 request
    soap_request = build_nfg_soap_request(nfg_method, params)

    headers = format_headers(nfg_method, soap_request)

    return_value = Hash.new

    # Being HTTP Post
    begin
      response = ssl_post(soap_request, headers)
      if response.code == '200'
        parsed = REXML::Document.new(response.body)
        # Build return hash parsing XML response
        if parsed.root.nil?
          return_value['StatusCode'] = 'MissingParameter'
          return_value['Message'] = response.body
          return_value['ErrorDetails'] = nil
        else
          return_value = parsed.root.elements['soap:Body'].elements["#{nfg_method}Response"].elements["#{nfg_method}Result"]
        end
      else
        return_value['StatusCode'] = 'UnexpectedError'
        return_value['Message'] = response.message
        return_value['ErrorDetails'] = response.body
      end
    rescue StandardError => e
      p e
      return_value['StatusCode'] = 'UnexpectedError'
      return_value['Message'] = e
      return_value['ErrorDetails'] = e.backtrace.join(' ')
    end

    return_value
  else
    raise ArgumentError.new('http_post requires a nfg_method and a hash of params')
  end
end

#requires!(hash, *params) ⇒ Object

Raises an exception if the required params are not part of the given hash

Arguments:

hash: (Hash)
*params: (Array or Symbol)


131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/nfg-client/utils.rb', line 131

def requires!(hash, *params)
  params.each do |param|
    if param.is_a?(Array)
      raise ArgumentError.new("Missing required parameter: #{param.first}") unless hash.has_key?(param.first) || hash.has_key?(param.first.to_s)

      valid_options = param[1..-1]
      raise ArgumentError.new("Parameter: #{param.first} must be one of #{valid_options.to_sentence(:words_connector => 'or')}") unless valid_options.include?(hash[param.first]) || valid_options.include?(hash[param.first.to_s])
    else
      raise ArgumentError.new("Missing required parameter: #{param}") unless hash.has_key?(param) || hash.has_key?(param.to_s)
    end
  end
end

#ssl_post(soap_request, headers) ⇒ Object

Makes HTTPS post request with given body (soap_request) and headers

Arguments:

soap_request: (String)
headers: (Hash)


80
81
82
83
84
85
# File 'lib/nfg-client/utils.rb', line 80

def ssl_post(soap_request, headers)
   uri = URI.parse(url)
   https_conn = Net::HTTP.new(uri.host, uri.port)
   https_conn.use_ssl = true
   https_conn.post(uri.path, soap_request, headers)
end

#urlObject

Returns NFG target URL



108
109
110
111
# File 'lib/nfg-client/utils.rb', line 108

def url
  return @@nfg_urls['sandbox']['url'] if @use_sandbox
  @@nfg_urls['production']['url']
end