Class: Gitlab::Triage::NetworkAdapters::GraphqlAdapter

Inherits:
BaseAdapter
  • Object
show all
Defined in:
lib/gitlab/triage/network_adapters/graphql_adapter.rb

Constant Summary collapse

Client =
GraphQL::Client

Constants inherited from BaseAdapter

BaseAdapter::USER_AGENT

Instance Attribute Summary

Attributes inherited from BaseAdapter

#options

Instance Method Summary collapse

Methods inherited from BaseAdapter

#initialize

Constructor Details

This class inherits a constructor from Gitlab::Triage::NetworkAdapters::BaseAdapter

Instance Method Details

#clientObject (private)



88
89
90
# File 'lib/gitlab/triage/network_adapters/graphql_adapter.rb', line 88

def client
  @client ||= Client.new(schema: schema, execute: http_client).tap { |client| client.allow_dynamic_queries = true }
end

#http_clientObject (private)



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/gitlab/triage/network_adapters/graphql_adapter.rb', line 56

def http_client
  Client::HTTP.new("#{options.host_url}/api/graphql") do
    def execute(document:, operation_name: nil, variables: {}, context: {}) # rubocop:disable Lint/NestedMethodDefinition
      body = {}
      body['query'] = document.to_query_string
      body['variables'] = variables if variables.any?
      body['operationName'] = operation_name if operation_name

      response = HTTParty.post(
        uri,
        body: body.to_json,
        headers: {
          'User-Agent' => USER_AGENT,
          'Content-type' => 'application/json',
          'PRIVATE-TOKEN' => context[:token]
        }
      )

      case response.code
      when 200, 400
        JSON.parse(response.body).merge('extensions' => { 'headers' => response.headers })
      else
        { 'errors' => [{ 'message' => "#{response.code} #{response.message}" }] }
      end
    end
  end
end

#parse_response(response, resource_path) ⇒ Object (private)



44
45
46
# File 'lib/gitlab/triage/network_adapters/graphql_adapter.rb', line 44

def parse_response(response, resource_path)
  resource_path.reduce(response.data) { |data, resource| data&.send(resource) } # rubocop:disable GitlabSecurity/PublicSend
end

#query(graphql_query, resource_path: [], variables: {}) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/gitlab/triage/network_adapters/graphql_adapter.rb', line 16

def query(graphql_query, resource_path: [], variables: {})
  response = client.query(graphql_query, variables: variables, context: { token: options.token })

  raise_on_error!(response)

  parsed_response = parse_response(response, resource_path)
  headers = response.extensions.fetch('headers', {})

  graphql_response = {
    ratelimit_remaining: headers['ratelimit-remaining'].to_i,
    ratelimit_reset_at: Time.at(headers['ratelimit-reset'].to_i)
  }

  return graphql_response.merge(results: {}) if parsed_response.nil?
  return graphql_response.merge(results: parsed_response.map(&:to_h)) if parsed_response.is_a?(Client::List)
  return graphql_response.merge(results: parsed_response.to_h) unless parsed_response.nodes?

  graphql_response.merge(
    more_pages: parsed_response.page_info.has_next_page,
    end_cursor: parsed_response.page_info.end_cursor,
    results: parsed_response.nodes.map(&:to_h)
  )
end

#raise_on_error!(response) ⇒ Object (private)



48
49
50
51
52
53
54
# File 'lib/gitlab/triage/network_adapters/graphql_adapter.rb', line 48

def raise_on_error!(response)
  return if response.errors.blank?

  puts Gitlab::Triage::UI.debug response.inspect if options.debug

  raise "There was an error: #{response.errors.messages.to_json}"
end

#schemaObject (private)



84
85
86
# File 'lib/gitlab/triage/network_adapters/graphql_adapter.rb', line 84

def schema
  @schema ||= Client.load_schema(http_client)
end