-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Customizing azure-core Http Header in RetryPolicy #6217 #6400
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
Changes from all commits
cb7cd8e
ceba8b1
1f0abed
14f37b0
08b37ff
cb1f4f4
f5333dc
333e36e
20eadd4
ad88092
063dafd
b4bbb15
23dee25
e3f3ccd
878ccff
498a616
c076457
9c07867
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 |
|---|---|---|
|
|
@@ -3,22 +3,63 @@ | |
|
|
||
| package com.azure.core.http.policy; | ||
|
|
||
| import com.azure.core.http.HttpHeader; | ||
| import com.azure.core.http.HttpHeaders; | ||
| import com.azure.core.http.HttpRequest; | ||
| import com.azure.core.http.HttpPipelineCallContext; | ||
| import com.azure.core.http.HttpPipelineNextPolicy; | ||
| import com.azure.core.http.HttpResponse; | ||
| import reactor.core.publisher.Mono; | ||
|
|
||
| import java.util.Objects; | ||
| import java.util.UUID; | ||
| import java.util.function.Supplier; | ||
|
|
||
| /** | ||
| * The pipeline policy that puts a UUID in the request header. Azure uses the request id as | ||
| * the unique identifier for the request. | ||
| * The pipeline policy that adds request id header in {@link HttpRequest} once. These id does not change | ||
| * when request is retried. Azure uses the request id as the unique identifier for the request. | ||
| * Example of these headers are 'x-ms-client-request-id' and 'x-ms-correlation-request-id'. | ||
| */ | ||
| public class RequestIdPolicy implements HttpPipelinePolicy { | ||
| private static final String REQUEST_ID_HEADER = "x-ms-client-request-id"; | ||
| private final Supplier<HttpHeaders> requestIdSupplier; | ||
|
|
||
| /** | ||
| * Creates default {@link RequestIdPolicy}. | ||
| */ | ||
| public RequestIdPolicy() { | ||
| requestIdSupplier = () -> new HttpHeaders().put(REQUEST_ID_HEADER, UUID.randomUUID().toString()); | ||
| } | ||
|
|
||
| /** | ||
| * Creates {@link RequestIdPolicy} with provided {@link Supplier} to dynamically generate request id for each | ||
| * {@link HttpRequest}. | ||
| * | ||
| * @param requestIdSupplier to dynamically generate to request id for each {@link HttpRequest}. It is suggested | ||
| * that this {@link Supplier} provides unique value every time it is called. | ||
| * Example of these headers are 'x-ms-client-request-id', 'x-ms-correlation-request-id'. | ||
| * | ||
| * @throws NullPointerException when {@code requestIdSupplier} is {@code null}. | ||
| */ | ||
| public RequestIdPolicy(Supplier<HttpHeaders> requestIdSupplier) { | ||
| this.requestIdSupplier = Objects.requireNonNull(requestIdSupplier, "'requestIdSupplier' must not be null"); | ||
| } | ||
|
|
||
| @Override | ||
| public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next) { | ||
|
|
||
| HttpHeaders httpHeaders = requestIdSupplier.get(); | ||
|
Member
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. Wouldn't this allow users to provide a random set of HTTP headers and not just the request id headers? For e.g. the supplier can return new HttpHeaders().put("foo", "bar").put(REQUEST_ID_HEADER, UUID.randomUUID().toString());
Contributor
Author
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. yes . But unless we keep a bag of valid request id header, we can not validate. And whenever a new request-id header is introduced, we need to update the bag and release. |
||
| if (Objects.nonNull(httpHeaders) && httpHeaders.getSize() > 0) { | ||
| for (HttpHeader header : httpHeaders) { | ||
| String requestIdHeaderValue = context.getHttpRequest().getHeaders().getValue(header.getName()); | ||
| if (requestIdHeaderValue == null) { | ||
| context.getHttpRequest().getHeaders().put(header.getName(), header.getValue()); | ||
| } | ||
| } | ||
| return next.process(); | ||
| } | ||
|
|
||
| // If we were not able to set client provided Request ID header, we will set default 'REQUEST_ID_HEADER'. | ||
| String requestId = context.getHttpRequest().getHeaders().getValue(REQUEST_ID_HEADER); | ||
| if (requestId == null) { | ||
| context.getHttpRequest().getHeaders().put(REQUEST_ID_HEADER, UUID.randomUUID().toString()); | ||
|
|
||
This file was deleted.
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.
What happens if the supplier provides a non-unique value? Will the service reject the request? How does the service use this request id?
Uh oh!
There was an error while loading. Please reload this page.
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.
When I spoke to Jeffrey Richter about this, I understood, request-id is for telemetry purpose. For example Cognitive Search request-id is optional. https://docs.microsoft.com/en-us/rest/api/searchservice/common-http-request-and-response-headers-used-in-azure-search
Optional caller-specified request ID, in the form of a GUID with no decoration such as curly braces (for example, client-request-id: 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0). A caller-defined value that identifies the given request. If specified, this will be included in response information as a way to map the request.