Class: Savon::Operation

Inherits:
Object
  • Object
show all
Defined in:
lib/savon/operation.rb

Overview

Represents a single named SOAP operation.

Bridges the SOAP layer (envelope building, action headers, multipart) and the transport layer (execution, logging). Knows nothing about transport internals such as proxy, SSL, or auth.

Constant Summary collapse

CONTENT_TYPE =

SOAP Content-Type values indexed by SOAP version. SOAP 1.1 §6 (HTTP binding), SOAP 1.2 Part 2 §7.1.4 (HTTP media type)

{
  1 => "text/xml;charset=%s",
  2 => "application/soap+xml;charset=%s"
}.freeze
SOAP_REQUEST_TYPE =

Maps SOAP version to the base MIME type used in multipart requests. RFC 2387 §3.1 (multipart/related Content-Type parameter)

{
  1 => "text/xml",
  2 => "application/soap+xml"
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, wsdl, globals, transport) ⇒ Operation

Returns a new instance of Operation.



58
59
60
61
62
63
# File 'lib/savon/operation.rb', line 58

def initialize(name, wsdl, globals, transport)
  @name      = name
  @wsdl      = wsdl
  @globals   = globals
  @transport = transport
end

Class Method Details

.create(operation_name, wsdl, globals, transport) ⇒ Object



33
34
35
36
37
38
39
40
# File 'lib/savon/operation.rb', line 33

def self.create(operation_name, wsdl, globals, transport)
  if wsdl.document?
    ensure_name_is_symbol! operation_name
    ensure_exists! operation_name, wsdl
  end

  new(operation_name, wsdl, globals, transport)
end

.ensure_exists!(operation_name, wsdl) ⇒ Object



42
43
44
45
46
47
48
49
# File 'lib/savon/operation.rb', line 42

def self.ensure_exists!(operation_name, wsdl)
  unless wsdl.soap_actions.include? operation_name
    raise UnknownOperationError, "Unable to find SOAP operation: #{operation_name.inspect}\n" \
                                 "Operations provided by your service: #{wsdl.soap_actions.inspect}"
  end
rescue Wasabi::Resolver::HTTPError => e
  raise HTTPError, e.response
end

.ensure_name_is_symbol!(operation_name) ⇒ Object

Raises:

  • (ArgumentError)


51
52
53
54
55
56
# File 'lib/savon/operation.rb', line 51

def self.ensure_name_is_symbol!(operation_name)
  return if operation_name.is_a? Symbol

  raise ArgumentError, "Expected the first parameter (the name of the operation to call) to be a symbol\n" \
                       "Actual: #{operation_name.inspect} (#{operation_name.class})"
end

Instance Method Details

#build(locals = {}, &block) ⇒ Object



65
66
67
68
# File 'lib/savon/operation.rb', line 65

def build(locals = {}, &block)
  set_locals(locals, block)
  Builder.new(@name, @wsdl, @globals, @locals)
end

#call(locals = {}, &block) ⇒ Object

Executes the SOAP operation and returns a Savon::Response.

Observer short-circuit: if any registered observer returns a Transport::Response (or legacy HTTPI::Response), the HTTP call is skipped and that response is used directly.



75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/savon/operation.rb', line 75

def call(locals = {}, &block)
  builder  = build(locals, &block)
  response = Savon.notify_observers(@name, builder, @globals, @locals)

  response =
    if response.nil?
      @transport.post(endpoint.to_s, soap_headers(builder), builder.to_s, @locals)
    else
      normalize_observer_response(response)
    end

  create_response(response)
end

#request(locals = {}, &block) ⇒ Object

Builds and returns the HTTPI::Request that would be sent for this operation, without executing it. Useful for inspection and debugging. Not supported with transport: :faraday.



92
93
94
95
96
97
98
99
100
101
# File 'lib/savon/operation.rb', line 92

def request(locals = {}, &block)
  if @globals[:transport] == :faraday
    raise ArgumentError, "#request returns an HTTPI::Request and is not supported " \
                         "with transport: :faraday. Use client.faraday to configure " \
                         "the connection"
  end

  builder = build(locals, &block)
  @transport.to_httpi_request(endpoint.to_s, soap_headers(builder), builder.to_s, @locals)
end