Class: CommandTower::Clients::ClientBase

Inherits:
Object
  • Object
show all
Defined in:
app/services/command_tower/clients/client_base.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(transport: Transport::FaradayAdapter.new(config: Transport::FaradayConfig.from_env)) ⇒ ClientBase

Returns a new instance of ClientBase.



24
25
26
27
28
29
30
# File 'app/services/command_tower/clients/client_base.rb', line 24

def initialize(transport: Transport::FaradayAdapter.new(config: Transport::FaradayConfig.from_env))
  raise Errors::ConfigurationError, "transport is required" if transport.nil?

  @transport = transport
  @namespace_mutex = Mutex.new
  @namespaces = {}
end

Class Method Details

.resolve_provider!(name, root: Clients) ⇒ Object

Internal: resolve a provider class under root via Zeitwerk const_get. Host product entry extends Invocation so root is the host Clients module. Not the locked product invocation API.



10
11
12
13
14
15
16
17
18
19
20
21
# File 'app/services/command_tower/clients/client_base.rb', line 10

def resolve_provider!(name, root: Clients)
  const_name = ConstResolution.normalize_name(name)
  path = "#{root.name}::#{const_name}"
  klass = ConstResolution.const_get!(root, const_name, expected: "provider")

  unless klass.is_a?(Class) && klass < ClientBase
    raise Errors::DiscoveryError,
          "invalid provider inheritance: expected #{path} < #{ClientBase.name}"
  end

  klass
end

Instance Method Details

#decode_response(response) ⇒ Object

Strip the transport wrapper before resource deserializers run. Default payload is the raw body — providers own encoding (JSON, XML, …).



65
66
67
68
69
70
# File 'app/services/command_tower/clients/client_base.rb', line 65

def decode_response(response)
  DecodedResponse.new(
    payload: response.body,
    provider_metadata: {}
  )
end

#enforce_authentication!Object

Provider-owned authentication check. Default is a no-op so bare/test providers keep working; ScopedClient delegates opaque scope kwargs.



59
60
61
# File 'app/services/command_tower/clients/client_base.rb', line 59

def enforce_authentication!(**)
  nil
end

#execute(request, context: nil) ⇒ Object

Primary execution contract. Accepts a normalized Clients::Transport::Request. Optional context: is internal framework plumbing (typically ScopedClient).



45
46
47
48
49
50
51
52
53
54
55
# File 'app/services/command_tower/clients/client_base.rb', line 45

def execute(request, context: nil)
  validate_request!(request)

  prepared = prepare_request(request, context: context)
  started_at = monotonic_now

  response = call_transport(prepared, started_at)
  return response if response.is_a?(ClientResult)

  build_result(response, started_at)
end

#resolve_namespace!(name) ⇒ Object

Internal: resolve a namespace module under this provider and wrap NamespaceProxy. Not the locked product invocation API.



34
35
36
37
38
39
40
# File 'app/services/command_tower/clients/client_base.rb', line 34

def resolve_namespace!(name)
  const_name = ConstResolution.normalize_name(name)

  @namespace_mutex.synchronize do
    @namespaces[const_name] ||= build_namespace_proxy!(const_name)
  end
end