diff --git a/applicationconfig/client/src/main/java/com/azure/applicationconfig/ConfigurationAsyncClientBuilder.java b/applicationconfig/client/src/main/java/com/azure/applicationconfig/ConfigurationAsyncClientBuilder.java index e62d7d827c02..bb81b576bf7a 100644 --- a/applicationconfig/client/src/main/java/com/azure/applicationconfig/ConfigurationAsyncClientBuilder.java +++ b/applicationconfig/client/src/main/java/com/azure/applicationconfig/ConfigurationAsyncClientBuilder.java @@ -128,9 +128,10 @@ public ConfigurationAsyncClient build() { policies.add(new HttpLoggingPolicy(httpLogDetailLevel)); - HttpPipeline pipeline = httpClient == null - ? new HttpPipeline(policies) - : new HttpPipeline(httpClient, policies); + HttpPipeline pipeline = HttpPipeline.builder() + .policies(policies.toArray(new HttpPipelinePolicy[0])) + .httpClient(httpClient) + .build(); return new ConfigurationAsyncClient(serviceEndpoint, pipeline); } diff --git a/core/azure-core-management/src/main/java/com/azure/core/management/AzureProxy.java b/core/azure-core-management/src/main/java/com/azure/core/management/AzureProxy.java index a8440d1bcae2..5e0adaf16e48 100644 --- a/core/azure-core-management/src/main/java/com/azure/core/management/AzureProxy.java +++ b/core/azure-core-management/src/main/java/com/azure/core/management/AzureProxy.java @@ -192,14 +192,17 @@ public static HttpPipeline createDefaultPipeline(Class swaggerInterface, Asyn public static HttpPipeline createDefaultPipeline(Class swaggerInterface, HttpPipelinePolicy credentialsPolicy) { // Order in which policies applied will be the order in which they appear in the array // - List policies = new ArrayList(); + List policies = new ArrayList<>(); policies.add(new UserAgentPolicy(getDefaultUserAgentString(swaggerInterface))); policies.add(new RetryPolicy()); policies.add(new CookiePolicy()); if (credentialsPolicy != null) { policies.add(credentialsPolicy); } - return new HttpPipeline(policies.toArray(new HttpPipelinePolicy[policies.size()])); + + return HttpPipeline.builder() + .policies(policies.toArray(new HttpPipelinePolicy[0])) + .build(); } /** diff --git a/core/azure-core-management/src/test/java/com/azure/core/management/AzureProxyTests.java b/core/azure-core-management/src/test/java/com/azure/core/management/AzureProxyTests.java index dd275d21bce6..d75f53894eee 100644 --- a/core/azure-core-management/src/test/java/com/azure/core/management/AzureProxyTests.java +++ b/core/azure-core-management/src/test/java/com/azure/core/management/AzureProxyTests.java @@ -850,7 +850,9 @@ public Mono send(HttpRequest request) { } private static T createMockService(Class serviceClass, MockAzureHttpClient httpClient) { - HttpPipeline pipeline = new HttpPipeline(httpClient); + HttpPipeline pipeline = HttpPipeline.builder() + .httpClient(httpClient) + .build(); return AzureProxy.create(serviceClass, null, pipeline, SERIALIZER); } diff --git a/core/azure-core-management/src/test/java/com/azure/core/management/AzureProxyToRestProxyTests.java b/core/azure-core-management/src/test/java/com/azure/core/management/AzureProxyToRestProxyTests.java index 2ab4376459b0..a5826149f8cb 100644 --- a/core/azure-core-management/src/test/java/com/azure/core/management/AzureProxyToRestProxyTests.java +++ b/core/azure-core-management/src/test/java/com/azure/core/management/AzureProxyToRestProxyTests.java @@ -745,7 +745,9 @@ public void service18GetStatus500WithExpectedResponse500() { } private T createService(Class serviceClass) { - HttpPipeline pipeline = new HttpPipeline(createHttpClient()); + HttpPipeline pipeline = HttpPipeline.builder() + .httpClient(createHttpClient()) + .build(); // return AzureProxy.create(serviceClass, null, pipeline, SERIALIZER); } diff --git a/core/azure-core/src/main/java/com/azure/core/http/HttpPipeline.java b/core/azure-core/src/main/java/com/azure/core/http/HttpPipeline.java index 052e59f49b98..7ee93824740a 100644 --- a/core/azure-core/src/main/java/com/azure/core/http/HttpPipeline.java +++ b/core/azure-core/src/main/java/com/azure/core/http/HttpPipeline.java @@ -3,11 +3,10 @@ package com.azure.core.http; -import com.azure.core.util.Context; import com.azure.core.http.policy.HttpPipelinePolicy; +import com.azure.core.util.Context; import reactor.core.publisher.Mono; -import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -18,35 +17,14 @@ public final class HttpPipeline { private final HttpClient httpClient; private final HttpPipelinePolicy[] pipelinePolicies; - /** - * Creates a HttpPipeline holding array of policies that gets applied to all request initiated through - * {@link HttpPipeline#send(HttpPipelineCallContext)} and it's response. - * - * @param httpClient the http client to write request to wire and receive response from wire. - * @param pipelinePolicies pipeline policies in the order they need to applied, a copy of this array will - * be made hence changing the original array after the creation of pipeline - * will not mutate the pipeline - */ - public HttpPipeline(HttpClient httpClient, HttpPipelinePolicy... pipelinePolicies) { - Objects.requireNonNull(httpClient); - Objects.requireNonNull(pipelinePolicies); - this.pipelinePolicies = Arrays.copyOf(pipelinePolicies, pipelinePolicies.length); - this.httpClient = httpClient; - } /** - * Creates a HttpPipeline holding array of policies that gets applied all request initiated through - * {@link HttpPipeline#send(HttpPipelineCallContext)} and it's response. + * Creates a builder that can configure options for the HttpPipeline before creating an instance of it. * - * The default HttpClient {@link HttpClient#createDefault()} will be used to write request to wire and - * receive response from wire. - * - * @param pipelinePolicies pipeline policies in the order they need to applied, a copy of this array will - * be made hence changing the original array after the creation of pipeline - * will not mutate the pipeline + * @return A new {@link HttpPipelineBuilder} to create a HttpPipeline from. */ - public HttpPipeline(HttpPipelinePolicy... pipelinePolicies) { - this(HttpClient.createDefault(), pipelinePolicies); + public static HttpPipelineBuilder builder() { + return new HttpPipelineBuilder(); } /** @@ -54,39 +32,32 @@ public HttpPipeline(HttpPipelinePolicy... pipelinePolicies) { * {@link HttpPipeline#send(HttpPipelineCallContext)} and it's response. * * @param httpClient the http client to write request to wire and receive response from wire. - * @param pipelinePolicies pipeline policies in the order they need to applied, a copy of this list - * will be made so changing the original list after the creation of pipeline - * will not mutate the pipeline + * @param pipelinePolicies pipeline policies in the order they need to applied, a copy of this array will + * be made hence changing the original array after the creation of pipeline + * will not mutate the pipeline */ - public HttpPipeline(HttpClient httpClient, List pipelinePolicies) { + HttpPipeline(HttpClient httpClient, List pipelinePolicies) { Objects.requireNonNull(httpClient); Objects.requireNonNull(pipelinePolicies); - this.pipelinePolicies = pipelinePolicies.toArray(new HttpPipelinePolicy[0]); this.httpClient = httpClient; + this.pipelinePolicies = pipelinePolicies.toArray(new HttpPipelinePolicy[0]); } /** - * Creates a HttpPipeline holding array of policies that gets applied all request initiated through - * {@link HttpPipeline#send(HttpPipelineCallContext)} and it's response. - * - * The default HttpClient {@link HttpClient#createDefault()} will be used to write request to wire and - * receive response from wire. - * - * @param pipelinePolicies pipeline policies in the order they need to applied, a copy of this list - * will be made so changing the original list after the creation of pipeline - * will not mutate the pipeline + * Get the policy at the passed index in the pipeline. + * @param index index of the the policy to retrieve. + * @return the policy stored at that index. */ - public HttpPipeline(List pipelinePolicies) { - this(HttpClient.createDefault(), pipelinePolicies); + public HttpPipelinePolicy getPolicy(final int index) { + return this.pipelinePolicies[index]; } /** - * Get the policies in the pipeline. - * - * @return policies in the pipeline + * Get the count of policies in the pipeline. + * @return count of policies. */ - public HttpPipelinePolicy[] pipelinePolicies() { - return Arrays.copyOf(this.pipelinePolicies, this.pipelinePolicies.length); + public int getPolicyCount() { + return this.pipelinePolicies.length; } /** @@ -99,34 +70,23 @@ public HttpClient httpClient() { } /** - * Creates a new context local to the provided http request. - * - * @param httpRequest the request for a context needs to be created - * @return the request context - */ - public HttpPipelineCallContext newContext(HttpRequest httpRequest) { - return new HttpPipelineCallContext(httpRequest); - } - - /** - * Creates a new context local to the provided http request. + * Wraps the request in a context and send it through pipeline. * - * @param httpRequest the request for a context needs to be created - * @param data the data to associate with the context - * @return the request context + * @param request the request + * @return a publisher upon subscription flows the context through policies, sends the request and emits response upon completion */ - public HttpPipelineCallContext newContext(HttpRequest httpRequest, Context data) { - return new HttpPipelineCallContext(httpRequest, data); + public Mono send(HttpRequest request) { + return this.send(new HttpPipelineCallContext(request)); } /** - * Wraps the request in a context and send it through pipeline. - * + * Wraps the request in a context with additional metadata and sends it through the pipeline. * @param request the request + * @param data additional metadata to pass along in the request * @return a publisher upon subscription flows the context through policies, sends the request and emits response upon completion */ - public Mono send(HttpRequest request) { - return this.send(this.newContext(request)); + public Mono send(HttpRequest request, Context data) { + return this.send(new HttpPipelineCallContext(request, data)); } /** diff --git a/core/azure-core/src/main/java/com/azure/core/http/HttpPipelineBuilder.java b/core/azure-core/src/main/java/com/azure/core/http/HttpPipelineBuilder.java new file mode 100644 index 000000000000..14f7f6ab53e5 --- /dev/null +++ b/core/azure-core/src/main/java/com/azure/core/http/HttpPipelineBuilder.java @@ -0,0 +1,88 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.core.http; + +import com.azure.core.http.policy.HttpPipelinePolicy; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * This class provides a fluent builder API to help aid the configuration and instantiation of the {@link HttpPipeline}, + * calling {@link HttpPipelineBuilder#build() build} constructs an instance of the pipeline. + * + *

A pipeline is configured with a HttpClient that sends the request, if no client is set a default is used. + * A pipeline may be configured with a list of policies that are applied to each request.

+ * + *

Code Samples

+ * + *

Create a pipeline without configuration

+ * + *
+ * HttpPipeline.builder()
+ *     .build();
+ * 
+ * + *

Create a pipeline using the default HTTP client and a retry policy

+ * + *
+ * HttpPipeline.builder()
+ *     .httpClient(HttpClient.createDefault())
+ *     .policies(new RetryPolicy())
+ *     .build();
+ * 
+ * + * @see HttpPipeline + */ +public class HttpPipelineBuilder { + private HttpClient httpClient; + private List pipelinePolicies; + + + HttpPipelineBuilder() { + } + + /** + * Creates a {@link HttpPipeline} based on options set in the Builder. Every time {@code build()} is + * called, a new instance of {@link HttpPipeline} is created. + * + * If HttpClient is not set then the {@link HttpClient#createDefault() default HttpClient} is used. + * + * @return A HttpPipeline with the options set from the builder. + */ + public HttpPipeline build() { + List policies = (pipelinePolicies == null) ? new ArrayList<>() : pipelinePolicies; + HttpClient client = (httpClient == null) ? HttpClient.createDefault() : httpClient; + + return new HttpPipeline(client, policies); + } + + /** + * Sets the HttpClient that the pipeline will use to send requests. + * + * @param httpClient The HttpClient the pipeline will use when sending requests. + * @return The updated HttpPipelineBuilder object. + */ + public HttpPipelineBuilder httpClient(HttpClient httpClient) { + this.httpClient = httpClient; + return this; + } + + /** + * Adds {@link HttpPipelinePolicy policies} to the set of policies that the pipeline will use + * when sending requests. + * + * @param policies Policies to add to the policy set. + * @return The updated HttpPipelineBuilder object. + */ + public HttpPipelineBuilder policies(HttpPipelinePolicy... policies) { + if (pipelinePolicies == null) { + pipelinePolicies = new ArrayList<>(); + } + + this.pipelinePolicies.addAll(Arrays.asList(policies)); + return this; + } +} diff --git a/core/azure-core/src/main/java/com/azure/core/http/HttpPipelineNextPolicy.java b/core/azure-core/src/main/java/com/azure/core/http/HttpPipelineNextPolicy.java index c56e2c833465..9d7a54e1792d 100644 --- a/core/azure-core/src/main/java/com/azure/core/http/HttpPipelineNextPolicy.java +++ b/core/azure-core/src/main/java/com/azure/core/http/HttpPipelineNextPolicy.java @@ -34,16 +34,16 @@ public class HttpPipelineNextPolicy { * @return a publisher upon subscription invokes next policy and emits response from the policy. */ public Mono process() { - final int size = this.pipeline.pipelinePolicies().length; + final int size = this.pipeline.getPolicyCount(); if (this.currentPolicyIndex > size) { return Mono.error(new IllegalStateException("There is no more policies to execute.")); + } + + this.currentPolicyIndex++; + if (this.currentPolicyIndex == size) { + return this.pipeline.httpClient().send(this.context.httpRequest()); } else { - this.currentPolicyIndex++; - if (this.currentPolicyIndex == size) { - return this.pipeline.httpClient().send(this.context.httpRequest()); - } else { - return this.pipeline.pipelinePolicies()[this.currentPolicyIndex].process(this.context, this); - } + return this.pipeline.getPolicy(this.currentPolicyIndex).process(this.context, this); } } diff --git a/core/azure-core/src/main/java/com/azure/core/implementation/RestProxy.java b/core/azure-core/src/main/java/com/azure/core/implementation/RestProxy.java index 00578b9f67e2..80c8b4b248d0 100644 --- a/core/azure-core/src/main/java/com/azure/core/implementation/RestProxy.java +++ b/core/azure-core/src/main/java/com/azure/core/implementation/RestProxy.java @@ -7,7 +7,6 @@ import com.azure.core.annotations.ResumeOperation; import com.azure.core.credentials.ServiceClientCredentials; import com.azure.core.exception.HttpRequestException; -import com.azure.core.util.Context; import com.azure.core.http.HttpHeader; import com.azure.core.http.HttpHeaders; import com.azure.core.http.HttpMethod; @@ -34,6 +33,7 @@ import com.azure.core.implementation.util.FluxUtil; import com.azure.core.implementation.util.ImplUtils; import com.azure.core.implementation.util.TypeUtil; +import com.azure.core.util.Context; import io.netty.buffer.ByteBuf; import reactor.core.Exceptions; import reactor.core.publisher.Flux; @@ -112,7 +112,7 @@ public SerializerAdapter serializer() { * @return a {@link Mono} that emits HttpResponse asynchronously */ public Mono send(HttpRequest request, Context contextData) { - return httpPipeline.send(httpPipeline.newContext(request, contextData)); + return httpPipeline.send(request, contextData); } @Override @@ -558,7 +558,10 @@ public static HttpPipeline createDefaultPipeline(HttpPipelinePolicy credentialsP if (credentialsPolicy != null) { policies.add(credentialsPolicy); } - return new HttpPipeline(policies.toArray(new HttpPipelinePolicy[policies.size()])); + + return HttpPipeline.builder() + .policies(policies.toArray(new HttpPipelinePolicy[0])) + .build(); } /** diff --git a/core/azure-core/src/test/java/com/azure/core/CredentialsTests.java b/core/azure-core/src/test/java/com/azure/core/CredentialsTests.java index 1b0c1c1c19ac..933dcf64ac2f 100644 --- a/core/azure-core/src/test/java/com/azure/core/CredentialsTests.java +++ b/core/azure-core/src/test/java/com/azure/core/CredentialsTests.java @@ -28,9 +28,10 @@ public void basicCredentialsTest() throws Exception { return next.process(); }; // - final HttpPipeline pipeline = new HttpPipeline(new MockHttpClient(), - new CredentialsPolicy(credentials), - auditorPolicy); + final HttpPipeline pipeline = HttpPipeline.builder() + .httpClient(new MockHttpClient()) + .policies(new CredentialsPolicy(credentials), auditorPolicy) + .build(); HttpRequest request = new HttpRequest(HttpMethod.GET, new URL("http://localhost")); @@ -47,9 +48,10 @@ public void tokenCredentialsTest() throws Exception { return next.process(); }; - final HttpPipeline pipeline = new HttpPipeline(new MockHttpClient(), - new CredentialsPolicy(credentials), - auditorPolicy); + final HttpPipeline pipeline = HttpPipeline.builder() + .httpClient(new MockHttpClient()) + .policies(new CredentialsPolicy(credentials), auditorPolicy) + .build(); HttpRequest request = new HttpRequest(HttpMethod.GET, new URL("http://localhost")); pipeline.send(request).block(); diff --git a/core/azure-core/src/test/java/com/azure/core/UserAgentTests.java b/core/azure-core/src/test/java/com/azure/core/UserAgentTests.java index 86ba18720c4a..404631e808c4 100644 --- a/core/azure-core/src/test/java/com/azure/core/UserAgentTests.java +++ b/core/azure-core/src/test/java/com/azure/core/UserAgentTests.java @@ -19,7 +19,8 @@ public class UserAgentTests { @Test public void defaultUserAgentTests() throws Exception { - final HttpPipeline pipeline = new HttpPipeline(new MockHttpClient() { + final HttpPipeline pipeline = HttpPipeline.builder() + .httpClient(new MockHttpClient() { @Override public Mono send(HttpRequest request) { Assert.assertEquals( @@ -27,8 +28,9 @@ public Mono send(HttpRequest request) { "AutoRest-Java"); return Mono.just(new MockHttpResponse(request, 200)); } - }, - new UserAgentPolicy("AutoRest-Java")); + }) + .policies(new UserAgentPolicy("AutoRest-Java")) + .build(); HttpResponse response = pipeline.send(new HttpRequest( HttpMethod.GET, new URL("http://localhost"))).block(); @@ -38,15 +40,17 @@ public Mono send(HttpRequest request) { @Test public void customUserAgentTests() throws Exception { - final HttpPipeline pipeline = new HttpPipeline(new MockHttpClient() { - @Override + final HttpPipeline pipeline = HttpPipeline.builder() + .httpClient(new MockHttpClient() { + @Override public Mono send(HttpRequest request) { String header = request.headers().value("User-Agent"); Assert.assertEquals("Awesome", header); return Mono.just(new MockHttpResponse(request, 200)); } - }, - new UserAgentPolicy("Awesome")); + }) + .policies(new UserAgentPolicy("Awesome")) + .build(); HttpResponse response = pipeline.send(new HttpRequest(HttpMethod.GET, new URL("http://localhost"))).block(); diff --git a/core/azure-core/src/test/java/com/azure/core/http/HttpPipelineTests.java b/core/azure-core/src/test/java/com/azure/core/http/HttpPipelineTests.java index 9561cdd6f79e..07f2e164317e 100644 --- a/core/azure-core/src/test/java/com/azure/core/http/HttpPipelineTests.java +++ b/core/azure-core/src/test/java/com/azure/core/http/HttpPipelineTests.java @@ -23,33 +23,37 @@ public class HttpPipelineTests { @Test public void constructorWithNoArguments() { - HttpPipeline pipeline = new HttpPipeline(); - assertEquals(0, pipeline.pipelinePolicies().length); + HttpPipeline pipeline = HttpPipeline.builder().build(); + assertEquals(0, pipeline.getPolicyCount()); assertNotNull(pipeline.httpClient()); assertTrue(pipeline.httpClient() instanceof ReactorNettyClient); } @Test public void withRequestPolicy() { - HttpPipeline pipeline = new HttpPipeline(new PortPolicy(80, true), + HttpPipeline pipeline = HttpPipeline.builder() + .policies(new PortPolicy(80, true), new ProtocolPolicy("ftp", true), - new RetryPolicy()); + new RetryPolicy()) + .build(); - assertEquals(3, pipeline.pipelinePolicies().length); - assertEquals(PortPolicy.class, pipeline.pipelinePolicies()[0].getClass()); - assertEquals(ProtocolPolicy.class, pipeline.pipelinePolicies()[1].getClass()); - assertEquals(RetryPolicy.class, pipeline.pipelinePolicies()[2].getClass()); + assertEquals(3, pipeline.getPolicyCount()); + assertEquals(PortPolicy.class, pipeline.getPolicy(0).getClass()); + assertEquals(ProtocolPolicy.class, pipeline.getPolicy(1).getClass()); + assertEquals(RetryPolicy.class, pipeline.getPolicy(2).getClass()); assertNotNull(pipeline.httpClient()); assertTrue(pipeline.httpClient() instanceof ReactorNettyClient); } @Test public void withRequestOptions() throws MalformedURLException { - HttpPipeline pipeline = new HttpPipeline(new PortPolicy(80, true), + HttpPipeline pipeline = HttpPipeline.builder() + .policies(new PortPolicy(80, true), new ProtocolPolicy("ftp", true), - new RetryPolicy()); + new RetryPolicy()) + .build(); - HttpPipelineCallContext context = pipeline.newContext(new HttpRequest(HttpMethod.GET, new URL("http://foo.com"))); + HttpPipelineCallContext context = new HttpPipelineCallContext(new HttpRequest(HttpMethod.GET, new URL("http://foo.com"))); assertNotNull(context); assertNotNull(pipeline.httpClient()); assertTrue(pipeline.httpClient() instanceof ReactorNettyClient); @@ -59,15 +63,17 @@ public void withRequestOptions() throws MalformedURLException { public void withNoRequestPolicies() throws MalformedURLException { final HttpMethod expectedHttpMethod = HttpMethod.GET; final URL expectedUrl = new URL("http://my.site.com"); - final HttpPipeline httpPipeline = new HttpPipeline(new MockHttpClient() { - @Override - public Mono send(HttpRequest request) { - assertEquals(0, request.headers().size()); - assertEquals(expectedHttpMethod, request.httpMethod()); - assertEquals(expectedUrl, request.url()); - return Mono.just(new MockHttpResponse(request, 200)); - } - }); + final HttpPipeline httpPipeline = HttpPipeline.builder() + .httpClient(new MockHttpClient() { + @Override + public Mono send(HttpRequest request) { + assertEquals(0, request.headers().size()); + assertEquals(expectedHttpMethod, request.httpMethod()); + assertEquals(expectedUrl, request.url()); + return Mono.just(new MockHttpResponse(request, 200)); + } + }) + .build(); final HttpResponse response = httpPipeline.send(new HttpRequest(expectedHttpMethod, expectedUrl)).block(); assertNotNull(response); @@ -90,8 +96,10 @@ public Mono send(HttpRequest request) { } }; - final HttpPipeline httpPipeline = new HttpPipeline(httpClient, - new UserAgentPolicy(expectedUserAgent)); + final HttpPipeline httpPipeline = HttpPipeline.builder() + .httpClient(httpClient) + .policies(new UserAgentPolicy(expectedUserAgent)) + .build(); final HttpResponse response = httpPipeline.send(new HttpRequest(expectedHttpMethod, expectedUrl)).block(); assertNotNull(response); @@ -102,7 +110,8 @@ public Mono send(HttpRequest request) { public void withRequestIdRequestPolicy() throws MalformedURLException { final HttpMethod expectedHttpMethod = HttpMethod.GET; final URL expectedUrl = new URL("http://my.site.com/1"); - final HttpPipeline httpPipeline = new HttpPipeline(new MockHttpClient() { + final HttpPipeline httpPipeline = HttpPipeline.builder() + .httpClient(new MockHttpClient() { @Override public Mono send(HttpRequest request) { assertEquals(1, request.headers().size()); @@ -114,8 +123,9 @@ public Mono send(HttpRequest request) { assertEquals(expectedUrl, request.url()); return Mono.just(new MockHttpResponse(request, 200)); } - }, - new RequestIdPolicy()); + }) + .policies(new RequestIdPolicy()) + .build(); final HttpResponse response = httpPipeline.send(new HttpRequest(expectedHttpMethod, expectedUrl)).block(); assertNotNull(response); diff --git a/core/azure-core/src/test/java/com/azure/core/http/policy/HostPolicyTests.java b/core/azure-core/src/test/java/com/azure/core/http/policy/HostPolicyTests.java index 1feec4572b12..8c209c4817c1 100644 --- a/core/azure-core/src/test/java/com/azure/core/http/policy/HostPolicyTests.java +++ b/core/azure-core/src/test/java/com/azure/core/http/policy/HostPolicyTests.java @@ -32,27 +32,26 @@ public void withPort() throws MalformedURLException { } private static HttpPipeline createPipeline(String host, String expectedUrl) { - return new HttpPipeline(new MockHttpClient() { - @Override - public Mono send(HttpRequest request) { - return Mono.empty(); // NOP - } - }, - new HostPolicy(host), - (context, next) -> { - assertEquals(expectedUrl, context.httpRequest().url().toString()); - return next.process(); - }); + return HttpPipeline.builder() + .httpClient(new MockHttpClient()) + .policies(new HostPolicy(host), + (context, next) -> { + assertEquals(expectedUrl, context.httpRequest().url().toString()); + return next.process(); + }) + .build(); } private static HttpRequest createHttpRequest(String url) throws MalformedURLException { return new HttpRequest(HttpMethod.GET, new URL(url)); } - private abstract static class MockHttpClient implements HttpClient { + private static class MockHttpClient implements HttpClient { @Override - public abstract Mono send(HttpRequest request); + public Mono send(HttpRequest request) { + return Mono.empty(); // NOP + } @Override public HttpClient proxy(Supplier proxyOptions) { diff --git a/core/azure-core/src/test/java/com/azure/core/http/policy/ProtocolPolicyTests.java b/core/azure-core/src/test/java/com/azure/core/http/policy/ProtocolPolicyTests.java index 9f0c11807d6b..c581c598b71a 100644 --- a/core/azure-core/src/test/java/com/azure/core/http/policy/ProtocolPolicyTests.java +++ b/core/azure-core/src/test/java/com/azure/core/http/policy/ProtocolPolicyTests.java @@ -32,41 +32,37 @@ public void withNoOverwrite() throws MalformedURLException { pipeline.send(createHttpRequest("https://www.bing.com")); } private static HttpPipeline createPipeline(String protocol, String expectedUrl) { - return new HttpPipeline(new MockHttpClient() { - @Override - public Mono send(HttpRequest request) { - return Mono.empty(); // NOP - } - }, - new ProtocolPolicy(protocol, true), - (context, next) -> { - assertEquals(expectedUrl, context.httpRequest().url().toString()); - return next.process(); - }); + return HttpPipeline.builder() + .httpClient(new MockHttpClient()) + .policies(new ProtocolPolicy(protocol, true), + (context, next) -> { + assertEquals(expectedUrl, context.httpRequest().url().toString()); + return next.process(); + }) + .build(); } private static HttpPipeline createPipeline(String protocol, boolean overwrite, String expectedUrl) { - return new HttpPipeline(new MockHttpClient() { - @Override - public Mono send(HttpRequest request) { - return Mono.empty(); // NOP - } - }, - new ProtocolPolicy(protocol, overwrite), - (context, next) -> { - assertEquals(expectedUrl, context.httpRequest().url().toString()); - return next.process(); - }); + return HttpPipeline.builder() + .httpClient(new MockHttpClient()) + .policies(new ProtocolPolicy(protocol, overwrite), + (context, next) -> { + assertEquals(expectedUrl, context.httpRequest().url().toString()); + return next.process(); + }) + .build(); } private static HttpRequest createHttpRequest(String url) throws MalformedURLException { return new HttpRequest(HttpMethod.GET, new URL(url)); } - private abstract static class MockHttpClient implements HttpClient { + private static class MockHttpClient implements HttpClient { @Override - public abstract Mono send(HttpRequest request); + public Mono send(HttpRequest request) { + return Mono.empty(); + } @Override public HttpClient proxy(Supplier proxyOptions) { diff --git a/core/azure-core/src/test/java/com/azure/core/http/policy/ProxyAuthenticationPolicyTests.java b/core/azure-core/src/test/java/com/azure/core/http/policy/ProxyAuthenticationPolicyTests.java index 1b6369793df5..2832ab41e820 100644 --- a/core/azure-core/src/test/java/com/azure/core/http/policy/ProxyAuthenticationPolicyTests.java +++ b/core/azure-core/src/test/java/com/azure/core/http/policy/ProxyAuthenticationPolicyTests.java @@ -23,13 +23,15 @@ public void test() throws MalformedURLException { final String username = "testuser"; final String password = "testpass"; // - final HttpPipeline pipeline = new HttpPipeline(new MockHttpClient(), - new ProxyAuthenticationPolicy(username, password), - (context, next) -> { - assertEquals("Basic dGVzdHVzZXI6dGVzdHBhc3M=", context.httpRequest().headers().value("Proxy-Authentication")); - auditorVisited.set(true); - return next.process(); - }); + final HttpPipeline pipeline = HttpPipeline.builder() + .httpClient(new MockHttpClient()) + .policies(new ProxyAuthenticationPolicy(username, password), + (context, next) -> { + assertEquals("Basic dGVzdHVzZXI6dGVzdHBhc3M=", context.httpRequest().headers().value("Proxy-Authentication")); + auditorVisited.set(true); + return next.process(); + }) + .build(); pipeline.send(new HttpRequest(HttpMethod.GET, new URL("http://localhost"))) .block(); diff --git a/core/azure-core/src/test/java/com/azure/core/http/policy/RequestIdPolicyTests.java b/core/azure-core/src/test/java/com/azure/core/http/policy/RequestIdPolicyTests.java index f67e324b2de0..e044f7d1ea5b 100644 --- a/core/azure-core/src/test/java/com/azure/core/http/policy/RequestIdPolicyTests.java +++ b/core/azure-core/src/test/java/com/azure/core/http/policy/RequestIdPolicyTests.java @@ -62,23 +62,26 @@ public Mono bodyAsString(Charset charset) { @Test public void newRequestIdForEachCall() throws Exception { - HttpPipeline pipeline = new HttpPipeline(new MockHttpClient() { - String firstRequestId = null; - @Override - public Mono send(HttpRequest request) { - if (firstRequestId != null) { - String newRequestId = request.headers().value(REQUEST_ID_HEADER); - Assert.assertNotNull(newRequestId); - Assert.assertNotEquals(newRequestId, firstRequestId); + HttpPipeline pipeline = HttpPipeline.builder() + .httpClient(new MockHttpClient() { + String firstRequestId = null; + @Override + public Mono send(HttpRequest request) { + if (firstRequestId != null) { + String newRequestId = request.headers().value(REQUEST_ID_HEADER); + Assert.assertNotNull(newRequestId); + Assert.assertNotEquals(newRequestId, firstRequestId); + } + + firstRequestId = request.headers().value(REQUEST_ID_HEADER); + if (firstRequestId == null) { + Assert.fail(); + } + return Mono.just(mockResponse); } - - firstRequestId = request.headers().value(REQUEST_ID_HEADER); - if (firstRequestId == null) { - Assert.fail(); - } - return Mono.just(mockResponse); - } - }, new RequestIdPolicy()); + }) + .policies(new RequestIdPolicy()) + .build(); pipeline.send(new HttpRequest(HttpMethod.GET, new URL("http://localhost/"))).block(); pipeline.send(new HttpRequest(HttpMethod.GET, new URL("http://localhost/"))).block(); @@ -86,25 +89,26 @@ public Mono send(HttpRequest request) { @Test public void sameRequestIdForRetry() throws Exception { - final HttpPipeline pipeline = new HttpPipeline(new MockHttpClient() { - String firstRequestId = null; - - @Override - public Mono send(HttpRequest request) { - if (firstRequestId != null) { - String newRequestId = request.headers().value(REQUEST_ID_HEADER); - Assert.assertNotNull(newRequestId); - Assert.assertEquals(newRequestId, firstRequestId); - } - firstRequestId = request.headers().value(REQUEST_ID_HEADER); - if (firstRequestId == null) { - Assert.fail(); + final HttpPipeline pipeline = HttpPipeline.builder() + .httpClient(new MockHttpClient() { + String firstRequestId = null; + + @Override + public Mono send(HttpRequest request) { + if (firstRequestId != null) { + String newRequestId = request.headers().value(REQUEST_ID_HEADER); + Assert.assertNotNull(newRequestId); + Assert.assertEquals(newRequestId, firstRequestId); + } + firstRequestId = request.headers().value(REQUEST_ID_HEADER); + if (firstRequestId == null) { + Assert.fail(); + } + return Mono.just(mockResponse); } - return Mono.just(mockResponse); - } - }, - new RequestIdPolicy(), - new RetryPolicy(1, Duration.of(0, ChronoUnit.SECONDS))); + }) + .policies(new RequestIdPolicy(), new RetryPolicy(1, Duration.of(0, ChronoUnit.SECONDS))) + .build(); pipeline.send(new HttpRequest(HttpMethod.GET, new URL("http://localhost/"))).block(); } diff --git a/core/azure-core/src/test/java/com/azure/core/http/policy/RetryPolicyTests.java b/core/azure-core/src/test/java/com/azure/core/http/policy/RetryPolicyTests.java index f2ee21cfabca..7a20532fa07c 100644 --- a/core/azure-core/src/test/java/com/azure/core/http/policy/RetryPolicyTests.java +++ b/core/azure-core/src/test/java/com/azure/core/http/policy/RetryPolicyTests.java @@ -20,16 +20,19 @@ public class RetryPolicyTests { @Test public void exponentialRetryEndOn501() throws Exception { - final HttpPipeline pipeline = new HttpPipeline(new MockHttpClient() { - // Send 408, 500, 502, all retried, with a 501 ending - private final int[] codes = new int[]{408, 500, 502, 501}; - private int count = 0; + final HttpPipeline pipeline = HttpPipeline.builder() + .httpClient(new MockHttpClient() { + // Send 408, 500, 502, all retried, with a 501 ending + private final int[] codes = new int[]{408, 500, 502, 501}; + private int count = 0; - @Override - public Mono send(HttpRequest request) { - return Mono.just(new MockHttpResponse(request, codes[count++])); - } - }, new RetryPolicy(3, Duration.of(0, ChronoUnit.MILLIS))); + @Override + public Mono send(HttpRequest request) { + return Mono.just(new MockHttpResponse(request, codes[count++])); + } + }) + .policies(new RetryPolicy(3, Duration.of(0, ChronoUnit.MILLIS))) + .build(); HttpResponse response = pipeline.send(new HttpRequest(HttpMethod.GET, new URL("http://localhost/"))).block(); @@ -40,16 +43,18 @@ public Mono send(HttpRequest request) { @Test public void exponentialRetryMax() throws Exception { final int maxRetries = 5; - final HttpPipeline pipeline = new HttpPipeline(new MockHttpClient() { - int count = -1; - - @Override - public Mono send(HttpRequest request) { - Assert.assertTrue(count++ < maxRetries); - return Mono.just(new MockHttpResponse(request, 500)); - } - }, - new RetryPolicy(maxRetries, Duration.of(0, ChronoUnit.MILLIS))); + final HttpPipeline pipeline = HttpPipeline.builder() + .httpClient(new MockHttpClient() { + int count = -1; + + @Override + public Mono send(HttpRequest request) { + Assert.assertTrue(count++ < maxRetries); + return Mono.just(new MockHttpResponse(request, 500)); + } + }) + .policies(new RetryPolicy(maxRetries, Duration.of(0, ChronoUnit.MILLIS))) + .build(); HttpResponse response = pipeline.send(new HttpRequest(HttpMethod.GET, diff --git a/core/azure-core/src/test/java/com/azure/core/implementation/RestProxyStressTests.java b/core/azure-core/src/test/java/com/azure/core/implementation/RestProxyStressTests.java index 64c8b88bcdc2..2166e27513c6 100644 --- a/core/azure-core/src/test/java/com/azure/core/implementation/RestProxyStressTests.java +++ b/core/azure-core/src/test/java/com/azure/core/implementation/RestProxyStressTests.java @@ -114,7 +114,9 @@ public static void beforeClass() throws IOException { polices.add(new HttpLoggingPolicy(HttpLogDetailLevel.BASIC, false)); // service = RestProxy.create(IOService.class, - new HttpPipeline(polices.toArray(new HttpPipelinePolicy[polices.size()]))); + HttpPipeline.builder() + .policies(polices.toArray(new HttpPipelinePolicy[0])) + .build()); RestProxyStressTests.tempFolderPath = Paths.get(tempFolderPath); create100MFiles(false); @@ -508,7 +510,9 @@ public void testHighParallelism() { } final IOService innerService = RestProxy.create(IOService.class, - new HttpPipeline(policies.toArray(new HttpPipelinePolicy[policies.size()]))); + HttpPipeline.builder() + .policies(policies.toArray(new HttpPipelinePolicy[0])) + .build()); // When running with MockServer, connections sometimes get dropped, // but this doesn't seem to result in any bad behavior as long as we retry. diff --git a/core/azure-core/src/test/java/com/azure/core/implementation/RestProxyTests.java b/core/azure-core/src/test/java/com/azure/core/implementation/RestProxyTests.java index ad01770018c2..12f2968a880d 100644 --- a/core/azure-core/src/test/java/com/azure/core/implementation/RestProxyTests.java +++ b/core/azure-core/src/test/java/com/azure/core/implementation/RestProxyTests.java @@ -1499,8 +1499,10 @@ public void flowableUploadTest() throws Exception { // // Order in which policies applied will be the order in which they added to builder // - final HttpPipeline httpPipeline = new HttpPipeline(httpClient, - new HttpLoggingPolicy(HttpLogDetailLevel.BODY_AND_HEADERS, true)); + final HttpPipeline httpPipeline = HttpPipeline.builder() + .httpClient(httpClient) + .policies(new HttpLoggingPolicy(HttpLogDetailLevel.BODY_AND_HEADERS, true)) + .build(); // Response response = RestProxy.create(FlowableUploadService.class, httpPipeline, SERIALIZER).put(stream, Files.size(filePath)); @@ -1578,14 +1580,14 @@ interface Service25 { @Test(expected = HttpRequestException.class) @Ignore("Decoding is not a policy anymore") public void testMissingDecodingPolicyCausesException() { - Service25 service = RestProxy.create(Service25.class, new HttpPipeline()); + Service25 service = RestProxy.create(Service25.class, HttpPipeline.builder().build()); service.get(); } @Test(expected = HttpRequestException.class) @Ignore("Decoding is not a policy anymore") public void testSingleMissingDecodingPolicyCausesException() { - Service25 service = RestProxy.create(Service25.class, new HttpPipeline()); + Service25 service = RestProxy.create(Service25.class, HttpPipeline.builder().build()); service.getAsync().block(); service.getBodyResponseAsync().block(); } @@ -1593,7 +1595,7 @@ public void testSingleMissingDecodingPolicyCausesException() { @Test(expected = HttpRequestException.class) @Ignore("Decoding is not a policy anymore") public void testSingleBodyResponseMissingDecodingPolicyCausesException() { - Service25 service = RestProxy.create(Service25.class, new HttpPipeline()); + Service25 service = RestProxy.create(Service25.class, HttpPipeline.builder().build()); service.getBodyResponseAsync().block(); } @@ -1605,7 +1607,7 @@ interface Service26 { @Test public void postUrlFormEncoded() { - Service26 service = RestProxy.create(Service26.class, new HttpPipeline()); + Service26 service = RestProxy.create(Service26.class, HttpPipeline.builder().build()); HttpBinFormDataJSON response = service.postForm("Foo", "123", "foo@bar.com", PizzaSize.LARGE, Arrays.asList("Bacon", "Onion")); assertNotNull(response); assertNotNull(response.form()); @@ -1626,7 +1628,9 @@ protected T createService(Class serviceClass) { } protected T createService(Class serviceClass, HttpClient httpClient) { - final HttpPipeline httpPipeline = new HttpPipeline(httpClient); + final HttpPipeline httpPipeline = HttpPipeline.builder() + .httpClient(httpClient) + .build(); return RestProxy.create(serviceClass, httpPipeline, SERIALIZER); } diff --git a/core/azure-core/src/test/java/com/azure/core/implementation/RestProxyWithMockTests.java b/core/azure-core/src/test/java/com/azure/core/implementation/RestProxyWithMockTests.java index ec9891a21d4c..98ecf53ddb94 100644 --- a/core/azure-core/src/test/java/com/azure/core/implementation/RestProxyWithMockTests.java +++ b/core/azure-core/src/test/java/com/azure/core/implementation/RestProxyWithMockTests.java @@ -176,7 +176,7 @@ interface ServiceErrorWithCharsetService { public void serviceErrorWithResponseContentType() { ServiceErrorWithCharsetService service = RestProxy.create( ServiceErrorWithCharsetService.class, - new HttpPipeline(new SimpleMockHttpClient() { + HttpPipeline.builder().httpClient(new SimpleMockHttpClient() { @Override public Mono send(HttpRequest request) { HttpHeaders headers = new HttpHeaders().put("Content-Type", "application/json"); @@ -185,7 +185,7 @@ public Mono send(HttpRequest request) { "{ \"error\": \"Something went wrong, but at least this JSON is valid.\"}".getBytes(StandardCharsets.UTF_8)); return Mono.just(response); } - })); + }).build()); try { service.get(); @@ -199,7 +199,7 @@ public Mono send(HttpRequest request) { public void serviceErrorWithResponseContentTypeBadJSON() { ServiceErrorWithCharsetService service = RestProxy.create( ServiceErrorWithCharsetService.class, - new HttpPipeline(new SimpleMockHttpClient() { + HttpPipeline.builder().httpClient(new SimpleMockHttpClient() { @Override public Mono send(HttpRequest request) { HttpHeaders headers = new HttpHeaders().put("Content-Type", "application/json"); @@ -207,7 +207,7 @@ public Mono send(HttpRequest request) { HttpResponse response = new MockHttpResponse(request, 200, headers, "BAD JSON".getBytes(StandardCharsets.UTF_8)); return Mono.just(response); } - })); + }).build()); try { service.get(); @@ -222,7 +222,7 @@ public Mono send(HttpRequest request) { public void serviceErrorWithResponseContentTypeCharset() { ServiceErrorWithCharsetService service = RestProxy.create( ServiceErrorWithCharsetService.class, - new HttpPipeline(new SimpleMockHttpClient() { + HttpPipeline.builder().httpClient(new SimpleMockHttpClient() { @Override public Mono send(HttpRequest request) { HttpHeaders headers = new HttpHeaders().put("Content-Type", "application/json; charset=UTF-8"); @@ -231,7 +231,7 @@ public Mono send(HttpRequest request) { "{ \"error\": \"Something went wrong, but at least this JSON is valid.\"}".getBytes(StandardCharsets.UTF_8)); return Mono.just(response); } - })); + }).build()); try { service.get(); @@ -245,7 +245,7 @@ public Mono send(HttpRequest request) { public void serviceErrorWithResponseContentTypeCharsetBadJSON() { ServiceErrorWithCharsetService service = RestProxy.create( ServiceErrorWithCharsetService.class, - new HttpPipeline(new SimpleMockHttpClient() { + HttpPipeline.builder().httpClient(new SimpleMockHttpClient() { @Override public Mono send(HttpRequest request) { HttpHeaders headers = new HttpHeaders().put("Content-Type", "application/json; charset=UTF-8"); @@ -253,7 +253,7 @@ public Mono send(HttpRequest request) { HttpResponse response = new MockHttpResponse(request, 200, headers, "BAD JSON".getBytes(StandardCharsets.UTF_8)); return Mono.just(response); } - })); + }).build()); try { service.get(); diff --git a/core/azure-core/src/test/java/com/azure/core/implementation/RestProxyXMLTests.java b/core/azure-core/src/test/java/com/azure/core/implementation/RestProxyXMLTests.java index f9fde46c6cbb..71296d1bc37e 100644 --- a/core/azure-core/src/test/java/com/azure/core/implementation/RestProxyXMLTests.java +++ b/core/azure-core/src/test/java/com/azure/core/implementation/RestProxyXMLTests.java @@ -94,7 +94,9 @@ interface MyXMLService { @Test public void canReadXMLResponse() throws Exception { // - final HttpPipeline pipeline = new HttpPipeline(new MockXMLHTTPClient()); + final HttpPipeline pipeline = HttpPipeline.builder() + .httpClient(new MockXMLHTTPClient()) + .build(); // MyXMLService myXMLService = RestProxy.create(MyXMLService.class, @@ -158,7 +160,9 @@ public void canWriteXMLRequest() throws Exception { JacksonAdapter serializer = new JacksonAdapter(); MockXMLReceiverClient httpClient = new MockXMLReceiverClient(); // - final HttpPipeline pipeline = new HttpPipeline(httpClient); + final HttpPipeline pipeline = HttpPipeline.builder() + .httpClient(httpClient) + .build(); // MyXMLService myXMLService = RestProxy.create(MyXMLService.class, pipeline, @@ -192,7 +196,9 @@ public interface MyXMLServiceWithAttributes { public void canDeserializeXMLWithAttributes() throws Exception { JacksonAdapter serializer = new JacksonAdapter(); // - final HttpPipeline pipeline = new HttpPipeline(new MockXMLHTTPClient()); + final HttpPipeline pipeline = HttpPipeline.builder() + .httpClient(new MockXMLHTTPClient()) + .build(); // MyXMLServiceWithAttributes myXMLService = RestProxy.create(