I am trying to make a SOAP request to a remote SOAP Server using the Savon gem in rails. The SOAP Server is replicated on three instances with different IP Addresses, i.e. XXX.XXX.XXX.1, XXX.XXX.XXX.2 and XXX.XXX.XXX.3.
I am able to explicitly define the savon client endpoint using one of the above ip addresses like so:
Savon.client(
endpoint: "http://XXX.XXX.XXX.1:15043/enmac/SOAP",
namespace: '',
convert_request_keys_to: :camelcase,
env_namespace: 'SOAP-ENV',
namespace_identifier: nil,
log: true,
log_level: :info,
pretty_print_xml: true,
read_timeout: 90,
open_timeout: 90,
headers: {
"Accept-Encoding" => "gzip"
}
)
The problem with the above sample code is that when the SOAP Server instance with IP Address XXX.XXX.XXX.1 is down then my services goes down as well.
What I am actually looking for is an approach that will make sure that when SOAP Server instance XXX.XXX.XXX.1 is down then XXX.XXX.XXX.2 takes over etc.
Below is what I tried but couldn't get it to work properly:
I have a database table with all the SOAP Servers instances populated by IP address with only a single of them with a status of active
I have a the following method that shift to then next server:
def shift_oms_server @oms_server = OmsServer.where(status: true).first case @oms_server.ip_address.to_s when 'XXX.XXX.XXX.1' @oms_server.update_attribute(:status, false) @next_oms_server = OmsServer.where(ip_address: 'XXX.XXX.XXX.2').first @next_oms_server.update_attribute(:status, true) when 'XXX.XXX.XXX.2' @oms_server.update_attribute(:status, false) @next_oms_server = OmsServer.where(ip_address: 'XXX.XXX.XXX.3').first @next_oms_server.update_attribute(:status, true) when 'XXX.XXX.XXX.3' @oms_server.update_attribute(:status, false) @next_oms_server = OmsServer.where(ip_address: 'XXX.XXX.XXX.1').first @next_oms_server.update_attribute(:status, true) end end
Now I modify my Savon Client initialization like so:
@oms_server = OmsServer.where(status: true).first Savon.client( endpoint: "http://#{@oms_server.ip_address.to_s}:15043/enmac/SOAP", namespace: '', convert_request_keys_to: :camelcase, env_namespace: 'SOAP-ENV', namespace_identifier: nil, log: true, log_level: :info, pretty_print_xml: true, read_timeout: 90, open_timeout: 90, headers: { "Accept-Encoding" => "gzip" } )
Finally wherever I make the SOAP Request call I will have something like a begin rescue block like so:
begin # make soap server request rescue HTTPServerException => e shift_oms_server # make soap server request ensure shift_oms_server # make soap server request end
Forgive my English. The approach above didn't work for me. I will be happy if someone could enlighten me where I went wrong with the above approach or provide a direction to a more simpler and efficient approach.
Ideally I would like to know if it is possible to have more than one endpoints defined using the Savon gem, if yes how?
Thanks in advance.