Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 3 additions & 14 deletions lib/datadog/core/remote/transport/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require_relative '../../../core/transport/request'
require_relative '../../../core/transport/parcel'
require_relative '../../../core/transport/transport'
require_relative 'http/config'

module Datadog
Expand All @@ -23,28 +24,16 @@ class Request < Datadog::Core::Transport::Request
end

# Config transport
class Transport
attr_reader :client, :apis, :default_api, :current_api_id, :logger
class Transport < Core::Transport::Transport
self.http_client_class = Remote::Transport::HTTP::Config::Client

def initialize(apis, default_api, logger: Datadog.logger)
@apis = apis
@logger = logger

@client = Remote::Transport::HTTP::Config::Client.new(current_api, logger: logger)
end

##### there is only one transport! it's negotiation!
def send_config(payload)
json = JSON.dump(payload)
parcel = EncodedParcel.new(json)
request = Request.new(parcel)

@client.send_config_payload(request)
end

def current_api
@apis[HTTP::API::V7]
end
end
end
end
Expand Down
16 changes: 3 additions & 13 deletions lib/datadog/core/remote/transport/negotiation.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require_relative '../../../core/transport/request'
require_relative '../../../core/transport/transport'
require_relative 'http/negotiation'

# TODO: Resolve conceptual conundrum
Expand Down Expand Up @@ -32,25 +33,14 @@ class Request < Datadog::Core::Transport::Request
end

# Negotiation transport
class Transport
attr_reader :client, :apis, :default_api, :current_api_id, :logger

def initialize(apis, default_api, logger: Datadog.logger)
@apis = apis
@logger = logger

@client = Remote::Transport::HTTP::Negotiation::Client.new(current_api, logger: logger)
end
class Transport < Core::Transport::Transport
self.http_client_class = Remote::Transport::HTTP::Negotiation::Client

def send_info
request = Request.new

@client.send_info_payload(request)
end

def current_api
@apis[HTTP::API::ROOT]
end
end
end
end
Expand Down
13 changes: 4 additions & 9 deletions lib/datadog/core/telemetry/transport/telemetry.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require_relative '../../transport/parcel'
require_relative '../../transport/transport'
require_relative 'http/telemetry'

module Datadog
Expand All @@ -23,16 +24,10 @@ def initialize(request_type, parcel, api_key)
end
end

class Transport
attr_reader :client, :apis, :default_api, :current_api_id, :logger
attr_accessor :api_key

def initialize(apis, default_api, logger:)
@apis = apis
@logger = logger
class Transport < Core::Transport::Transport
self.http_client_class = Core::Telemetry::Transport::HTTP::Telemetry::Client

@client = Core::Telemetry::Transport::HTTP::Telemetry::Client.new(@apis[default_api], logger: logger)
end
attr_accessor :api_key

def send_telemetry(request_type:, payload:)
json = JSON.dump(payload)
Expand Down
26 changes: 13 additions & 13 deletions lib/datadog/core/transport/http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ module Transport
module HTTP
# Add adapters to registry
Builder::REGISTRY.set(
Transport::HTTP::Adapters::Net,
Core::Transport::HTTP::Adapters::Net,
Core::Configuration::Ext::Agent::HTTP::ADAPTER
)
Builder::REGISTRY.set(
Transport::HTTP::Adapters::Test,
Transport::Ext::Test::ADAPTER
Core::Transport::HTTP::Adapters::Test,
Core::Transport::Ext::Test::ADAPTER
)
Builder::REGISTRY.set(
Transport::HTTP::Adapters::UnixSocket,
Transport::Ext::UnixSocket::ADAPTER
Core::Transport::HTTP::Adapters::UnixSocket,
Core::Transport::Ext::UnixSocket::ADAPTER
)

module_function
Expand All @@ -45,27 +45,27 @@ def build(api_instance_class:, agent_settings:, logger: Datadog.logger, api_vers

def default_headers
{
Datadog::Core::Transport::Ext::HTTP::HEADER_CLIENT_COMPUTED_TOP_LEVEL => '1',
Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG =>
Core::Transport::Ext::HTTP::HEADER_CLIENT_COMPUTED_TOP_LEVEL => '1',
Core::Transport::Ext::HTTP::HEADER_META_LANG =>
Datadog::Core::Environment::Ext::LANG,
Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG_VERSION =>
Core::Transport::Ext::HTTP::HEADER_META_LANG_VERSION =>
Datadog::Core::Environment::Ext::LANG_VERSION,
Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG_INTERPRETER =>
Core::Transport::Ext::HTTP::HEADER_META_LANG_INTERPRETER =>
Datadog::Core::Environment::Ext::LANG_INTERPRETER,
Datadog::Core::Transport::Ext::HTTP::HEADER_META_LANG_INTERPRETER_VENDOR =>
Core::Transport::Ext::HTTP::HEADER_META_LANG_INTERPRETER_VENDOR =>
Core::Environment::Ext::LANG_ENGINE,
Datadog::Core::Transport::Ext::HTTP::HEADER_META_TRACER_VERSION =>
Core::Transport::Ext::HTTP::HEADER_META_TRACER_VERSION =>
Datadog::Core::Environment::Ext::GEM_DATADOG_VERSION
}.tap do |headers|
# Add container ID, if present.
if (container_id = Datadog::Core::Environment::Container.container_id)
headers[Datadog::Core::Transport::Ext::HTTP::HEADER_CONTAINER_ID] = container_id
headers[Core::Transport::Ext::HTTP::HEADER_CONTAINER_ID] = container_id
end
# TODO: inject configuration rather than reading from global here
unless Datadog.configuration.apm.tracing.enabled
# Sending this header to the agent will disable metrics computation (and billing) on the agent side
# by pretending it has already been done on the library side.
headers[Datadog::Core::Transport::Ext::HTTP::HEADER_CLIENT_COMPUTED_STATS] = 'yes'
headers[Core::Transport::Ext::HTTP::HEADER_CLIENT_COMPUTED_STATS] = 'yes'
end
end
end
Expand Down
45 changes: 45 additions & 0 deletions lib/datadog/core/transport/http/api/downgradable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# frozen_string_literal: true

module Datadog
module Core
module Transport
# Raised when the API verson to downgrade to does not map to a
# defined API.
class NoDowngradeAvailableError < StandardError
attr_reader :version

def initialize(version)
super

@version = version
end

def message
"No downgrade from transport API version #{version} is available!"
end
end

module HTTP
module API
# Functionality for downgrading API to a fallback one.
module Downgradable
private

def downgrade?(response)
return false unless apis.fallbacks.key?(@current_api_id)

response.not_found? || response.unsupported?
end

def downgrade!
downgrade_api_id = apis.fallbacks[@current_api_id]
raise NoDowngradeAvailableError, @current_api_id if downgrade_api_id.nil?

set_api!(downgrade_api_id)
end
end
end
end
end
end
end
6 changes: 6 additions & 0 deletions lib/datadog/core/transport/http/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ def api(key, spec, options = {})
@apis[key] = spec

# Apply as default API, if specified to do so.
#
# This code also sets the first defined API to be the default API.
# In APIs without fallbacks (currently, everything other than
# tracing's Traces, though DI Input will also have fallbacks soon)
# there is only one declaration of `transport.api`, and that
# API is set as the default API in the transport by this line.
@default_api = key if options.delete(:default) || @default_api.nil?

# Save all other settings for initialization
Expand Down
63 changes: 63 additions & 0 deletions lib/datadog/core/transport/transport.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# frozen_string_literal: true

module Datadog
module Core
module Transport
# Raised when configured with an unknown API version
class UnknownApiVersionError < StandardError
attr_reader :version

def initialize(version)
super

@version = version
end

def message
"No matching transport API for version #{version}!"
end
end

class HTTPClientClassNotSet < StandardError
end

# Base class for transports.
class Transport
attr_reader :client, :apis, :default_api, :current_api_id, :logger

class << self
# The HTTP client class to use for requests, derived from
# Core::Transport::HTTP::Client.
#
# Important: this attribute is NOT inherited by derived classes -
# it must be set by/for every Transport class.
attr_accessor :http_client_class
end

def initialize(apis, default_api, logger:)
@apis = apis
@default_api = default_api
@logger = logger

set_api!(default_api)
end

def current_api
apis[current_api_id]
end

private

def set_api!(api_id)
raise UnknownApiVersionError, api_id unless apis.key?(api_id)

@current_api_id = api_id
unless (client_class = self.class.http_client_class)
raise HTTPClientClassNotSet, "http_client_class is not set for #{self.class}"
end
@client = client_class.new(current_api, logger: logger)
end
end
end
end
end
19 changes: 4 additions & 15 deletions lib/datadog/data_streams/transport/stats.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
require 'zlib'
require_relative '../../core/transport/parcel'
require_relative '../../core/transport/request'
require_relative '../../core/transport/transport'
require_relative 'http/client'

module Datadog
module DataStreams
Expand All @@ -25,17 +27,8 @@ class Request < Datadog::Core::Transport::Request
end

# Transport for Data Streams Monitoring stats
class Transport
attr_reader :client, :apis, :current_api_id, :logger

def initialize(apis, default_api, logger:)
@apis = apis
@logger = logger
@default_api = default_api
@current_api_id = default_api

@client = DataStreams::Transport::HTTP::Client.new(current_api, logger: @logger)
end
class Transport < Core::Transport::Transport
self.http_client_class = DataStreams::Transport::HTTP::Client

def send_stats(payload)
# MessagePack encode and gzip compress the payload
Expand All @@ -49,10 +42,6 @@ def send_stats(payload)
# Send to agent
client.send_stats_payload(request)
end

def current_api
apis[@current_api_id]
end
end
end
end
Expand Down
16 changes: 3 additions & 13 deletions lib/datadog/di/transport/diagnostics.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

require_relative '../../core/transport/parcel'
require_relative '../../core/transport/transport'
require_relative 'http/diagnostics'

module Datadog
Expand All @@ -14,19 +15,8 @@ class EncodedParcel
class Request < Datadog::Core::Transport::Request
end

class Transport
attr_reader :client, :apis, :default_api, :current_api_id, :logger

def initialize(apis, default_api, logger:)
@apis = apis
@logger = logger

@client = DI::Transport::HTTP::Diagnostics::Client.new(current_api, logger: logger)
end

def current_api
@apis[HTTP::API::DIAGNOSTICS]
end
class Transport < Core::Transport::Transport
self.http_client_class = DI::Transport::HTTP::Diagnostics::Client

def send_diagnostics(payload)
json = JSON.dump(payload)
Expand Down
18 changes: 5 additions & 13 deletions lib/datadog/di/transport/input.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# frozen_string_literal: true

require_relative '../../core/transport/parcel'
require_relative '../../core/transport/request'
require_relative '../../core/transport/transport'
require_relative '../error'
require_relative 'http/input'

module Datadog
Expand All @@ -21,19 +24,8 @@ def initialize(parcel, serialized_tags)
end
end

class Transport
attr_reader :client, :apis, :default_api, :current_api_id, :logger

def initialize(apis, default_api, logger:)
@apis = apis
@logger = logger

@client = DI::Transport::HTTP::Input::Client.new(current_api, logger: logger)
end

def current_api
@apis[HTTP::API::INPUT]
end
class Transport < Core::Transport::Transport
self.http_client_class = DI::Transport::HTTP::Input::Client

def send_input(payload, tags)
json = JSON.dump(payload)
Expand Down
Loading
Loading