0
# HTTP Pipeline Policies
1
2
Comprehensive HTTP pipeline policies providing cross-cutting concerns like authentication, retry, logging, and request modification. These policies enable modular request/response processing with configurable behavior.
3
4
## Capabilities
5
6
### Core Policy Interfaces
7
8
Base interfaces for creating custom HTTP pipeline policies.
9
10
```java { .api }
11
/**
12
* Interface for policies that can be added to the HttpPipeline.
13
*/
14
interface HttpPipelinePolicy {
15
/**
16
* Processes provided request context and invokes the next policy.
17
* @param context The request context
18
* @param next The next HTTP pipeline policy to process
19
* @return A Mono that emits an HttpResponse
20
*/
21
Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next);
22
}
23
24
/**
25
* Interface for synchronous HTTP pipeline policies.
26
*/
27
interface HttpPipelineSyncPolicy extends HttpPipelinePolicy {
28
/**
29
* Processes provided request context and invokes the next policy synchronously.
30
* @param context The request context
31
* @param next The next HTTP pipeline policy to process
32
* @return The HttpResponse
33
*/
34
HttpResponse processSync(HttpPipelineCallContext context, HttpPipelineNextSyncPolicy next);
35
}
36
```
37
38
### Authentication Policies
39
40
Policies for various authentication mechanisms.
41
42
```java { .api }
43
/**
44
* Pipeline policy that applies a Bearer token credential to requests as an Authorization header.
45
*/
46
class BearerTokenAuthenticationPolicy implements HttpPipelinePolicy {
47
/**
48
* Creates BearerTokenAuthenticationPolicy.
49
* @param credential The token credential to authenticate requests
50
* @param scopes The scopes required for the token
51
*/
52
public BearerTokenAuthenticationPolicy(TokenCredential credential, String... scopes);
53
54
/**
55
* Creates BearerTokenAuthenticationPolicy with custom options.
56
* @param credential The token credential to authenticate requests
57
* @param scopes The scopes required for the token
58
* @param challengeHandler Custom challenge handler for handling authentication challenges
59
*/
60
public BearerTokenAuthenticationPolicy(TokenCredential credential, String[] scopes, AuthenticationChallengeHandler challengeHandler);
61
62
@Override
63
public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next);
64
}
65
66
/**
67
* Pipeline policy that applies AzureKeyCredential to requests.
68
*/
69
class AzureKeyCredentialPolicy implements HttpPipelinePolicy {
70
/**
71
* Creates AzureKeyCredentialPolicy.
72
* @param name The name of the key credential header or query parameter
73
* @param credential The AzureKeyCredential used to authenticate requests
74
* @param location Where to apply the key (HEADER or QUERY_PARAMETER)
75
*/
76
public AzureKeyCredentialPolicy(String name, AzureKeyCredential credential, AzureKeyCredentialPolicy.KeyCredentialLocation location);
77
78
@Override
79
public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next);
80
81
/**
82
* Enum defining where the key credential should be applied.
83
*/
84
enum KeyCredentialLocation {
85
HEADER, QUERY_PARAMETER
86
}
87
}
88
89
/**
90
* Pipeline policy that applies AzureSasCredential to requests as a query parameter.
91
*/
92
class AzureSasCredentialPolicy implements HttpPipelinePolicy {
93
/**
94
* Creates AzureSasCredentialPolicy.
95
* @param credential The AzureSasCredential used to authenticate requests
96
*/
97
public AzureSasCredentialPolicy(AzureSasCredential credential);
98
99
/**
100
* Creates AzureSasCredentialPolicy with custom parameter name.
101
* @param credential The AzureSasCredential used to authenticate requests
102
* @param queryParameterName Custom query parameter name for the SAS token
103
*/
104
public AzureSasCredentialPolicy(AzureSasCredential credential, String queryParameterName);
105
106
@Override
107
public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next);
108
}
109
110
/**
111
* Pipeline policy that applies KeyCredential to requests.
112
*/
113
class KeyCredentialPolicy implements HttpPipelinePolicy {
114
/**
115
* Creates KeyCredentialPolicy.
116
* @param name The name of the key credential header
117
* @param credential The KeyCredential used to authenticate requests
118
*/
119
public KeyCredentialPolicy(String name, KeyCredential credential);
120
121
@Override
122
public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next);
123
}
124
```
125
126
### Retry Policies
127
128
Policies for handling request retries with various strategies.
129
130
```java { .api }
131
/**
132
* Pipeline policy that retries requests when recoverable HTTP errors or exceptions occur.
133
*/
134
class RetryPolicy implements HttpPipelinePolicy {
135
/**
136
* Creates RetryPolicy with default retry options.
137
*/
138
public RetryPolicy();
139
140
/**
141
* Creates RetryPolicy with custom retry options.
142
* @param retryOptions The retry configuration options
143
*/
144
public RetryPolicy(RetryOptions retryOptions);
145
146
/**
147
* Creates RetryPolicy with custom retry strategy.
148
* @param retryStrategy Custom retry strategy implementation
149
*/
150
public RetryPolicy(RetryStrategy retryStrategy);
151
152
@Override
153
public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next);
154
}
155
156
/**
157
* Configuration options for retry behavior.
158
*/
159
class RetryOptions {
160
/**
161
* Creates RetryOptions with default settings.
162
*/
163
public RetryOptions();
164
165
/**
166
* Gets the maximum number of retry attempts.
167
* @return Maximum retry attempts
168
*/
169
public int getMaxRetries();
170
171
/**
172
* Sets the maximum number of retry attempts.
173
* @param maxRetries Maximum retry attempts (0-10)
174
* @return Updated RetryOptions
175
*/
176
public RetryOptions setMaxRetries(int maxRetries);
177
178
/**
179
* Gets the delay between retry attempts.
180
* @return Delay duration
181
*/
182
public Duration getDelay();
183
184
/**
185
* Sets the delay between retry attempts.
186
* @param delay Delay duration
187
* @return Updated RetryOptions
188
*/
189
public RetryOptions setDelay(Duration delay);
190
191
/**
192
* Gets the maximum delay between retry attempts.
193
* @return Maximum delay duration
194
*/
195
public Duration getMaxDelay();
196
197
/**
198
* Sets the maximum delay between retry attempts.
199
* @param maxDelay Maximum delay duration
200
* @return Updated RetryOptions
201
*/
202
public RetryOptions setMaxDelay(Duration maxDelay);
203
204
/**
205
* Gets the retry strategy.
206
* @return Retry strategy
207
*/
208
public RetryStrategy getRetryStrategy();
209
210
/**
211
* Sets the retry strategy.
212
* @param retryStrategy Retry strategy implementation
213
* @return Updated RetryOptions
214
*/
215
public RetryOptions setRetryStrategy(RetryStrategy retryStrategy);
216
}
217
218
/**
219
* Interface defining retry strategies.
220
*/
221
interface RetryStrategy {
222
/**
223
* Calculates the delay before the next retry attempt.
224
* @param retryAttempt The current retry attempt number (1-based)
225
* @param baseDelay The base delay duration
226
* @param maxDelay The maximum allowed delay
227
* @return The calculated delay duration
228
*/
229
Duration calculateRetryDelay(int retryAttempt, Duration baseDelay, Duration maxDelay);
230
}
231
232
/**
233
* Exponential backoff retry strategy.
234
*/
235
class ExponentialBackoff implements RetryStrategy {
236
/**
237
* Creates ExponentialBackoff with default options.
238
*/
239
public ExponentialBackoff();
240
241
/**
242
* Creates ExponentialBackoff with custom options.
243
* @param options Exponential backoff configuration
244
*/
245
public ExponentialBackoff(ExponentialBackoffOptions options);
246
247
@Override
248
public Duration calculateRetryDelay(int retryAttempt, Duration baseDelay, Duration maxDelay);
249
}
250
251
/**
252
* Fixed delay retry strategy.
253
*/
254
class FixedDelay implements RetryStrategy {
255
/**
256
* Creates FixedDelay with default options.
257
*/
258
public FixedDelay();
259
260
/**
261
* Creates FixedDelay with custom options.
262
* @param options Fixed delay configuration
263
*/
264
public FixedDelay(FixedDelayOptions options);
265
266
@Override
267
public Duration calculateRetryDelay(int retryAttempt, Duration baseDelay, Duration maxDelay);
268
}
269
```
270
271
### Logging Policies
272
273
Policies for HTTP request and response logging.
274
275
```java { .api }
276
/**
277
* Pipeline policy that handles logging of HTTP requests and responses.
278
*/
279
class HttpLoggingPolicy implements HttpPipelinePolicy {
280
/**
281
* Creates HttpLoggingPolicy with default options.
282
*/
283
public HttpLoggingPolicy();
284
285
/**
286
* Creates HttpLoggingPolicy with custom options.
287
* @param httpLogOptions HTTP logging configuration
288
*/
289
public HttpLoggingPolicy(HttpLogOptions httpLogOptions);
290
291
@Override
292
public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next);
293
}
294
295
/**
296
* Configuration for HTTP request and response logging.
297
*/
298
class HttpLogOptions {
299
/**
300
* Creates HttpLogOptions with default settings.
301
*/
302
public HttpLogOptions();
303
304
/**
305
* Gets the logging detail level.
306
* @return The logging detail level
307
*/
308
public HttpLogDetailLevel getLogLevel();
309
310
/**
311
* Sets the logging detail level.
312
* @param logLevel The logging detail level
313
* @return Updated HttpLogOptions
314
*/
315
public HttpLogOptions setLogLevel(HttpLogDetailLevel logLevel);
316
317
/**
318
* Gets the allowed header names for logging.
319
* @return Set of allowed header names
320
*/
321
public Set<String> getAllowedHeaderNames();
322
323
/**
324
* Sets the allowed header names for logging.
325
* @param allowedHeaderNames Set of allowed header names
326
* @return Updated HttpLogOptions
327
*/
328
public HttpLogOptions setAllowedHeaderNames(Set<String> allowedHeaderNames);
329
330
/**
331
* Adds an allowed header name for logging.
332
* @param allowedHeaderName Header name to allow
333
* @return Updated HttpLogOptions
334
*/
335
public HttpLogOptions addAllowedHeaderName(String allowedHeaderName);
336
337
/**
338
* Gets the allowed query parameter names for logging.
339
* @return Set of allowed query parameter names
340
*/
341
public Set<String> getAllowedQueryParamNames();
342
343
/**
344
* Sets the allowed query parameter names for logging.
345
* @param allowedQueryParamNames Set of allowed query parameter names
346
* @return Updated HttpLogOptions
347
*/
348
public HttpLogOptions setAllowedQueryParamNames(Set<String> allowedQueryParamNames);
349
350
/**
351
* Adds an allowed query parameter name for logging.
352
* @param allowedQueryParamName Query parameter name to allow
353
* @return Updated HttpLogOptions
354
*/
355
public HttpLogOptions addAllowedQueryParamName(String allowedQueryParamName);
356
357
/**
358
* Gets whether to pretty print JSON bodies.
359
* @return Whether to pretty print JSON
360
*/
361
public boolean isPrettyPrintBody();
362
363
/**
364
* Sets whether to pretty print JSON bodies.
365
* @param prettyPrintBody Whether to pretty print JSON
366
* @return Updated HttpLogOptions
367
*/
368
public HttpLogOptions setPrettyPrintBody(boolean prettyPrintBody);
369
}
370
371
/**
372
* Enumeration of HTTP logging detail levels.
373
*/
374
enum HttpLogDetailLevel {
375
/**
376
* No logging.
377
*/
378
NONE,
379
380
/**
381
* Log only the request method and URL, and the response status code and execution time.
382
*/
383
BASIC,
384
385
/**
386
* Log the basic information along with request and response headers.
387
*/
388
HEADERS,
389
390
/**
391
* Log the headers information along with request and response body.
392
*/
393
BODY,
394
395
/**
396
* Log everything including request and response bodies and headers.
397
*/
398
BODY_AND_HEADERS
399
}
400
```
401
402
### Request Modification Policies
403
404
Policies for modifying HTTP requests.
405
406
```java { .api }
407
/**
408
* Pipeline policy that adds headers to HTTP requests.
409
*/
410
class AddHeadersPolicy implements HttpPipelinePolicy {
411
/**
412
* Creates AddHeadersPolicy.
413
* @param headers Headers to add to requests
414
*/
415
public AddHeadersPolicy(HttpHeaders headers);
416
417
@Override
418
public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next);
419
}
420
421
/**
422
* Pipeline policy that adds headers from context to HTTP requests.
423
*/
424
class AddHeadersFromContextPolicy implements HttpPipelinePolicy {
425
/**
426
* Creates AddHeadersFromContextPolicy.
427
*/
428
public AddHeadersFromContextPolicy();
429
430
@Override
431
public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next);
432
}
433
434
/**
435
* Pipeline policy that adds the current date to HTTP requests.
436
*/
437
class AddDatePolicy implements HttpPipelinePolicy {
438
/**
439
* Creates AddDatePolicy.
440
*/
441
public AddDatePolicy();
442
443
@Override
444
public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next);
445
}
446
447
/**
448
* Pipeline policy that sets the User-Agent header.
449
*/
450
class UserAgentPolicy implements HttpPipelinePolicy {
451
/**
452
* Creates UserAgentPolicy with application ID.
453
* @param applicationId The application identifier
454
*/
455
public UserAgentPolicy(String applicationId);
456
457
/**
458
* Creates UserAgentPolicy with custom user agent string.
459
* @param applicationId The application identifier
460
* @param applicationVersion The application version
461
* @param configuration Configuration for additional user agent information
462
*/
463
public UserAgentPolicy(String applicationId, String applicationVersion, Configuration configuration);
464
465
@Override
466
public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next);
467
}
468
469
/**
470
* Pipeline policy that adds a request ID to HTTP requests.
471
*/
472
class RequestIdPolicy implements HttpPipelinePolicy {
473
/**
474
* Creates RequestIdPolicy with default request ID header.
475
*/
476
public RequestIdPolicy();
477
478
/**
479
* Creates RequestIdPolicy with custom request ID header name.
480
* @param requestIdHeaderName Custom header name for request ID
481
*/
482
public RequestIdPolicy(String requestIdHeaderName);
483
484
@Override
485
public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next);
486
}
487
488
/**
489
* Pipeline policy that handles request timeouts.
490
*/
491
class TimeoutPolicy implements HttpPipelinePolicy {
492
/**
493
* Creates TimeoutPolicy.
494
* @param timeout The timeout duration for requests
495
*/
496
public TimeoutPolicy(Duration timeout);
497
498
@Override
499
public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next);
500
}
501
```
502
503
### Redirect and Network Policies
504
505
Policies for handling redirects and network-level concerns.
506
507
```java { .api }
508
/**
509
* Pipeline policy that handles HTTP redirects.
510
*/
511
class RedirectPolicy implements HttpPipelinePolicy {
512
/**
513
* Creates RedirectPolicy with default redirect strategy.
514
*/
515
public RedirectPolicy();
516
517
/**
518
* Creates RedirectPolicy with custom redirect strategy.
519
* @param redirectStrategy Custom redirect handling strategy
520
*/
521
public RedirectPolicy(RedirectStrategy redirectStrategy);
522
523
@Override
524
public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next);
525
}
526
527
/**
528
* Interface for redirect handling strategies.
529
*/
530
interface RedirectStrategy {
531
/**
532
* Determines if a request should be redirected based on the response.
533
* @param httpRequest The original HTTP request
534
* @param httpResponse The HTTP response indicating a redirect
535
* @param redirectAttempt The number of redirect attempts so far
536
* @param maxRedirects The maximum number of allowed redirects
537
* @return true if the request should be redirected, false otherwise
538
*/
539
boolean shouldRedirect(HttpRequest httpRequest, HttpResponse httpResponse, int redirectAttempt, int maxRedirects);
540
541
/**
542
* Creates a redirect request based on the original request and response.
543
* @param httpRequest The original HTTP request
544
* @param httpResponse The HTTP response indicating a redirect
545
* @param redirectAttempt The number of redirect attempts so far
546
* @return The redirect HTTP request, or null if redirect should not happen
547
*/
548
HttpRequest createRedirectRequest(HttpRequest httpRequest, HttpResponse httpResponse, int redirectAttempt);
549
}
550
551
/**
552
* Default implementation of redirect strategy.
553
*/
554
class DefaultRedirectStrategy implements RedirectStrategy {
555
/**
556
* Creates DefaultRedirectStrategy with default settings.
557
*/
558
public DefaultRedirectStrategy();
559
560
/**
561
* Creates DefaultRedirectStrategy with custom maximum redirects.
562
* @param maxRedirects Maximum number of redirects to follow
563
*/
564
public DefaultRedirectStrategy(int maxRedirects);
565
566
@Override
567
public boolean shouldRedirect(HttpRequest httpRequest, HttpResponse httpResponse, int redirectAttempt, int maxRedirects);
568
569
@Override
570
public HttpRequest createRedirectRequest(HttpRequest httpRequest, HttpResponse httpResponse, int redirectAttempt);
571
}
572
573
/**
574
* Pipeline policy that handles cookies.
575
*/
576
class CookiePolicy implements HttpPipelinePolicy {
577
/**
578
* Creates CookiePolicy.
579
*/
580
public CookiePolicy();
581
582
@Override
583
public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next);
584
}
585
586
/**
587
* Pipeline policy that ensures the correct host header.
588
*/
589
class HostPolicy implements HttpPipelinePolicy {
590
/**
591
* Creates HostPolicy.
592
*/
593
public HostPolicy();
594
595
@Override
596
public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next);
597
}
598
599
/**
600
* Pipeline policy that ensures the correct port in the URL.
601
*/
602
class PortPolicy implements HttpPipelinePolicy {
603
/**
604
* Creates PortPolicy.
605
*/
606
public PortPolicy();
607
608
@Override
609
public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next);
610
}
611
612
/**
613
* Pipeline policy that ensures the correct protocol (HTTP/HTTPS).
614
*/
615
class ProtocolPolicy implements HttpPipelinePolicy {
616
/**
617
* Creates ProtocolPolicy.
618
*/
619
public ProtocolPolicy();
620
621
@Override
622
public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next);
623
}
624
```
625
626
### Policy Provider Interfaces
627
628
Interfaces for providing policies at different stages of the pipeline.
629
630
```java { .api }
631
/**
632
* Provider interface for policies that should be executed before retry policies.
633
*/
634
interface BeforeRetryPolicyProvider {
635
/**
636
* Gets the policies to execute before retry logic.
637
* @return List of HttpPipelinePolicy instances
638
*/
639
List<HttpPipelinePolicy> getPolicies();
640
}
641
642
/**
643
* Provider interface for policies that should be executed after retry policies.
644
*/
645
interface AfterRetryPolicyProvider {
646
/**
647
* Gets the policies to execute after retry logic.
648
* @return List of HttpPipelinePolicy instances
649
*/
650
List<HttpPipelinePolicy> getPolicies();
651
}
652
653
/**
654
* General provider interface for HTTP pipeline policies.
655
*/
656
interface HttpPolicyProvider {
657
/**
658
* Gets the HTTP pipeline policies provided by this provider.
659
* @return List of HttpPipelinePolicy instances
660
*/
661
List<HttpPipelinePolicy> getPolicies();
662
}
663
664
/**
665
* Utility class for working with HTTP policy providers.
666
*/
667
class HttpPolicyProviders {
668
/**
669
* Adds a policy provider to be executed before retry policies.
670
* @param provider The policy provider
671
*/
672
public static void addBeforeRetryPolicyProvider(BeforeRetryPolicyProvider provider);
673
674
/**
675
* Adds a policy provider to be executed after retry policies.
676
* @param provider The policy provider
677
*/
678
public static void addAfterRetryPolicyProvider(AfterRetryPolicyProvider provider);
679
680
/**
681
* Gets all before retry policy providers.
682
* @return List of BeforeRetryPolicyProvider instances
683
*/
684
public static List<BeforeRetryPolicyProvider> getBeforeRetryPolicyProviders();
685
686
/**
687
* Gets all after retry policy providers.
688
* @return List of AfterRetryPolicyProvider instances
689
*/
690
public static List<AfterRetryPolicyProvider> getAfterRetryPolicyProviders();
691
}
692
```
693
694
## Usage Examples
695
696
### Basic Policy Pipeline Setup
697
698
```java
699
import com.azure.core.http.*;
700
import com.azure.core.http.policy.*;
701
import com.azure.core.credential.TokenCredential;
702
import com.azure.identity.DefaultAzureCredentialBuilder;
703
704
public class BasicPipelineSetup {
705
706
public HttpPipeline createStandardPipeline(String endpoint) {
707
TokenCredential credential = new DefaultAzureCredentialBuilder().build();
708
709
return new HttpPipelineBuilder()
710
.httpClient(HttpClient.createDefault())
711
.policies(
712
// Request modification policies
713
new UserAgentPolicy("MyApp/1.0"),
714
new RequestIdPolicy(),
715
new AddDatePolicy(),
716
717
// Authentication policy
718
new BearerTokenAuthenticationPolicy(credential, "https://management.azure.com/.default"),
719
720
// Retry policy
721
new RetryPolicy(new RetryOptions()
722
.setMaxRetries(3)
723
.setDelay(Duration.ofSeconds(1))
724
.setMaxDelay(Duration.ofSeconds(10))),
725
726
// Logging policy
727
new HttpLoggingPolicy(new HttpLogOptions()
728
.setLogLevel(HttpLogDetailLevel.HEADERS)
729
.addAllowedHeaderName("x-ms-request-id")),
730
731
// Redirect policy
732
new RedirectPolicy()
733
)
734
.build();
735
}
736
}
737
```
738
739
### Custom Authentication Policy
740
741
```java
742
import com.azure.core.http.policy.*;
743
import com.azure.core.credential.AzureKeyCredential;
744
745
public class CustomAuthenticationExample {
746
747
public HttpPipeline createPipelineWithMultipleAuth(String apiKey, String sasToken) {
748
return new HttpPipelineBuilder()
749
.httpClient(HttpClient.createDefault())
750
.policies(
751
new UserAgentPolicy("MultiAuthApp/1.0"),
752
753
// Multiple authentication policies
754
new AzureKeyCredentialPolicy("x-api-key",
755
new AzureKeyCredential(apiKey),
756
AzureKeyCredentialPolicy.KeyCredentialLocation.HEADER),
757
758
new AzureSasCredentialPolicy(new AzureSasCredential(sasToken)),
759
760
// Custom headers
761
new AddHeadersPolicy(new HttpHeaders()
762
.put("x-custom-client", "MyApplication")
763
.put("Accept", "application/json")),
764
765
new RetryPolicy(),
766
new HttpLoggingPolicy()
767
)
768
.build();
769
}
770
}
771
```
772
773
### Advanced Retry Configuration
774
775
```java
776
import com.azure.core.http.policy.*;
777
import java.time.Duration;
778
779
public class AdvancedRetryExample {
780
781
public RetryPolicy createCustomRetryPolicy() {
782
RetryOptions options = new RetryOptions()
783
.setMaxRetries(5)
784
.setDelay(Duration.ofMillis(500))
785
.setMaxDelay(Duration.ofSeconds(30))
786
.setRetryStrategy(new ExponentialBackoff(
787
new ExponentialBackoffOptions()
788
.setBaseDelay(Duration.ofMillis(500))
789
.setMaxDelay(Duration.ofSeconds(30))));
790
791
return new RetryPolicy(options);
792
}
793
794
// Custom retry strategy
795
public class CustomRetryStrategy implements RetryStrategy {
796
@Override
797
public Duration calculateRetryDelay(int retryAttempt, Duration baseDelay, Duration maxDelay) {
798
// Custom logic: fibonacci-like backoff
799
long delayMs = Math.min(
800
baseDelay.toMillis() * fibonacci(retryAttempt),
801
maxDelay.toMillis()
802
);
803
return Duration.ofMillis(delayMs);
804
}
805
806
private long fibonacci(int n) {
807
if (n <= 1) return n;
808
return fibonacci(n - 1) + fibonacci(n - 2);
809
}
810
}
811
}
812
```
813
814
### Comprehensive Logging Setup
815
816
```java
817
import com.azure.core.http.policy.*;
818
import java.util.Set;
819
820
public class ComprehensiveLoggingExample {
821
822
public HttpLoggingPolicy createDetailedLoggingPolicy() {
823
HttpLogOptions options = new HttpLogOptions()
824
.setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)
825
.setPrettyPrintBody(true)
826
827
// Allow specific headers to be logged
828
.setAllowedHeaderNames(Set.of(
829
"x-ms-request-id",
830
"x-ms-correlation-request-id",
831
"x-ms-client-request-id",
832
"Content-Type",
833
"Accept"
834
))
835
836
// Allow specific query parameters to be logged
837
.setAllowedQueryParamNames(Set.of(
838
"api-version",
839
"timeout",
840
"$filter",
841
"$select"
842
));
843
844
return new HttpLoggingPolicy(options);
845
}
846
}
847
```
848
849
### Custom Policy Implementation
850
851
```java
852
import com.azure.core.http.policy.*;
853
import reactor.core.publisher.Mono;
854
855
public class CustomPolicyExample {
856
857
// Rate limiting policy
858
public static class RateLimitingPolicy implements HttpPipelinePolicy {
859
private final Semaphore semaphore;
860
861
public RateLimitingPolicy(int maxConcurrentRequests) {
862
this.semaphore = new Semaphore(maxConcurrentRequests);
863
}
864
865
@Override
866
public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next) {
867
return Mono.fromCallable(() -> {
868
semaphore.acquire();
869
return true;
870
})
871
.flatMap(ignored -> next.process())
872
.doFinally(signal -> semaphore.release());
873
}
874
}
875
876
// Request correlation policy
877
public static class CorrelationIdPolicy implements HttpPipelinePolicy {
878
private final String correlationIdHeader;
879
880
public CorrelationIdPolicy() {
881
this("x-correlation-id");
882
}
883
884
public CorrelationIdPolicy(String correlationIdHeader) {
885
this.correlationIdHeader = correlationIdHeader;
886
}
887
888
@Override
889
public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next) {
890
HttpRequest request = context.getHttpRequest();
891
892
// Add correlation ID if not present
893
if (request.getHeaders().getValue(correlationIdHeader) == null) {
894
String correlationId = UUID.randomUUID().toString();
895
request.setHeader(correlationIdHeader, correlationId);
896
897
// Also add to context for logging
898
context.setData("correlationId", correlationId);
899
}
900
901
return next.process();
902
}
903
}
904
905
// Circuit breaker policy
906
public static class CircuitBreakerPolicy implements HttpPipelinePolicy {
907
private volatile CircuitState state = CircuitState.CLOSED;
908
private final AtomicInteger failureCount = new AtomicInteger(0);
909
private volatile Instant lastFailureTime = Instant.MIN;
910
private final int failureThreshold;
911
private final Duration timeoutDuration;
912
913
public CircuitBreakerPolicy(int failureThreshold, Duration timeoutDuration) {
914
this.failureThreshold = failureThreshold;
915
this.timeoutDuration = timeoutDuration;
916
}
917
918
@Override
919
public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next) {
920
if (state == CircuitState.OPEN) {
921
if (Instant.now().isAfter(lastFailureTime.plus(timeoutDuration))) {
922
state = CircuitState.HALF_OPEN;
923
} else {
924
return Mono.error(new RuntimeException("Circuit breaker is OPEN"));
925
}
926
}
927
928
return next.process()
929
.doOnSuccess(response -> {
930
if (response.getStatusCode() >= 500) {
931
recordFailure();
932
} else {
933
recordSuccess();
934
}
935
})
936
.doOnError(error -> recordFailure());
937
}
938
939
private void recordFailure() {
940
failureCount.incrementAndGet();
941
lastFailureTime = Instant.now();
942
943
if (failureCount.get() >= failureThreshold) {
944
state = CircuitState.OPEN;
945
}
946
}
947
948
private void recordSuccess() {
949
failureCount.set(0);
950
state = CircuitState.CLOSED;
951
}
952
953
enum CircuitState {
954
CLOSED, OPEN, HALF_OPEN
955
}
956
}
957
}
958
```
959
960
### Policy Provider Implementation
961
962
```java
963
import com.azure.core.http.policy.*;
964
import java.util.List;
965
966
public class CustomPolicyProviderExample {
967
968
// Before retry policy provider
969
public static class SecurityPolicyProvider implements BeforeRetryPolicyProvider {
970
@Override
971
public List<HttpPipelinePolicy> getPolicies() {
972
return List.of(
973
new CustomPolicyExample.CorrelationIdPolicy(),
974
new RequestIdPolicy(),
975
new AddHeadersPolicy(new HttpHeaders()
976
.put("X-Security-Token", "security-header-value")
977
.put("X-Client-Version", "1.0.0"))
978
);
979
}
980
}
981
982
// After retry policy provider
983
public static class InstrumentationPolicyProvider implements AfterRetryPolicyProvider {
984
@Override
985
public List<HttpPipelinePolicy> getPolicies() {
986
return List.of(
987
new HttpLoggingPolicy(new HttpLogOptions()
988
.setLogLevel(HttpLogDetailLevel.BASIC)),
989
new CustomPolicyExample.RateLimitingPolicy(10),
990
new TimeoutPolicy(Duration.ofSeconds(30))
991
);
992
}
993
}
994
995
// Usage with policy providers
996
public void setupPipelineWithProviders() {
997
// Register policy providers
998
HttpPolicyProviders.addBeforeRetryPolicyProvider(new SecurityPolicyProvider());
999
HttpPolicyProviders.addAfterRetryPolicyProvider(new InstrumentationPolicyProvider());
1000
1001
// Create pipeline - providers will be automatically included
1002
HttpPipeline pipeline = new HttpPipelineBuilder()
1003
.httpClient(HttpClient.createDefault())
1004
.policies(
1005
new UserAgentPolicy("MyApp/1.0"),
1006
new BearerTokenAuthenticationPolicy(credential, scopes),
1007
new RetryPolicy()
1008
)
1009
.build();
1010
}
1011
}
1012
```
1013
1014
### Policy Ordering and Coordination
1015
1016
```java
1017
import com.azure.core.http.policy.*;
1018
1019
public class PolicyOrderingExample {
1020
1021
public HttpPipeline createWellOrderedPipeline() {
1022
return new HttpPipelineBuilder()
1023
.httpClient(HttpClient.createDefault())
1024
.policies(
1025
// 1. Request preparation policies (should be first)
1026
new UserAgentPolicy("MyApp/1.0"),
1027
new RequestIdPolicy(),
1028
new AddDatePolicy(),
1029
new ProtocolPolicy(),
1030
new HostPolicy(),
1031
new PortPolicy(),
1032
1033
// 2. Request modification policies
1034
new AddHeadersPolicy(createCommonHeaders()),
1035
new AddHeadersFromContextPolicy(),
1036
1037
// 3. Authentication policies (before retry so failed auth doesn't get retried unnecessarily)
1038
new BearerTokenAuthenticationPolicy(credential, scopes),
1039
1040
// 4. Before retry policies (custom policies that should run before retry)
1041
new CustomPolicyExample.CorrelationIdPolicy(),
1042
new CustomPolicyExample.CircuitBreakerPolicy(5, Duration.ofMinutes(1)),
1043
1044
// 5. Retry policy (central retry logic)
1045
new RetryPolicy(new RetryOptions()
1046
.setMaxRetries(3)
1047
.setDelay(Duration.ofSeconds(1))),
1048
1049
// 6. After retry policies
1050
new CustomPolicyExample.RateLimitingPolicy(20),
1051
new TimeoutPolicy(Duration.ofSeconds(60)),
1052
1053
// 7. Response handling policies
1054
new RedirectPolicy(new DefaultRedirectStrategy(5)),
1055
new CookiePolicy(),
1056
1057
// 8. Logging policy (should be last to capture the final request/response)
1058
new HttpLoggingPolicy(new HttpLogOptions()
1059
.setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS))
1060
)
1061
.build();
1062
}
1063
1064
private HttpHeaders createCommonHeaders() {
1065
return new HttpHeaders()
1066
.put("Accept", "application/json")
1067
.put("Content-Type", "application/json")
1068
.put("X-Client-Name", "MyApplication");
1069
}
1070
}
1071
```