-
Notifications
You must be signed in to change notification settings - Fork 173
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
187 B3 Headers Support #188
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -92,6 +92,7 @@ class TraceInfo(_TraceInfo): | |
collecting the trace context and passing it along to the server span. | ||
|
||
""" | ||
|
||
@classmethod | ||
def new(cls): | ||
"""Generate IDs for a new initial server span. | ||
|
@@ -135,6 +136,62 @@ def from_upstream(cls, trace_id, parent_id, span_id, sampled, flags): | |
|
||
return cls(trace_id, parent_id, span_id, sampled, flags) | ||
|
||
@classmethod | ||
def extract_upstream_header_values(cls, upstream_header_names, headers): | ||
"""Extract values from upstream headers. | ||
|
||
This method thinks about upstream headers by a general name as oppposed to the header | ||
name, i.e. "trace_id" instead of "X-Trace". These general names are "trace_id", | ||
"span_id", "parent_span_id", "sampled" and "flags". | ||
|
||
A dict mapping these general names to corresponding header names is expected. | ||
|
||
For example: | ||
|
||
{ | ||
"trace_id": ("X-Trace", "X-B3-TraceId"), | ||
"span_id": ("X-Span", "X-B3-SpanId"), | ||
"parent_span_id": ("X-Parent", "X-B3-ParentSpanId"), | ||
"sampled": ("X-Sampled", "X-B3-Sampled"), | ||
"flags": ("X-Flags", "X-B3-Flags"), | ||
} | ||
|
||
This structure is used to extract relevant values from the request headers resulting | ||
in a dict mapping general names to values. | ||
|
||
For example: | ||
|
||
{ | ||
"trace_id": "2391921232992245445", | ||
"span_id": "7638783876913511395", | ||
"parent_span_id": "3383915029748331832", | ||
"sampled": "1", | ||
} | ||
|
||
:param dict upstream_headers_name: Map of general upstream value labels to header names | ||
:param dict headers: Headers sent with a request | ||
:return: Values found in upstream trace headers | ||
:rtype: dict | ||
|
||
:raises: :py:exc:`ValueError` if conflicting values are found for the same header category | ||
|
||
""" | ||
extracted_values = {} | ||
for name, header_names in upstream_header_names.items(): | ||
values = [] | ||
for header_name in header_names: | ||
if header_name in headers: | ||
values.append(headers[header_name]) | ||
|
||
if not values: | ||
continue | ||
elif not all(value == values[0] for value in values): | ||
raise ValueError("Conflicting values found for %s header(s)".format(header_names)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we want to crash the whole request if the headers are iffy? (i could see either answer being reasonable) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I raised this to follow what is being done in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah, perfect. thanks! |
||
else: | ||
# All the values are the same | ||
extracted_values[name] = values[0] | ||
return extracted_values | ||
|
||
|
||
class AuthenticationTokenValidator(object): | ||
"""Factory that knows how to validate raw authentication tokens.""" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense just to merge this into
from_upstream
? I don't think we'd ever use one without the other?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah... I wanted to do that but there are subtle differences in how the two protocols handle the header values due to Thrift operating in bytes and HTTP using strings.
https://github.com/reddit/baseplate/pull/188/files#diff-db4cf04c08224f72cb9627e1f9866bbcR121
https://github.com/reddit/baseplate/pull/188/files#diff-d1382533c32ca95376190e31679acc05R162
Some type checking could be done. Or possibly a generic
but this started to feel protocol specific again. If others are added, other protocol specific edge cases could arise making the
from_upstream
method kind of gnarly. I'm happy to take a stab at it though, if you'd like.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 alrighty, makes sense. thanks