Skip to content

Commit

Permalink
Header Setter Extension: add default value to configuration (open-tel…
Browse files Browse the repository at this point in the history
…emetry#34455)

**Description:** <Describe what has changed.>
* default value config
* set default value in context source if metadata empty

**Link to tracking Issue: open-telemetry#34412

**Testing:** tbd

**Documentation:** see README.md

---------

Co-authored-by: Juraci Paixão Kröhling <juraci@kroehling.de>
  • Loading branch information
2 people authored and jriguera committed Oct 4, 2024
1 parent 91a965b commit 3aff405
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 8 deletions.
28 changes: 28 additions & 0 deletions .chloggen/headersetter_default_value.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
component: headersetterextension

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: adding default_value config

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
issues: [34412]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext: |
default_value config item applied in case context value is empty
# If your change doesn't affect end users or the exported elements of any package,
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: [user]
4 changes: 3 additions & 1 deletion extension/headerssetterextension/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ The following settings are required:
- `delete`: Deletes the header.
- `value`: The header value is looked up from the `value` property of the
extension configuration.
- `default_value`: (Optional) Value used if no entry for header key specified in `from_context` is present in request metadata.
- `from_context`: The header value is looked up from the request metadata,
such as HTTP headers, using the property value as the key (likely a header
name).

The `value` and `from_context` properties are mutually exclusive.
The `value` and `from_context,default_value` properties are mutually exclusive.

In order for `from_context` to work, other components in the pipeline also need to be configured appropriately:
* If a [batch processor][batch-processor] is present in the pipeline, it must be configured to [preserve client metadata][batch-processor-preserve-metadata].
Expand All @@ -54,6 +55,7 @@ extensions:
- action: insert
key: X-Scope-OrgID
from_context: tenant_id
default_value: Org-ID
- action: upsert
key: User-ID
value: user_id
Expand Down
9 changes: 5 additions & 4 deletions extension/headerssetterextension/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ type Config struct {
}

type HeaderConfig struct {
Action ActionValue `mapstructure:"action"`
Key *string `mapstructure:"key"`
Value *string `mapstructure:"value"`
FromContext *string `mapstructure:"from_context"`
Action ActionValue `mapstructure:"action"`
Key *string `mapstructure:"key"`
Value *string `mapstructure:"value"`
FromContext *string `mapstructure:"from_context"`
DefaultValue *string `mapstructure:"default_value"`
}

// ActionValue is the enum to capture the four types of actions to perform on a header
Expand Down
18 changes: 18 additions & 0 deletions extension/headerssetterextension/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ func TestLoadConfig(t *testing.T) {
Action: INSERT,
FromContext: stringp("tenant_id"),
Value: nil,
}, {
Key: stringp("X-Scope-OrgID"),
Action: INSERT,
FromContext: stringp("tenant_id"),
DefaultValue: stringp("some_id"),
Value: nil,
},
{
Key: stringp("User-ID"),
Expand Down Expand Up @@ -148,6 +154,18 @@ func TestValidateConfig(t *testing.T) {
},
errMissingSource,
},
{
"header value source is missing snd default value set",
[]HeaderConfig{
{
Key: stringp("name"),
Action: INSERT,
FromContext: stringp("from context"),
DefaultValue: stringp("default"),
},
},
nil,
},
{
"delete header action",
[]HeaderConfig{
Expand Down
7 changes: 6 additions & 1 deletion extension/headerssetterextension/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,13 @@ func newHeadersSetterExtension(cfg *Config, logger *zap.Logger) (auth.Client, er
Value: *header.Value,
}
} else if header.FromContext != nil {
var defaultValue = ""
if header.DefaultValue != nil {
defaultValue = *header.DefaultValue
}
s = &source.ContextSource{
Key: *header.FromContext,
Key: *header.FromContext,
DefaultValue: defaultValue,
}
}

Expand Down
36 changes: 36 additions & 0 deletions extension/headerssetterextension/extension_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,42 @@ var (
"header_name": "",
},
},
{
cfg: &Config{
HeadersConfig: []HeaderConfig{
{
Key: &header,
Action: INSERT,
FromContext: stringp("tenant"),
DefaultValue: stringp("default_tenant"),
},
},
},
metadata: client.NewMetadata(
map[string][]string{},
),
expectedHeaders: map[string]string{
"header_name": "default_tenant",
},
},
{
cfg: &Config{
HeadersConfig: []HeaderConfig{
{
Key: &header,
Action: INSERT,
FromContext: stringp("tenant"),
DefaultValue: stringp("default_tenant"),
},
},
},
metadata: client.NewMetadata(
map[string][]string{"tenant": {"acme"}},
),
expectedHeaders: map[string]string{
"header_name": "acme",
},
},
}
)

Expand Down
5 changes: 3 additions & 2 deletions extension/headerssetterextension/internal/source/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@ import (
var _ Source = (*ContextSource)(nil)

type ContextSource struct {
Key string
Key string
DefaultValue string
}

func (ts *ContextSource) Get(ctx context.Context) (string, error) {
cl := client.FromContext(ctx)
ss := cl.Metadata.Get(ts.Key)

if len(ss) == 0 {
return "", nil
return ts.DefaultValue, nil
}

if len(ss) > 1 {
Expand Down
4 changes: 4 additions & 0 deletions extension/headerssetterextension/testdata/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ headers_setter/1:
- key: X-Scope-OrgID
action: insert
from_context: "tenant_id"
- key: X-Scope-OrgID
action: insert
from_context: "tenant_id"
default_value: "some_id"
- key: User-ID
action: update
from_context: "user_id"
Expand Down

0 comments on commit 3aff405

Please sign in to comment.