Class: WSDL::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/wsdl/client.rb

Overview

Wraps a Definition with an HTTP client for inspecting services and executing SOAP operations.

Client instances are thread-safe after construction. All instance state is either frozen (Definition, Config, #services) or only read (the HTTP client). Operation instances returned by #operation are not thread-safe — create one per thread or per request.

Examples:

Basic usage

definition = WSDL.parse('http://example.com/service?wsdl')
client = WSDL::Client.new(definition)
operation = client.operation('GetData')

Calling an operation

definition = WSDL.parse('http://example.com/service?wsdl')
client = WSDL::Client.new(definition)
operation = client.operation('GetData')
operation.prepare do
  tag('GetData') { tag('id', 123) }
end
response = operation.invoke

Multi-service WSDL

client = WSDL::Client.new(definition)
operation = client.operation('ExampleService', 'ExamplePort', 'GetData')

With custom HTTP client

client = WSDL::Client.new(definition, http: my_client)

With runtime options

config = WSDL::Config.new(strictness: WSDL::Strictness.off)
client = WSDL::Client.new(definition, config:)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(definition, http: nil, config: nil) ⇒ Client

Creates a new Client instance from a pre-built Definition.

Use WSDL.parse to create a Definition from a URL or file path. Parse-time options (strictness, limits, sandbox_paths) belong on WSDL.parse, not here.

Raises:

  • (ArgumentError)

    if definition is not a Definition



54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/wsdl/client.rb', line 54

def initialize(definition, http: nil, config: nil, **)
  unless definition.is_a?(Definition)
    raise ArgumentError,
      "Client.new requires a Definition (got #{definition.class}). " \
      'Use WSDL.parse(source) to create one.'
  end

  @config = config ? config.with(**) : Config.new(**)
  @http = http || WSDL.http_client.new
  @definition = definition
  @services = build_services.freeze
end

Instance Attribute Details

#configConfig (readonly)

Returns the behavioral configuration for this client.



76
77
78
# File 'lib/wsdl/client.rb', line 76

def config
  @config
end

#definitionDefinition (readonly)

Returns the Definition for this client's WSDL.



70
71
72
# File 'lib/wsdl/client.rb', line 70

def definition
  @definition
end

#servicesHash (readonly)

Returns the services and ports defined by the WSDL.

Each port includes an operations array. Overloaded operations (same name, different messages) include input_name for disambiguation.

The hash is eagerly built and frozen at construction time so that Client instances can be safely shared across threads.

Examples:

client.services
# => {"ServiceName" => {ports: {"PortName" => {type: "...", location: "...",
#      operations: [{name: "Op1"}, {name: "Op2"}]}}}}


101
102
103
# File 'lib/wsdl/client.rb', line 101

def services
  @services
end

Instance Method Details

#httpObject

Returns the HTTP client's config for customizing timeouts, SSL, etc.



82
83
84
# File 'lib/wsdl/client.rb', line 82

def http
  @http.config
end

#operation(service_name, port_name, operation_name, input_name: nil) ⇒ Operation #operation(operation_name, input_name: nil) ⇒ Operation

Returns an Operation instance for calling a SOAP operation.

Overloads:

  • #operation(service_name, port_name, operation_name, input_name: nil) ⇒ Operation

    Returns an operation for the specified service, port, and operation.

  • #operation(operation_name, input_name: nil) ⇒ Operation

    Returns an operation by name, auto-resolving the only service and port. Requires exactly one service with exactly one port.

Raises:

  • (ArgumentError)

    if the service, port, or operation does not exist, or if auto-resolution is used with multiple services/ports

  • (UnsupportedStyleError)

    if the operation uses an unsupported style (e.g., rpc/encoded)

  • (OperationOverloadError)

    if overloaded and strictness.operation_overloading is true



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/wsdl/client.rb', line 162

def operation(service_name_or_operation_name, port_name = nil, operation_name = nil, input_name: nil)
  if port_name && !operation_name
    raise ArgumentError,
      'Pass 1 argument (operation_name) or 3 arguments (service_name, port_name, operation_name).'
  end

  if operation_name
    service_name = service_name_or_operation_name
  else
    operation_name = service_name_or_operation_name
    service_name, port_name = resolve_service_and_port(nil, nil)
  end

  build_operation_from_definition(service_name, port_name, operation_name, input_name:)
end

#operations(service_name, port_name) ⇒ Array<String> #operationsArray<String>

Returns an array of operation names for a service and port.

Overloads:

  • #operations(service_name, port_name) ⇒ Array<String>

    Returns operations for the specified service and port.

  • #operationsArray<String>

    Returns operations for the only service and port. Requires exactly one service with exactly one port.

Raises:

  • (ArgumentError)

    if the service or port does not exist, or if auto-resolution is used with multiple services/ports



131
132
133
134
135
136
137
138
139
# File 'lib/wsdl/client.rb', line 131

def operations(service_name = nil, port_name = nil)
  if service_name && !port_name
    raise ArgumentError, 'Pass 0 arguments (auto-resolve) or 2 arguments (service_name, port_name).'
  end

  service_name, port_name = resolve_service_and_port(service_name, port_name)
  verify_service_and_port!(service_name.to_s, port_name.to_s)
  definition.operations(service_name.to_s, port_name.to_s).map { |op| op[:name] }.uniq
end

#service_nameString?

Returns the name of the primary service defined by the WSDL.

Falls back to the first discovered service key when the root definitions element does not provide a name attribute.



109
110
111
112
113
114
# File 'lib/wsdl/client.rb', line 109

def service_name
  name = definition.service_name
  return name if name && !name.empty?

  definition.services.first&.dig(:name)
end