hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject svn commit: r1793320 [2/5] - in /httpcomponents/httpclient/trunk: httpclient5-testing/src/main/java/org/apache/hc/client5/testing/async/ httpclient5-testing/src/main/java/org/apache/hc/client5/testing/classic/ httpclient5-testing/src/test/java/org/apac...
Date Mon, 01 May 2017 12:39:18 GMT
Added: httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestAsyncStatefulConnManagement.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestAsyncStatefulConnManagement.java?rev=1793320&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestAsyncStatefulConnManagement.java (added)
+++ httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestAsyncStatefulConnManagement.java Mon May  1 12:39:16 2017
@@ -0,0 +1,257 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.testing.async;
+
+import java.util.concurrent.Future;
+
+import org.apache.hc.client5.http.HttpRoute;
+import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
+import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
+import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.client5.http.protocol.UserTokenHandler;
+import org.apache.hc.core5.function.Supplier;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.EndpointDetails;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
+import org.apache.hc.core5.http.protocol.BasicHttpContext;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.http.protocol.HttpCoreContext;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestAsyncStatefulConnManagement extends IntegrationTestBase {
+
+    @Test
+    public void testStatefulConnections() throws Exception {
+        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
+
+            @Override
+            public AsyncServerExchangeHandler get() {
+                return new AbstractSimpleServerExchangeHandler() {
+
+                    @Override
+                    protected SimpleHttpResponse handle(
+                            final SimpleHttpRequest request,
+                            final HttpCoreContext context) throws HttpException {
+                        return new SimpleHttpResponse(HttpStatus.SC_OK, "Whatever", ContentType.TEXT_PLAIN);
+                    }
+                };
+            }
+
+        });
+
+        final UserTokenHandler userTokenHandler = new UserTokenHandler() {
+
+            @Override
+            public Object getUserToken(final HttpRoute route, final HttpContext context) {
+                return context.getAttribute("user");
+            }
+
+        };
+        clientBuilder.setUserTokenHandler(userTokenHandler);
+        final HttpHost target = start();
+
+        final int workerCount = 2;
+        final int requestCount = 5;
+
+        final HttpContext[] contexts = new HttpContext[workerCount];
+        final HttpWorker[] workers = new HttpWorker[workerCount];
+        for (int i = 0; i < contexts.length; i++) {
+            final HttpClientContext context = HttpClientContext.create();
+            contexts[i] = context;
+            workers[i] = new HttpWorker(
+                    "user" + i,
+                    context, requestCount, target, httpclient);
+        }
+
+        for (final HttpWorker worker : workers) {
+            worker.start();
+        }
+        for (final HttpWorker worker : workers) {
+            worker.join(10000);
+        }
+        for (final HttpWorker worker : workers) {
+            final Exception ex = worker.getException();
+            if (ex != null) {
+                throw ex;
+            }
+            Assert.assertEquals(requestCount, worker.getCount());
+        }
+
+        for (final HttpContext context : contexts) {
+            final String state0 = (String) context.getAttribute("r0");
+            Assert.assertNotNull(state0);
+            for (int r = 1; r < requestCount; r++) {
+                Assert.assertEquals(state0, context.getAttribute("r" + r));
+            }
+        }
+
+    }
+
+    static class HttpWorker extends Thread {
+
+        private final String uid;
+        private final HttpClientContext context;
+        private final int requestCount;
+        private final HttpHost target;
+        private final CloseableHttpAsyncClient httpclient;
+
+        private volatile Exception exception;
+        private volatile int count;
+
+        public HttpWorker(
+                final String uid,
+                final HttpClientContext context,
+                final int requestCount,
+                final HttpHost target,
+                final CloseableHttpAsyncClient httpclient) {
+            super();
+            this.uid = uid;
+            this.context = context;
+            this.requestCount = requestCount;
+            this.target = target;
+            this.httpclient = httpclient;
+            this.count = 0;
+        }
+
+        public int getCount() {
+            return count;
+        }
+
+        public Exception getException() {
+            return exception;
+        }
+
+        @Override
+        public void run() {
+            try {
+                context.setAttribute("user", uid);
+                for (int r = 0; r < requestCount; r++) {
+                    final SimpleHttpRequest httpget = SimpleHttpRequest.get(target, "/");
+                    final Future<SimpleHttpResponse> future = httpclient.execute(httpget, null);
+                    future.get();
+
+                    count++;
+                    final EndpointDetails endpointDetails = context.getEndpointDetails();
+                    final String connuid = Integer.toHexString(System.identityHashCode(endpointDetails));
+                    context.setAttribute("r" + r, connuid);
+                }
+
+            } catch (final Exception ex) {
+                exception = ex;
+            }
+        }
+
+    }
+
+    @Test
+    public void testRouteSpecificPoolRecylcing() throws Exception {
+        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
+
+            @Override
+            public AsyncServerExchangeHandler get() {
+                return new AbstractSimpleServerExchangeHandler() {
+
+                    @Override
+                    protected SimpleHttpResponse handle(
+                            final SimpleHttpRequest request,
+                            final HttpCoreContext context) throws HttpException {
+                        return new SimpleHttpResponse(HttpStatus.SC_OK, "Whatever", ContentType.TEXT_PLAIN);
+                    }
+                };
+            }
+
+        });
+
+        // This tests what happens when a maxed connection pool needs
+        // to kill the last idle connection to a route to build a new
+        // one to the same route.
+        final UserTokenHandler userTokenHandler = new UserTokenHandler() {
+
+            @Override
+            public Object getUserToken(final HttpRoute route, final HttpContext context) {
+                return context.getAttribute("user");
+            }
+
+        };
+        clientBuilder.setUserTokenHandler(userTokenHandler);
+
+        final HttpHost target = start();
+        final int maxConn = 2;
+        // We build a client with 2 max active // connections, and 2 max per route.
+        connManager.setMaxTotal(maxConn);
+        connManager.setDefaultMaxPerRoute(maxConn);
+
+        // Bottom of the pool : a *keep alive* connection to Route 1.
+        final HttpContext context1 = new BasicHttpContext();
+        context1.setAttribute("user", "stuff");
+
+        final Future<SimpleHttpResponse> future1 = httpclient.execute(SimpleHttpRequest.get(target, "/"), context1, null);
+        final HttpResponse response1 = future1.get();
+        Assert.assertNotNull(response1);
+        Assert.assertEquals(200, response1.getCode());
+
+        // The ConnPoolByRoute now has 1 free connection, out of 2 max
+        // The ConnPoolByRoute has one RouteSpcfcPool, that has one free connection
+        // for [localhost][stuff]
+
+        Thread.sleep(100);
+
+        // Send a very simple HTTP get (it MUST be simple, no auth, no proxy, no 302, no 401, ...)
+        // Send it to another route. Must be a keepalive.
+        final HttpContext context2 = new BasicHttpContext();
+
+        final Future<SimpleHttpResponse> future2 = httpclient.execute(SimpleHttpRequest.get(
+                new HttpHost("127.0.0.1", target.getPort(), target.getSchemeName()),"/"), context2, null);
+        final HttpResponse response2 = future2.get();
+        Assert.assertNotNull(response2);
+        Assert.assertEquals(200, response2.getCode());
+
+        // ConnPoolByRoute now has 2 free connexions, out of its 2 max.
+        // The [localhost][stuff] RouteSpcfcPool is the same as earlier
+        // And there is a [127.0.0.1][null] pool with 1 free connection
+
+        Thread.sleep(100);
+
+        // This will put the ConnPoolByRoute to the targeted state :
+        // [localhost][stuff] will not get reused because this call is [localhost][null]
+        // So the ConnPoolByRoute will need to kill one connection (it is maxed out globally).
+        // The killed conn is the oldest, which means the first HTTPGet ([localhost][stuff]).
+        // When this happens, the RouteSpecificPool becomes empty.
+        final HttpContext context3 = new BasicHttpContext();
+        final Future<SimpleHttpResponse> future3 = httpclient.execute(SimpleHttpRequest.get(target, "/"), context3, null);
+        final HttpResponse response3 = future3.get();
+        Assert.assertNotNull(response3);
+        Assert.assertEquals(200, response3.getCode());
+    }
+
+}
\ No newline at end of file

Propchange: httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestAsyncStatefulConnManagement.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestAsyncStatefulConnManagement.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestAsyncStatefulConnManagement.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttpAsync.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttpAsync.java?rev=1793320&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttpAsync.java (added)
+++ httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttpAsync.java Mon May  1 12:39:16 2017
@@ -0,0 +1,252 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.testing.async;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.Random;
+import java.util.concurrent.Future;
+
+import org.apache.hc.client5.http.async.methods.AsyncRequestBuilder;
+import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
+import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
+import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
+import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.HeaderElements;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.Message;
+import org.apache.hc.core5.http.URIScheme;
+import org.apache.hc.core5.http.nio.BasicResponseConsumer;
+import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityConsumer;
+import org.hamcrest.CoreMatchers;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class TestHttpAsync extends IntegrationTestBase {
+
+    @Parameterized.Parameters(name = "{0}")
+    public static Collection<Object[]> protocols() {
+        return Arrays.asList(new Object[][]{
+                { URIScheme.HTTP },
+                { URIScheme.HTTPS },
+        });
+    }
+
+    public TestHttpAsync(final URIScheme scheme) {
+        super(scheme);
+    }
+
+    @Test
+    public void testSequenctialGetRequests() throws Exception {
+        final HttpHost target = start();
+        for (int i = 0; i < 3; i++) {
+            final Future<SimpleHttpResponse> future = httpclient.execute(
+                    SimpleHttpRequest.get(target, "/random/2048"), null);
+            final SimpleHttpResponse response = future.get();
+            Assert.assertThat(response, CoreMatchers.notNullValue());
+            Assert.assertThat(response.getCode(), CoreMatchers.equalTo(200));
+            final String body = response.getBody();
+            Assert.assertThat(body, CoreMatchers.notNullValue());
+            Assert.assertThat(body.length(), CoreMatchers.equalTo(2048));
+        }
+    }
+
+    @Test
+    public void testSequenctialHeadRequests() throws Exception {
+        final HttpHost target = start();
+        for (int i = 0; i < 3; i++) {
+            final Future<SimpleHttpResponse> future = httpclient.execute(
+                    SimpleHttpRequest.head(target, "/random/2048"), null);
+            final SimpleHttpResponse response = future.get();
+            Assert.assertThat(response, CoreMatchers.notNullValue());
+            Assert.assertThat(response.getCode(), CoreMatchers.equalTo(200));
+            final String body = response.getBody();
+            Assert.assertThat(body, CoreMatchers.nullValue());
+        }
+    }
+
+    @Test
+    public void testSequenctialGetRequestsCloseConnection() throws Exception {
+        final HttpHost target = start();
+        for (int i = 0; i < 3; i++) {
+            final SimpleHttpRequest get = SimpleHttpRequest.get(target, "/random/2048");
+            get.setHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
+            final Future<SimpleHttpResponse> future = httpclient.execute(get, null);
+            final SimpleHttpResponse response = future.get();
+            Assert.assertThat(response, CoreMatchers.notNullValue());
+            Assert.assertThat(response.getCode(), CoreMatchers.equalTo(200));
+            final String body = response.getBody();
+            Assert.assertThat(body, CoreMatchers.notNullValue());
+            Assert.assertThat(body.length(), CoreMatchers.equalTo(2048));
+        }
+    }
+
+    @Test
+    public void testSequenctialPostRequests() throws Exception {
+        final HttpHost target = start();
+        for (int i = 0; i < 3; i++) {
+            final byte[] b1 = new byte[1024];
+            final Random rnd = new Random(System.currentTimeMillis());
+            rnd.nextBytes(b1);
+            final Future<Message<HttpResponse, byte[]>> future = httpclient.execute(
+                    AsyncRequestBuilder.post(target, "/echo/")
+                        .setEntity(b1, ContentType.APPLICATION_OCTET_STREAM)
+                        .build(),
+                    new BasicResponseConsumer<>(new BasicAsyncEntityConsumer()), HttpClientContext.create(), null);
+            final Message<HttpResponse, byte[]> responseMessage = future.get();
+            Assert.assertThat(responseMessage, CoreMatchers.notNullValue());
+            final HttpResponse response = responseMessage.getHead();
+            Assert.assertThat(response.getCode(), CoreMatchers.equalTo(200));
+            final byte[] b2 = responseMessage.getBody();
+            Assert.assertThat(b1, CoreMatchers.equalTo(b2));
+        }
+    }
+
+    @Test
+    public void testConcurrentPostsOverMultipleConnections() throws Exception {
+        final HttpHost target = start();
+        final byte[] b1 = new byte[1024];
+        final Random rnd = new Random(System.currentTimeMillis());
+        rnd.nextBytes(b1);
+
+        final int reqCount = 20;
+
+        connManager.setDefaultMaxPerRoute(reqCount);
+        connManager.setMaxTotal(100);
+
+        final Queue<Future<Message<HttpResponse, byte[]>>> queue = new LinkedList<>();
+        for (int i = 0; i < reqCount; i++) {
+            final Future<Message<HttpResponse, byte[]>> future = httpclient.execute(
+                    AsyncRequestBuilder.post(target, "/echo/")
+                            .setEntity(b1, ContentType.APPLICATION_OCTET_STREAM)
+                            .build(),
+                    new BasicResponseConsumer<>(new BasicAsyncEntityConsumer()), HttpClientContext.create(), null);
+            queue.add(future);
+        }
+
+        while (!queue.isEmpty()) {
+            final Future<Message<HttpResponse, byte[]>> future = queue.remove();
+            final Message<HttpResponse, byte[]> responseMessage = future.get();
+            Assert.assertThat(responseMessage, CoreMatchers.notNullValue());
+            final HttpResponse response = responseMessage.getHead();
+            Assert.assertThat(response.getCode(), CoreMatchers.equalTo(200));
+            final byte[] b2 = responseMessage.getBody();
+            Assert.assertThat(b1, CoreMatchers.equalTo(b2));
+        }
+    }
+
+    @Test
+    public void testConcurrentPostsOverSingleConnection() throws Exception {
+        final HttpHost target = start();
+        final byte[] b1 = new byte[1024];
+        final Random rnd = new Random(System.currentTimeMillis());
+        rnd.nextBytes(b1);
+
+        final int reqCount = 20;
+
+        connManager.setDefaultMaxPerRoute(1);
+        connManager.setMaxTotal(100);
+
+        final Queue<Future<Message<HttpResponse, byte[]>>> queue = new LinkedList<>();
+        for (int i = 0; i < reqCount; i++) {
+            final Future<Message<HttpResponse, byte[]>> future = httpclient.execute(
+                    AsyncRequestBuilder.post(target, "/echo/")
+                            .setEntity(b1, ContentType.APPLICATION_OCTET_STREAM)
+                            .build(),
+                    new BasicResponseConsumer<>(new BasicAsyncEntityConsumer()), HttpClientContext.create(), null);
+            queue.add(future);
+        }
+
+        while (!queue.isEmpty()) {
+            final Future<Message<HttpResponse, byte[]>> future = queue.remove();
+            final Message<HttpResponse, byte[]> responseMessage = future.get();
+            Assert.assertThat(responseMessage, CoreMatchers.notNullValue());
+            final HttpResponse response = responseMessage.getHead();
+            Assert.assertThat(response.getCode(), CoreMatchers.equalTo(200));
+            final byte[] b2 = responseMessage.getBody();
+            Assert.assertThat(b1, CoreMatchers.equalTo(b2));
+        }
+    }
+
+    @Test
+    public void testSharedPool() throws Exception {
+        final HttpHost target = start();
+        final Future<SimpleHttpResponse> future1 = httpclient.execute(
+                SimpleHttpRequest.get(target, "/random/2048"), null);
+        final SimpleHttpResponse response1 = future1.get();
+        Assert.assertThat(response1, CoreMatchers.notNullValue());
+        Assert.assertThat(response1.getCode(), CoreMatchers.equalTo(200));
+        final String body1 = response1.getBody();
+        Assert.assertThat(body1, CoreMatchers.notNullValue());
+        Assert.assertThat(body1.length(), CoreMatchers.equalTo(2048));
+
+
+        try (final CloseableHttpAsyncClient httpclient2 = HttpAsyncClients.custom()
+                .setConnectionManager(connManager)
+                .setConnectionManagerShared(true)
+                .build()) {
+            httpclient2.start();
+            final Future<SimpleHttpResponse> future2 = httpclient2.execute(
+                    SimpleHttpRequest.get(target, "/random/2048"), null);
+            final SimpleHttpResponse response2 = future2.get();
+            Assert.assertThat(response2, CoreMatchers.notNullValue());
+            Assert.assertThat(response2.getCode(), CoreMatchers.equalTo(200));
+            final String body2 = response2.getBody();
+            Assert.assertThat(body2, CoreMatchers.notNullValue());
+            Assert.assertThat(body2.length(), CoreMatchers.equalTo(2048));
+        }
+
+        final Future<SimpleHttpResponse> future3 = httpclient.execute(
+                SimpleHttpRequest.get(target, "/random/2048"), null);
+        final SimpleHttpResponse response3 = future3.get();
+        Assert.assertThat(response3, CoreMatchers.notNullValue());
+        Assert.assertThat(response3.getCode(), CoreMatchers.equalTo(200));
+        final String body3 = response3.getBody();
+        Assert.assertThat(body3, CoreMatchers.notNullValue());
+        Assert.assertThat(body3.length(), CoreMatchers.equalTo(2048));
+    }
+
+    @Test
+    public void testBadRequest() throws Exception {
+        final HttpHost target = start();
+        final Future<SimpleHttpResponse> future = httpclient.execute(
+                SimpleHttpRequest.get(target, "/random/boom"), null);
+        final SimpleHttpResponse response = future.get();
+        Assert.assertThat(response, CoreMatchers.notNullValue());
+        Assert.assertThat(response.getCode(), CoreMatchers.equalTo(400));
+    }
+
+}
\ No newline at end of file

Propchange: httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttpAsync.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttpAsync.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttpAsync.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttpAsyncMinimal.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttpAsyncMinimal.java?rev=1793320&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttpAsyncMinimal.java (added)
+++ httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttpAsyncMinimal.java Mon May  1 12:39:16 2017
@@ -0,0 +1,274 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.testing.async;
+
+import java.net.InetSocketAddress;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.Random;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.hc.client5.http.async.methods.AsyncRequestBuilder;
+import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
+import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
+import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
+import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
+import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
+import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.client5.http.ssl.H2TlsStrategy;
+import org.apache.hc.client5.testing.SSLTestContexts;
+import org.apache.hc.core5.function.Supplier;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.HttpVersion;
+import org.apache.hc.core5.http.Message;
+import org.apache.hc.core5.http.URIScheme;
+import org.apache.hc.core5.http.config.H1Config;
+import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
+import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
+import org.apache.hc.core5.http.nio.BasicResponseConsumer;
+import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityConsumer;
+import org.apache.hc.core5.http2.HttpVersionPolicy;
+import org.apache.hc.core5.http2.config.H2Config;
+import org.apache.hc.core5.io.ShutdownType;
+import org.apache.hc.core5.reactor.IOReactorConfig;
+import org.apache.hc.core5.reactor.ListenerEndpoint;
+import org.apache.hc.core5.testing.nio.Http2TestServer;
+import org.apache.hc.core5.util.TimeValue;
+import org.hamcrest.CoreMatchers;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExternalResource;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class TestHttpAsyncMinimal {
+
+    @Parameterized.Parameters(name = "{0} {1}")
+    public static Collection<Object[]> protocols() {
+        return Arrays.asList(new Object[][]{
+                { HttpVersion.HTTP_1_1, URIScheme.HTTP },
+                { HttpVersion.HTTP_1_1, URIScheme.HTTPS },
+                { HttpVersion.HTTP_2, URIScheme.HTTP },
+                { HttpVersion.HTTP_2, URIScheme.HTTPS }
+        });
+    }
+
+    protected final HttpVersion version;
+    protected final URIScheme scheme;
+
+    public TestHttpAsyncMinimal(final HttpVersion version, final URIScheme scheme) {
+        this.version = version;
+        this.scheme = scheme;
+    }
+
+    protected Http2TestServer server;
+    protected MinimalHttpAsyncClient httpclient;
+
+    @Rule
+    public ExternalResource serverResource = new ExternalResource() {
+
+        @Override
+        protected void before() throws Throwable {
+            server = new Http2TestServer(
+                    IOReactorConfig.DEFAULT,
+                    scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null);
+            server.register("/echo/*", new Supplier<AsyncServerExchangeHandler>() {
+
+                @Override
+                public AsyncServerExchangeHandler get() {
+                    return new AsyncEchoHandler();
+                }
+
+            });
+            server.register("/random/*", new Supplier<AsyncServerExchangeHandler>() {
+
+                @Override
+                public AsyncServerExchangeHandler get() {
+                    return new AsyncRandomHandler();
+                }
+
+            });
+        }
+
+        @Override
+        protected void after() {
+            if (server != null) {
+                server.shutdown(TimeValue.ofSeconds(5));
+                server = null;
+            }
+        }
+
+    };
+
+    @Rule
+    public ExternalResource clientResource = new ExternalResource() {
+
+        @Override
+        protected void before() throws Throwable {
+            final PoolingAsyncClientConnectionManager connectionManager = PoolingAsyncClientConnectionManagerBuilder.create()
+                    .setTlsStrategy(new H2TlsStrategy(SSLTestContexts.createClientSSLContext()))
+                    .build();
+            final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
+                    .setSoTimeout(5, TimeUnit.SECONDS)
+                    .build();
+            if (version.greaterEquals(HttpVersion.HTTP_2)) {
+                httpclient = HttpAsyncClients.createMinimal(
+                        HttpVersionPolicy.FORCE_HTTP_2, H2Config.DEFAULT, H1Config.DEFAULT, ioReactorConfig, connectionManager);
+            } else {
+                httpclient = HttpAsyncClients.createMinimal(
+                        HttpVersionPolicy.FORCE_HTTP_1, H2Config.DEFAULT, H1Config.DEFAULT, ioReactorConfig, connectionManager);
+            }
+        }
+
+        @Override
+        protected void after() {
+            if (httpclient != null) {
+                httpclient.shutdown(ShutdownType.GRACEFUL);
+                httpclient = null;
+            }
+        }
+
+    };
+
+    public HttpHost start() throws Exception {
+        if (version.greaterEquals(HttpVersion.HTTP_2)) {
+            server.start(H2Config.DEFAULT);
+        } else {
+            server.start(H1Config.DEFAULT);
+        }
+        final ListenerEndpoint listener = server.listen(new InetSocketAddress(0));
+        httpclient.start();
+        listener.waitFor();
+        final InetSocketAddress address = (InetSocketAddress) listener.getAddress();
+        return new HttpHost("localhost", address.getPort(), scheme.name());
+    }
+
+    @Test
+    public void testSequenctialGetRequests() throws Exception {
+        final HttpHost target = start();
+        for (int i = 0; i < 3; i++) {
+            final Future<SimpleHttpResponse> future = httpclient.execute(
+                    SimpleHttpRequest.get(target, "/random/2048"), null);
+            final SimpleHttpResponse response = future.get();
+            Assert.assertThat(response, CoreMatchers.notNullValue());
+            Assert.assertThat(response.getCode(), CoreMatchers.equalTo(200));
+            final String body = response.getBody();
+            Assert.assertThat(body, CoreMatchers.notNullValue());
+            Assert.assertThat(body.length(), CoreMatchers.equalTo(2048));
+        }
+    }
+
+    @Test
+    public void testSequenctialHeadRequests() throws Exception {
+        final HttpHost target = start();
+        for (int i = 0; i < 3; i++) {
+            final Future<SimpleHttpResponse> future = httpclient.execute(
+                    SimpleHttpRequest.head(target, "/random/2048"), null);
+            final SimpleHttpResponse response = future.get();
+            Assert.assertThat(response, CoreMatchers.notNullValue());
+            Assert.assertThat(response.getCode(), CoreMatchers.equalTo(200));
+            final String body = response.getBody();
+            Assert.assertThat(body, CoreMatchers.nullValue());
+        }
+    }
+
+    @Test
+    public void testConcurrentPostsOverMultipleConnections() throws Exception {
+        final HttpHost target = start();
+        final byte[] b1 = new byte[1024];
+        final Random rnd = new Random(System.currentTimeMillis());
+        rnd.nextBytes(b1);
+
+        final int reqCount = 20;
+
+        final Queue<Future<Message<HttpResponse, byte[]>>> queue = new LinkedList<>();
+        for (int i = 0; i < reqCount; i++) {
+            final Future<Message<HttpResponse, byte[]>> future = httpclient.execute(
+                    AsyncRequestBuilder.post(target, "/echo/")
+                            .setEntity(b1, ContentType.APPLICATION_OCTET_STREAM)
+                            .build(),
+                    new BasicResponseConsumer<>(new BasicAsyncEntityConsumer()), HttpClientContext.create(), null);
+            queue.add(future);
+        }
+
+        while (!queue.isEmpty()) {
+            final Future<Message<HttpResponse, byte[]>> future = queue.remove();
+            final Message<HttpResponse, byte[]> responseMessage = future.get();
+            Assert.assertThat(responseMessage, CoreMatchers.notNullValue());
+            final HttpResponse response = responseMessage.getHead();
+            Assert.assertThat(response.getCode(), CoreMatchers.equalTo(200));
+            final byte[] b2 = responseMessage.getBody();
+            Assert.assertThat(b1, CoreMatchers.equalTo(b2));
+        }
+    }
+
+    @Test
+    public void testConcurrentPostsOverSingleConnection() throws Exception {
+        final HttpHost target = start();
+        final byte[] b1 = new byte[1024];
+        final Random rnd = new Random(System.currentTimeMillis());
+        rnd.nextBytes(b1);
+
+        final int reqCount = 20;
+
+        final Future<AsyncClientEndpoint> endpointLease = httpclient.lease(target, null);
+        final AsyncClientEndpoint endpoint = endpointLease.get(5, TimeUnit.SECONDS);
+        try {
+            final Queue<Future<Message<HttpResponse, byte[]>>> queue = new LinkedList<>();
+            for (int i = 0; i < reqCount; i++) {
+                final Future<Message<HttpResponse, byte[]>> future = endpoint.execute(
+                        AsyncRequestBuilder.post(target, "/echo/")
+                                .setEntity(b1, ContentType.APPLICATION_OCTET_STREAM)
+                                .build(),
+                        new BasicResponseConsumer<>(new BasicAsyncEntityConsumer()), HttpClientContext.create(), null);
+                queue.add(future);
+            }
+            while (!queue.isEmpty()) {
+                final Future<Message<HttpResponse, byte[]>> future = queue.remove();
+                final Message<HttpResponse, byte[]> responseMessage = future.get();
+                Assert.assertThat(responseMessage, CoreMatchers.notNullValue());
+                final HttpResponse response = responseMessage.getHead();
+                Assert.assertThat(response.getCode(), CoreMatchers.equalTo(200));
+                final byte[] b2 = responseMessage.getBody();
+                Assert.assertThat(b1, CoreMatchers.equalTo(b2));
+                endpoint.releaseAndReuse();
+            }
+        } finally {
+            endpoint.releaseAndDiscard();
+        }
+
+    }
+
+}
\ No newline at end of file

Propchange: httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttpAsyncMinimal.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttpAsyncMinimal.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttpAsyncMinimal.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/external/HttpAsyncClientCompatibilityTest.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/external/HttpAsyncClientCompatibilityTest.java?rev=1793320&r1=1793319&r2=1793320&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/external/HttpAsyncClientCompatibilityTest.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/external/HttpAsyncClientCompatibilityTest.java Mon May  1 12:39:16 2017
@@ -52,7 +52,6 @@ import org.apache.hc.core5.http.HttpHost
 import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.HttpVersion;
-import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
 import org.apache.hc.core5.http2.HttpVersionPolicy;
 import org.apache.hc.core5.ssl.SSLContexts;
 import org.apache.hc.core5.util.TextUtils;
@@ -167,13 +166,10 @@ public class HttpAsyncClientCompatibilit
             final HttpClientContext context = HttpClientContext.create();
             context.setCredentialsProvider(credentialsProvider);
 
-            final Future<AsyncClientEndpoint> leaseFuture = client.lease(target, null);
-            final AsyncClientEndpoint clientEndpoint = leaseFuture.get(20, TimeUnit.SECONDS);
-
             final String[] requestUris = new String[] {"/", "/news.html", "/status.html"};
             for (String requestUri: requestUris) {
                 final SimpleHttpRequest httpGet = new SimpleHttpRequest("GET", target, requestUri, null, null);
-                final Future<SimpleHttpResponse> future = clientEndpoint.execute(new SimpleRequestProducer(httpGet), new SimpleResponseConsumer(), null);
+                final Future<SimpleHttpResponse> future = client.execute(new SimpleRequestProducer(httpGet), new SimpleResponseConsumer(), null);
                 try {
                     final SimpleHttpResponse response = future.get(5, TimeUnit.SECONDS);
                     final int code = response.getCode();

Modified: httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/LocalServerTestBase.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/LocalServerTestBase.java?rev=1793320&r1=1793319&r2=1793320&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/LocalServerTestBase.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/LocalServerTestBase.java Mon May  1 12:39:16 2017
@@ -30,9 +30,11 @@ package org.apache.hc.client5.testing.sy
 import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
 import org.apache.hc.client5.http.impl.sync.CloseableHttpClient;
 import org.apache.hc.client5.http.impl.sync.HttpClientBuilder;
+import org.apache.hc.client5.testing.SSLTestContexts;
 import org.apache.hc.client5.testing.classic.EchoHandler;
 import org.apache.hc.client5.testing.classic.RandomHandler;
 import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.config.SocketConfig;
 import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
 import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
@@ -46,9 +48,7 @@ import org.junit.Before;
  */
 public abstract class LocalServerTestBase {
 
-    public enum ProtocolScheme { http, https };
-
-    protected final ProtocolScheme scheme;
+    protected final URIScheme scheme;
 
     protected ServerBootstrap serverBootstrap;
     protected HttpServer server;
@@ -56,12 +56,12 @@ public abstract class LocalServerTestBas
     protected HttpClientBuilder clientBuilder;
     protected CloseableHttpClient httpclient;
 
-    public LocalServerTestBase(final ProtocolScheme scheme) {
+    public LocalServerTestBase(final URIScheme scheme) {
         this.scheme = scheme;
     }
 
     public LocalServerTestBase() {
-        this(ProtocolScheme.http);
+        this(URIScheme.HTTP);
     }
 
     public String getSchemeName() {
@@ -77,7 +77,7 @@ public abstract class LocalServerTestBas
                 .setSocketConfig(socketConfig)
                 .registerHandler("/echo/*", new EchoHandler())
                 .registerHandler("/random/*", new RandomHandler());
-        if (this.scheme.equals(ProtocolScheme.https)) {
+        if (this.scheme.equals(URIScheme.HTTPS)) {
             this.serverBootstrap.setSslContext(SSLTestContexts.createServerSSLContext());
         }
 

Modified: httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestRedirects.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestRedirects.java?rev=1793320&r1=1793319&r2=1793320&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestRedirects.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestRedirects.java Mon May  1 12:39:16 2017
@@ -27,8 +27,8 @@
 package org.apache.hc.client5.testing.sync;
 
 import java.io.IOException;
-import java.net.InetSocketAddress;
 import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.Arrays;
 import java.util.List;
 
@@ -45,7 +45,6 @@ import org.apache.hc.client5.http.sync.m
 import org.apache.hc.client5.http.utils.URIUtils;
 import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.EndpointDetails;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHeaders;
@@ -59,7 +58,7 @@ import org.apache.hc.core5.http.io.entit
 import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.apache.hc.core5.http.message.BasicHeader;
 import org.apache.hc.core5.http.protocol.HttpContext;
-import org.apache.hc.core5.http.protocol.HttpCoreContext;
+import org.apache.hc.core5.net.URIBuilder;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -86,25 +85,25 @@ public class TestRedirects extends Local
                 final ClassicHttpRequest request,
                 final ClassicHttpResponse response,
                 final HttpContext context) throws HttpException, IOException {
-            final EndpointDetails endpointDetails = (EndpointDetails) context.getAttribute(HttpCoreContext.CONNECTION_ENDPOINT);
-            final InetSocketAddress socketAddress = (InetSocketAddress) endpointDetails.getLocalAddress();
-            String localhost = socketAddress.getHostName();
-            if (localhost.equals("127.0.0.1")) {
-                localhost = "localhost";
-            }
-            final int port = socketAddress.getPort();
-            final String uri = request.getRequestUri();
-            if (uri.equals("/oldlocation/")) {
-                response.setCode(this.statuscode);
-                response.addHeader(new BasicHeader("Location",
-                        "http://" + localhost + ":" + port + "/newlocation/"));
-                response.addHeader(new BasicHeader("Connection", "close"));
-            } else if (uri.equals("/newlocation/")) {
-                response.setCode(HttpStatus.SC_OK);
-                final StringEntity entity = new StringEntity("Successful redirect");
-                response.setEntity(entity);
-            } else {
-                response.setCode(HttpStatus.SC_NOT_FOUND);
+
+            try {
+                final URI requestURI = request.getUri();
+                final String path = requestURI.getPath();
+                if (path.equals("/oldlocation/")) {
+                    response.setCode(this.statuscode);
+                    response.addHeader(new BasicHeader("Location",
+                            new URIBuilder(requestURI).setPath("/newlocation/").build()));
+                    response.addHeader(new BasicHeader("Connection", "close"));
+                } else if (path.equals("/newlocation/")) {
+                    response.setCode(HttpStatus.SC_OK);
+                    final StringEntity entity = new StringEntity("Successful redirect");
+                    response.setEntity(entity);
+                } else {
+                    response.setCode(HttpStatus.SC_NOT_FOUND);
+                }
+
+            } catch (URISyntaxException ex) {
+                throw new ProtocolException(ex.getMessage(), ex);
             }
         }
 

Modified: httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestSSLSocketFactory.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestSSLSocketFactory.java?rev=1793320&r1=1793319&r2=1793320&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestSSLSocketFactory.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestSSLSocketFactory.java Mon May  1 12:39:16 2017
@@ -47,6 +47,7 @@ import org.apache.hc.client5.http.ssl.No
 import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
 import org.apache.hc.client5.http.ssl.TrustAllStrategy;
 import org.apache.hc.client5.http.ssl.TrustSelfSignedStrategy;
+import org.apache.hc.client5.testing.SSLTestContexts;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
 import org.apache.hc.core5.http.impl.bootstrap.SSLServerSetupHandler;

Modified: httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientConnectionEviction.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientConnectionEviction.java?rev=1793320&r1=1793319&r2=1793320&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientConnectionEviction.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientConnectionEviction.java Mon May  1 12:39:16 2017
@@ -63,7 +63,7 @@ public class AsyncClientConnectionEvicti
 
         final HttpHost target = new HttpHost("httpbin.org");
 
-        final SimpleHttpRequest request = new SimpleHttpRequest("GET", target, "/", null, null);
+        final SimpleHttpRequest request = SimpleHttpRequest.get(target, "/");
         final Future<SimpleHttpResponse> future1 = client.execute(
                 new SimpleRequestProducer(request),
                 new SimpleResponseConsumer(),

Added: httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientCustomSSL.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientCustomSSL.java?rev=1793320&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientCustomSSL.java (added)
+++ httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientCustomSSL.java Mon May  1 12:39:16 2017
@@ -0,0 +1,142 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.client5.http.examples;
+
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.concurrent.Future;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+
+import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
+import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
+import org.apache.hc.client5.http.async.methods.SimpleRequestProducer;
+import org.apache.hc.client5.http.async.methods.SimpleResponseConsumer;
+import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
+import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
+import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
+import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.client5.http.ssl.H2TlsStrategy;
+import org.apache.hc.core5.concurrent.FutureCallback;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
+import org.apache.hc.core5.io.ShutdownType;
+import org.apache.hc.core5.ssl.SSLContexts;
+import org.apache.hc.core5.ssl.TrustStrategy;
+
+/**
+ * This example demonstrates how to create secure connections with a custom SSL
+ * context.
+ */
+public class AsyncClientCustomSSL {
+
+    public final static void main(final String[] args) throws Exception {
+        // Trust standard CA and those trusted by our custom strategy
+        final SSLContext sslcontext = SSLContexts.custom()
+                .loadTrustMaterial(new TrustStrategy() {
+
+                    @Override
+                    public boolean isTrusted(
+                            final X509Certificate[] chain,
+                            final String authType) throws CertificateException {
+                        final X509Certificate cert = chain[0];
+                        return "CN=http2bin.org".equalsIgnoreCase(cert.getSubjectDN().getName());
+                    }
+
+                })
+                .build();
+        final TlsStrategy tlsStrategy = new H2TlsStrategy(
+                sslcontext,
+                H2TlsStrategy.getDefaultHostnameVerifier()) {
+
+            // IMPORTANT
+            // In order for HTTP/2 protocol negotiation to succeed one must allow access
+            // to Java 9 specific properties of SSLEngine via reflection
+            // by adding the following line to the JVM arguments
+            //
+            // --add-opens java.base/sun.security.ssl=ALL-UNNAMED
+            //
+            // or uncomment the method below
+
+//            @Override
+//            protected TlsDetails createTlsDetails(final SSLEngine sslEngine) {
+//                return new TlsDetails(sslEngine.getSession(), sslEngine.getApplicationProtocol());
+//            }
+
+        };
+        final PoolingAsyncClientConnectionManager cm = PoolingAsyncClientConnectionManagerBuilder.create()
+                .setTlsStrategy(tlsStrategy)
+                .build();
+        try (CloseableHttpAsyncClient client = HttpAsyncClients.custom()
+                .setConnectionManager(cm)
+                .build()) {
+
+            client.start();
+
+            final HttpHost target = new HttpHost("http2bin.org", 443, "https");
+            final String requestUri = "/";
+            final HttpClientContext clientContext = HttpClientContext.create();
+
+            final SimpleHttpRequest request = SimpleHttpRequest.get(target, requestUri);
+            final Future<SimpleHttpResponse> future = client.execute(
+                    new SimpleRequestProducer(request),
+                    new SimpleResponseConsumer(),
+                    clientContext,
+                    new FutureCallback<SimpleHttpResponse>() {
+
+                        @Override
+                        public void completed(final SimpleHttpResponse response) {
+                            System.out.println(requestUri + "->" + response.getCode());
+                            System.out.println(response.getBody());
+                            final SSLSession sslSession = clientContext.getSSLSession();
+                            if (sslSession != null) {
+                                System.out.println("SSL protocol " + sslSession.getProtocol());
+                                System.out.println("SSL cipher suite " + sslSession.getCipherSuite());
+                            }
+                        }
+
+                        @Override
+                        public void failed(final Exception ex) {
+                            System.out.println(requestUri + "->" + ex);
+                        }
+
+                        @Override
+                        public void cancelled() {
+                            System.out.println(requestUri + " cancelled");
+                        }
+
+                    });
+            future.get();
+
+            System.out.println("Shutting down");
+            client.shutdown(ShutdownType.GRACEFUL);
+        }
+    }
+
+}

Propchange: httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientCustomSSL.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientCustomSSL.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientCustomSSL.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp1Pipelining.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp1Pipelining.java?rev=1793320&r1=1793319&r2=1793320&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp1Pipelining.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp1Pipelining.java Mon May  1 12:39:16 2017
@@ -34,12 +34,12 @@ import org.apache.hc.client5.http.async.
 import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
 import org.apache.hc.client5.http.async.methods.SimpleRequestProducer;
 import org.apache.hc.client5.http.async.methods.SimpleResponseConsumer;
-import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
 import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
+import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
 import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.config.H1Config;
 import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
-import org.apache.hc.core5.http2.HttpVersionPolicy;
 import org.apache.hc.core5.io.ShutdownType;
 import org.apache.hc.core5.reactor.IOReactorConfig;
 import org.apache.hc.core5.util.TimeValue;
@@ -55,10 +55,7 @@ public class AsyncClientHttp1Pipelining
                 .setSoTimeout(TimeValue.ofSeconds(5))
                 .build();
 
-        final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
-                .setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_1)
-                .setIOReactorConfig(ioReactorConfig)
-                .build();
+        final MinimalHttpAsyncClient client = HttpAsyncClients.createMinimal(H1Config.DEFAULT, ioReactorConfig);
 
         client.start();
 
@@ -70,7 +67,7 @@ public class AsyncClientHttp1Pipelining
 
             final CountDownLatch latch = new CountDownLatch(requestUris.length);
             for (final String requestUri: requestUris) {
-                final SimpleHttpRequest request = new SimpleHttpRequest("GET", target, requestUri, null, null);
+                final SimpleHttpRequest request = SimpleHttpRequest.get(target, requestUri);
                 endpoint.execute(
                         new SimpleRequestProducer(request),
                         new SimpleResponseConsumer(),

Modified: httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp2Multiplexing.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp2Multiplexing.java?rev=1793320&r1=1793319&r2=1793320&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp2Multiplexing.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttp2Multiplexing.java Mon May  1 12:39:16 2017
@@ -34,12 +34,11 @@ import org.apache.hc.client5.http.async.
 import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
 import org.apache.hc.client5.http.async.methods.SimpleRequestProducer;
 import org.apache.hc.client5.http.async.methods.SimpleResponseConsumer;
-import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
 import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
+import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
 import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
-import org.apache.hc.core5.http2.HttpVersionPolicy;
 import org.apache.hc.core5.http2.config.H2Config;
 import org.apache.hc.core5.io.ShutdownType;
 import org.apache.hc.core5.reactor.IOReactorConfig;
@@ -57,15 +56,7 @@ public class AsyncClientHttp2Multiplexin
                 .setSoTimeout(TimeValue.ofSeconds(5))
                 .build();
 
-        final H2Config h2Config = H2Config.custom()
-                .setPushEnabled(false)
-                .build();
-
-        final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
-                .setIOReactorConfig(ioReactorConfig)
-                .setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_2)
-                .setH2Config(h2Config)
-                .build();
+        final MinimalHttpAsyncClient client = HttpAsyncClients.createMinimal(H2Config.DEFAULT, ioReactorConfig);
 
         client.start();
 
@@ -77,7 +68,7 @@ public class AsyncClientHttp2Multiplexin
 
             final CountDownLatch latch = new CountDownLatch(requestUris.length);
             for (final String requestUri: requestUris) {
-                final SimpleHttpRequest request = new SimpleHttpRequest("GET", target, requestUri, null, null);
+                final SimpleHttpRequest request = SimpleHttpRequest.get(target, requestUri);
                 endpoint.execute(
                         new SimpleRequestProducer(request),
                         new SimpleResponseConsumer(),

Modified: httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttpExchange.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttpExchange.java?rev=1793320&r1=1793319&r2=1793320&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttpExchange.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientHttpExchange.java Mon May  1 12:39:16 2017
@@ -30,8 +30,6 @@ import java.util.concurrent.Future;
 
 import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
 import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
-import org.apache.hc.client5.http.async.methods.SimpleRequestProducer;
-import org.apache.hc.client5.http.async.methods.SimpleResponseConsumer;
 import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
 import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
 import org.apache.hc.core5.concurrent.FutureCallback;
@@ -61,10 +59,10 @@ public class AsyncClientHttpExchange {
         final String[] requestUris = new String[] {"/", "/ip", "/user-agent", "/headers"};
 
         for (final String requestUri: requestUris) {
-            final SimpleHttpRequest request = new SimpleHttpRequest("GET", target, requestUri, null, null);
+            final SimpleHttpRequest httpget = SimpleHttpRequest.get(target, requestUri);
+            System.out.println("Executing request " + httpget.getMethod() + " " + httpget.getUri());
             final Future<SimpleHttpResponse> future = client.execute(
-                    new SimpleRequestProducer(request),
-                    new SimpleResponseConsumer(),
+                    httpget,
                     new FutureCallback<SimpleHttpResponse>() {
 
                         @Override

Added: httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientInterceptors.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientInterceptors.java?rev=1793320&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientInterceptors.java (added)
+++ httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientInterceptors.java Mon May  1 12:39:16 2017
@@ -0,0 +1,156 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.hc.client5.http.examples;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.hc.client5.http.async.AsyncExecCallback;
+import org.apache.hc.client5.http.async.AsyncExecChain;
+import org.apache.hc.client5.http.async.AsyncExecChainHandler;
+import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
+import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
+import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
+import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
+import org.apache.hc.client5.http.impl.sync.ChainElements;
+import org.apache.hc.core5.concurrent.FutureCallback;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.EntityDetails;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.HttpRequestInterceptor;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.impl.BasicEntityDetails;
+import org.apache.hc.core5.http.message.BasicHttpResponse;
+import org.apache.hc.core5.http.nio.AsyncDataConsumer;
+import org.apache.hc.core5.http.nio.AsyncEntityProducer;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.io.ShutdownType;
+import org.apache.hc.core5.reactor.IOReactorConfig;
+import org.apache.hc.core5.util.TimeValue;
+
+/**
+ * This example demonstrates how to insert custom request interceptor and an execution interceptor
+ * to the request execution chain.
+ */
+public class AsyncClientInterceptors {
+
+    public final static void main(final String[] args) throws Exception {
+
+        final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
+                .setSoTimeout(TimeValue.ofSeconds(5))
+                .build();
+
+        final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
+                .setIOReactorConfig(ioReactorConfig)
+
+                // Add a simple request ID to each outgoing request
+
+                .addRequestInterceptorFirst(new HttpRequestInterceptor() {
+
+                    private final AtomicLong count = new AtomicLong(0);
+
+                    @Override
+                    public void process(
+                            final HttpRequest request,
+                            final EntityDetails entity,
+                            final HttpContext context) throws HttpException, IOException {
+                        request.setHeader("request-id", Long.toString(count.incrementAndGet()));
+                    }
+                })
+
+                // Simulate a 404 response for some requests without passing the message down to the backend
+
+                .addExecInterceptorAfter(ChainElements.PROTOCOL.name(), "custom", new AsyncExecChainHandler() {
+
+                    @Override
+                    public void execute(
+                            final HttpRequest request,
+                            final AsyncEntityProducer requestEntityProducer,
+                            final AsyncExecChain.Scope scope,
+                            final AsyncExecChain chain,
+                            final AsyncExecCallback asyncExecCallback) throws HttpException, IOException {
+                        Header idHeader = request.getFirstHeader("request-id");
+                        if (idHeader != null && "13".equalsIgnoreCase(idHeader.getValue())) {
+                            HttpResponse response = new BasicHttpResponse(HttpStatus.SC_NOT_FOUND, "Oppsie");
+                            ByteBuffer content = ByteBuffer.wrap("bad luck".getBytes(StandardCharsets.US_ASCII));
+                            AsyncDataConsumer asyncDataConsumer = asyncExecCallback.handleResponse(
+                                    response,
+                                    new BasicEntityDetails(content.remaining(), ContentType.TEXT_PLAIN));
+                            asyncDataConsumer.consume(content);
+                            asyncDataConsumer.streamEnd(null);
+                        } else {
+                            chain.proceed(request, requestEntityProducer, scope, asyncExecCallback);
+                        }
+                    }
+
+                })
+
+                .build();
+
+        client.start();
+
+        final String requestUri = "http://httpbin.org/get";
+        for (int i = 0; i < 20; i++) {
+            final SimpleHttpRequest httpget = SimpleHttpRequest.get(requestUri);
+            System.out.println("Executing request " + httpget.getMethod() + " " + httpget.getUri());
+            final Future<SimpleHttpResponse> future = client.execute(
+                    httpget,
+                    new FutureCallback<SimpleHttpResponse>() {
+
+                        @Override
+                        public void completed(final SimpleHttpResponse response) {
+                            System.out.println(requestUri + "->" + response.getCode());
+                            System.out.println(response.getBody());
+                        }
+
+                        @Override
+                        public void failed(final Exception ex) {
+                            System.out.println(requestUri + "->" + ex);
+                        }
+
+                        @Override
+                        public void cancelled() {
+                            System.out.println(requestUri + " cancelled");
+                        }
+
+                    });
+            future.get();
+        }
+
+        System.out.println("Shutting down");
+        client.shutdown(ShutdownType.GRACEFUL);
+    }
+
+}
+

Propchange: httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientInterceptors.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientInterceptors.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientInterceptors.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Copied: httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientMessageTrailers.java (from r1793319, httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientConnectionEviction.java)
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientMessageTrailers.java?p2=httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientMessageTrailers.java&p1=httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientConnectionEviction.java&r1=1793319&r2=1793320&rev=1793320&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientConnectionEviction.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncClientMessageTrailers.java Mon May  1 12:39:16 2017
@@ -24,30 +24,40 @@
  * <http://www.apache.org/>.
  *
  */
+
 package org.apache.hc.client5.http.examples;
 
+import java.io.IOException;
 import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
 
-import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
+import org.apache.hc.client5.http.async.AsyncExecCallback;
+import org.apache.hc.client5.http.async.AsyncExecChain;
+import org.apache.hc.client5.http.async.AsyncExecChainHandler;
+import org.apache.hc.client5.http.async.methods.AsyncRequestBuilder;
 import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
-import org.apache.hc.client5.http.async.methods.SimpleRequestProducer;
 import org.apache.hc.client5.http.async.methods.SimpleResponseConsumer;
 import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
 import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
+import org.apache.hc.client5.http.impl.sync.ChainElements;
 import org.apache.hc.core5.concurrent.FutureCallback;
-import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.nio.AsyncEntityProducer;
+import org.apache.hc.core5.http.nio.AsyncRequestProducer;
+import org.apache.hc.core5.http.nio.entity.DigestingEntityProducer;
+import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
 import org.apache.hc.core5.io.ShutdownType;
 import org.apache.hc.core5.reactor.IOReactorConfig;
 import org.apache.hc.core5.util.TimeValue;
 
 /**
- * Example demonstrating how to evict expired and idle connections
- * from the connection pool.
+ * This example demonstrates how to use a custom execution interceptor
+ * to add trailers to all outgoing request enclosing an entity.
  */
-public class AsyncClientConnectionEviction {
+public class AsyncClientMessageTrailers {
 
-    public static void main(final String[] args) throws Exception {
+    public final static void main(final String[] args) throws Exception {
 
         final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
                 .setSoTimeout(TimeValue.ofSeconds(5))
@@ -55,71 +65,59 @@ public class AsyncClientConnectionEvicti
 
         final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
                 .setIOReactorConfig(ioReactorConfig)
-                .evictExpiredConnections()
-                .evictIdleConnections(TimeValue.ofSeconds(10))
-                .build();
-
-        client.start();
-
-        final HttpHost target = new HttpHost("httpbin.org");
-
-        final SimpleHttpRequest request = new SimpleHttpRequest("GET", target, "/", null, null);
-        final Future<SimpleHttpResponse> future1 = client.execute(
-                new SimpleRequestProducer(request),
-                new SimpleResponseConsumer(),
-                new FutureCallback<SimpleHttpResponse>() {
-
-                    @Override
-                    public void completed(final SimpleHttpResponse response) {
-                        System.out.println(request.getRequestUri() + "->" + response.getCode());
-                        System.out.println(response.getBody());
-                    }
+                .addExecInterceptorAfter(ChainElements.PROTOCOL.name(), "custom", new AsyncExecChainHandler() {
 
                     @Override
-                    public void failed(final Exception ex) {
-                        System.out.println(request.getRequestUri() + "->" + ex);
+                    public void execute(
+                            final HttpRequest request,
+                            final AsyncEntityProducer entityProducer,
+                            final AsyncExecChain.Scope scope,
+                            final AsyncExecChain chain,
+                            final AsyncExecCallback asyncExecCallback) throws HttpException, IOException {
+                        // Send MD5 hash in a trailer by decorating the original entity producer
+                        chain.proceed(
+                                request,
+                                entityProducer != null ? new DigestingEntityProducer("MD5", entityProducer) : null,
+                                scope,
+                                asyncExecCallback);
                     }
 
-                    @Override
-                    public void cancelled() {
-                        System.out.println(request.getRequestUri() + " cancelled");
-                    }
-
-                });
-
-        future1.get();
-
-        Thread.sleep(TimeUnit.SECONDS.toMillis(30));
+                })
+                .build();
 
-        // Previous connection should get evicted from the pool by now
+        client.start();
 
-        final Future<SimpleHttpResponse> future2 = client.execute(
-                new SimpleRequestProducer(request),
+        final String requestUri = "http://httpbin.org/post";
+        final AsyncRequestProducer requestProducer = AsyncRequestBuilder.post(requestUri)
+                .setEntity(new StringAsyncEntityProducer("some stuff", ContentType.TEXT_PLAIN))
+                .build();
+        final Future<SimpleHttpResponse> future = client.execute(
+                requestProducer,
                 new SimpleResponseConsumer(),
                 new FutureCallback<SimpleHttpResponse>() {
 
                     @Override
                     public void completed(final SimpleHttpResponse response) {
-                        System.out.println(request.getRequestUri() + "->" + response.getCode());
+                        System.out.println(requestUri + "->" + response.getCode());
                         System.out.println(response.getBody());
                     }
 
                     @Override
                     public void failed(final Exception ex) {
-                        System.out.println(request.getRequestUri() + "->" + ex);
+                        System.out.println(requestUri + "->" + ex);
                     }
 
                     @Override
                     public void cancelled() {
-                        System.out.println(request.getRequestUri() + " cancelled");
+                        System.out.println(requestUri + " cancelled");
                     }
 
                 });
-
-        future2.get();
+        future.get();
 
         System.out.println("Shutting down");
         client.shutdown(ShutdownType.GRACEFUL);
     }
 
 }
+

Added: httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncQuickStart.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncQuickStart.java?rev=1793320&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncQuickStart.java (added)
+++ httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncQuickStart.java Mon May  1 12:39:16 2017
@@ -0,0 +1,155 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.hc.client5.http.examples;
+
+
+import java.io.IOException;
+import java.nio.CharBuffer;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Future;
+
+import org.apache.hc.client5.http.async.methods.AbstractCharResponseConsumer;
+import org.apache.hc.client5.http.async.methods.AsyncRequestBuilder;
+import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
+import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
+import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
+import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
+import org.apache.hc.core5.concurrent.FutureCallback;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.nio.AsyncRequestProducer;
+
+public class AsyncQuickStart {
+
+    public static void main(String[] args) throws Exception {
+        CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();
+        try {
+            // Start the client
+            httpclient.start();
+
+            // Execute request
+            final SimpleHttpRequest request1 = SimpleHttpRequest.get("http://httpbin.org/get");
+            Future<SimpleHttpResponse> future = httpclient.execute(request1, null);
+            // and wait until response is received
+            final SimpleHttpResponse response1 = future.get();
+            System.out.println(request1.getRequestUri() + "->" + response1.getCode());
+
+            // One most likely would want to use a callback for operation result
+            final CountDownLatch latch1 = new CountDownLatch(1);
+            final SimpleHttpRequest request2 = SimpleHttpRequest.get("http://httpbin.org/get");
+            httpclient.execute(request2, new FutureCallback<SimpleHttpResponse>() {
+
+                @Override
+                public void completed(final SimpleHttpResponse response2) {
+                    latch1.countDown();
+                    System.out.println(request2.getRequestUri() + "->" + response2.getCode());
+                }
+
+                @Override
+                public void failed(final Exception ex) {
+                    latch1.countDown();
+                    System.out.println(request2.getRequestUri() + "->" + ex);
+                }
+
+                @Override
+                public void cancelled() {
+                    latch1.countDown();
+                    System.out.println(request2.getRequestUri() + " cancelled");
+                }
+
+            });
+            latch1.await();
+
+            // In real world one most likely would want also want to stream
+            // request and response body content
+            final CountDownLatch latch2 = new CountDownLatch(1);
+            AsyncRequestProducer producer3 = AsyncRequestBuilder.get("http://httpbin.org/get").build();
+            AbstractCharResponseConsumer<HttpResponse> consumer3 = new AbstractCharResponseConsumer<HttpResponse>() {
+
+                HttpResponse response;
+
+                @Override
+                protected void start(final HttpResponse response, final ContentType contentType) throws HttpException, IOException {
+                    this.response = response;
+                }
+
+                @Override
+                protected int capacity() {
+                    return Integer.MAX_VALUE;
+                }
+
+                @Override
+                protected void data(final CharBuffer data, final boolean endOfStream) throws IOException {
+                    // Do something useful
+                }
+
+                @Override
+                protected HttpResponse buildResult() throws IOException {
+                    return response;
+                }
+
+                @Override
+                public HttpResponse getResult() {
+                    return response;
+                }
+
+                @Override
+                public void releaseResources() {
+                }
+
+            };
+            httpclient.execute(producer3, consumer3, new FutureCallback<HttpResponse>() {
+
+                @Override
+                public void completed(final HttpResponse response3) {
+                    latch2.countDown();
+                    System.out.println(request2.getRequestUri() + "->" + response3.getCode());
+                }
+
+                @Override
+                public void failed(final Exception ex) {
+                    latch2.countDown();
+                    System.out.println(request2.getRequestUri() + "->" + ex);
+                }
+
+                @Override
+                public void cancelled() {
+                    latch2.countDown();
+                    System.out.println(request2.getRequestUri() + " cancelled");
+                }
+
+            });
+            latch2.await();
+
+        } finally {
+            httpclient.close();
+        }
+    }
+
+}
\ No newline at end of file

Propchange: httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncQuickStart.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncQuickStart.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpclient/trunk/httpclient5/src/examples/org/apache/hc/client5/http/examples/AsyncQuickStart.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



Mime
View raw message