From 61b84aec36130799603e1fb6f0b22155a42edfcd Mon Sep 17 00:00:00 2001 From: Robert Date: Fri, 12 Nov 2021 17:59:00 -0600 Subject: [PATCH] Feat: Add custom getters to common (#1006) Co-authored-by: Matthew Wear --- common/lib/opentelemetry/common.rb | 1 + .../lib/opentelemetry/common/propagation.rb | 33 +++++++++++++ .../common/propagation/rack_env_getter.rb | 48 +++++++++++++++++++ .../common/propagation/symbol_key_getter.rb | 26 ++++++++++ .../propagation/rack_env_getter_test.rb | 45 +++++++++++++++++ .../propagation/symbol_key_getter_test.rb | 24 ++++++++++ 6 files changed, 177 insertions(+) create mode 100644 common/lib/opentelemetry/common/propagation.rb create mode 100644 common/lib/opentelemetry/common/propagation/rack_env_getter.rb create mode 100644 common/lib/opentelemetry/common/propagation/symbol_key_getter.rb create mode 100644 common/test/opentelemetry/common/propagation/rack_env_getter_test.rb create mode 100644 common/test/opentelemetry/common/propagation/symbol_key_getter_test.rb diff --git a/common/lib/opentelemetry/common.rb b/common/lib/opentelemetry/common.rb index f8127ee57..8141cc9ff 100644 --- a/common/lib/opentelemetry/common.rb +++ b/common/lib/opentelemetry/common.rb @@ -6,6 +6,7 @@ require 'opentelemetry' require 'opentelemetry/common/http' +require 'opentelemetry/common/propagation' require 'opentelemetry/common/utilities' require 'opentelemetry/common/version' diff --git a/common/lib/opentelemetry/common/propagation.rb b/common/lib/opentelemetry/common/propagation.rb new file mode 100644 index 000000000..35d1d11c5 --- /dev/null +++ b/common/lib/opentelemetry/common/propagation.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require_relative './propagation/rack_env_getter' +require_relative './propagation/symbol_key_getter' + +module OpenTelemetry + module Common + # Propagation contains common helpers for context propagation. + module Propagation + extend self + + RACK_ENV_GETTER = RackEnvGetter.new + SYMBOL_KEY_GETTER = SymbolKeyGetter.new + private_constant :RACK_ENV_GETTER, :SYMBOL_KEY_GETTER + + # Returns a {RackEnvGetter} instance suitable for reading values from a + # Rack environment. + def rack_env_getter + RACK_ENV_GETTER + end + + # Returns a {SymbolKeyGetter} instance for reading values from a + # symbol keyed hash. + def symbol_key_getter + SYMBOL_KEY_GETTER + end + end + end +end diff --git a/common/lib/opentelemetry/common/propagation/rack_env_getter.rb b/common/lib/opentelemetry/common/propagation/rack_env_getter.rb new file mode 100644 index 000000000..a6be22196 --- /dev/null +++ b/common/lib/opentelemetry/common/propagation/rack_env_getter.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module Common + module Propagation + # The RackEnvGetter class provides a common methods for reading + # keys from a rack environment. It abstracts away the rack-normalization + # process so that keys can be looked up without having to transform them + # first. With this class you can get +traceparent+ instead of + # +HTTP_TRACEPARENT+ + class RackEnvGetter + # Converts key into a rack-normalized key and reads it from the carrier. + # Useful for extract operations. + def get(carrier, key) + carrier[to_rack_key(key)] || carrier[key] + end + + # Reads all keys from a carrier and converts them from the rack-normalized + # form to the original. The resulting keys will be lowercase and + # underscores will be replaced with dashes. + def keys(carrier) + carrier.keys.map(&method(:from_rack_key)) + end + + private + + def to_rack_key(key) + ret = 'HTTP_' + key + ret.tr!('-', '_') + ret.upcase! + ret + end + + def from_rack_key(key) + start = key.start_with?('HTTP_') ? 5 : 0 + ret = key[start..-1] + ret.tr!('_', '-') + ret.downcase! + ret + end + end + end + end +end diff --git a/common/lib/opentelemetry/common/propagation/symbol_key_getter.rb b/common/lib/opentelemetry/common/propagation/symbol_key_getter.rb new file mode 100644 index 000000000..02300d105 --- /dev/null +++ b/common/lib/opentelemetry/common/propagation/symbol_key_getter.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module Common + module Propagation + # The SymbolKeyGetter class provides a common method for reading + # symbol keys from a hash. + class SymbolKeyGetter + # Converts key into a symbol and reads it from the carrier. + # Useful for extract operations. + def get(carrier, key) + carrier[key.to_sym] + end + + # Reads all keys from a carrier + def keys(carrier) + carrier.keys.map(&:to_s) + end + end + end + end +end diff --git a/common/test/opentelemetry/common/propagation/rack_env_getter_test.rb b/common/test/opentelemetry/common/propagation/rack_env_getter_test.rb new file mode 100644 index 000000000..b53bc40f4 --- /dev/null +++ b/common/test/opentelemetry/common/propagation/rack_env_getter_test.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require 'test_helper' + +describe OpenTelemetry::Common::Propagation::RackEnvGetter do + let(:getter) do + OpenTelemetry::Context::Propagation::RackEnvGetter.new + end + + let(:carrier) do + { + 'HTTP_TRACEPARENT' => 'tp', + 'HTTP_TRACESTATE' => 'ts', + 'HTTP_X_SOURCE_ID' => '123', + 'rack.hijack?' => true + } + end + + describe '#get' do + it 'reads key from carrier' do + _(getter.get(carrier, 'traceparent')).must_equal('tp') + _(getter.get(carrier, 'tracestate')).must_equal('ts') + _(getter.get(carrier, 'x-source-id')).must_equal('123') + _(getter.get(carrier, 'rack.hijack?')).must_equal(true) + end + + it 'returns nil for non-existent key' do + _(getter.get(carrier, 'not-here')).must_be_nil + end + end + + describe '#keys' do + it 'returns carrier keys' do + _(getter.keys(carrier)).must_equal(%w[traceparent tracestate x-source-id rack.hijack?]) + end + + it 'returns empty array for empty carrier' do + _(getter.keys({})).must_equal([]) + end + end +end diff --git a/common/test/opentelemetry/common/propagation/symbol_key_getter_test.rb b/common/test/opentelemetry/common/propagation/symbol_key_getter_test.rb new file mode 100644 index 000000000..d744e96de --- /dev/null +++ b/common/test/opentelemetry/common/propagation/symbol_key_getter_test.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require 'test_helper' + +describe OpenTelemetry::Common::Propagation::SymbolKeyGetter do + let(:symbol_key_getter) { OpenTelemetry::Common::Propagation::SymbolKeyGetter.new } + let(:carrier) { { foo: 'bar' } } + + describe '#get' do + it 'retrieves the value' do + _(symbol_key_getter.get(carrier, 'foo')).must_equal('bar') + end + end + + describe '#keys' do + it 'returns all the keys as strings' do + _(symbol_key_getter.keys(carrier)).must_equal(['foo']) + end + end +end