From commits-return-11766-archive-asf-public=cust-asf.ponee.io@hc.apache.org Thu Jan 4 11:32:00 2018 Return-Path: X-Original-To: archive-asf-public@eu.ponee.io Delivered-To: archive-asf-public@eu.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by mx-eu-01.ponee.io (Postfix) with ESMTP id A46F5180657 for ; Thu, 4 Jan 2018 11:32:00 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 942B5160C3A; Thu, 4 Jan 2018 10:32:00 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id E0774160C28 for ; Thu, 4 Jan 2018 11:31:58 +0100 (CET) Received: (qmail 90746 invoked by uid 500); 4 Jan 2018 10:31:58 -0000 Mailing-List: contact commits-help@hc.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "HttpComponents Project" Delivered-To: mailing list commits@hc.apache.org Received: (qmail 90737 invoked by uid 99); 4 Jan 2018 10:31:58 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 04 Jan 2018 10:31:58 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id EEB43DFC3E; Thu, 4 Jan 2018 10:31:57 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: olegk@apache.org To: commits@hc.apache.org Date: Thu, 04 Jan 2018 10:31:57 -0000 Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: [1/2] httpcomponents-client git commit: Renamed ExecRuntimeImpl to InternalExecRuntime (no functional changes) Repository: httpcomponents-client Updated Branches: refs/heads/master 47a0eb8b6 -> 1c7328098 Renamed ExecRuntimeImpl to InternalExecRuntime (no functional changes) Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/repo Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/commit/26bb4b6b Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/tree/26bb4b6b Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/diff/26bb4b6b Branch: refs/heads/master Commit: 26bb4b6b9c7b6365e236e014e154a20c01775fb0 Parents: 47a0eb8 Author: Oleg Kalnichevski Authored: Thu Jan 4 10:37:00 2018 +0100 Committer: Oleg Kalnichevski Committed: Thu Jan 4 10:37:00 2018 +0100 ---------------------------------------------------------------------- .../http/impl/classic/ExecRuntimeImpl.java | 258 ---------------- .../http/impl/classic/InternalExecRuntime.java | 258 ++++++++++++++++ .../http/impl/classic/InternalHttpClient.java | 2 +- .../http/impl/classic/MinimalHttpClient.java | 2 +- .../http/impl/classic/TestExecRuntimeImpl.java | 307 ------------------- .../impl/classic/TestInternalExecRuntime.java | 307 +++++++++++++++++++ 6 files changed, 567 insertions(+), 567 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/26bb4b6b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ExecRuntimeImpl.java ---------------------------------------------------------------------- diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ExecRuntimeImpl.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ExecRuntimeImpl.java deleted file mode 100644 index 86c8f3a..0000000 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ExecRuntimeImpl.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * ==================================================================== - * 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 - * . - * - */ - -package org.apache.hc.client5.http.impl.classic; - -import java.io.IOException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicReference; - -import org.apache.hc.client5.http.CancellableAware; -import org.apache.hc.client5.http.HttpRoute; -import org.apache.hc.client5.http.classic.ExecRuntime; -import org.apache.hc.client5.http.config.RequestConfig; -import org.apache.hc.client5.http.io.ConnectionEndpoint; -import org.apache.hc.client5.http.io.HttpClientConnectionManager; -import org.apache.hc.client5.http.io.LeaseRequest; -import org.apache.hc.client5.http.protocol.HttpClientContext; -import org.apache.hc.core5.concurrent.Cancellable; -import org.apache.hc.core5.http.ClassicHttpRequest; -import org.apache.hc.core5.http.ClassicHttpResponse; -import org.apache.hc.core5.http.ConnectionRequestTimeoutException; -import org.apache.hc.core5.http.HttpException; -import org.apache.hc.core5.http.impl.io.HttpRequestExecutor; -import org.apache.hc.core5.io.ShutdownType; -import org.apache.hc.core5.util.Args; -import org.apache.hc.core5.util.TimeValue; -import org.apache.hc.core5.util.Timeout; -import org.apache.logging.log4j.Logger; - -class ExecRuntimeImpl implements ExecRuntime, Cancellable { - - private final Logger log; - - private final HttpClientConnectionManager manager; - private final HttpRequestExecutor requestExecutor; - private final CancellableAware cancellableAware; - private final AtomicReference endpointRef; - - private volatile boolean reusable; - private volatile Object state; - private volatile TimeValue validDuration; - - ExecRuntimeImpl( - final Logger log, - final HttpClientConnectionManager manager, - final HttpRequestExecutor requestExecutor, - final CancellableAware cancellableAware) { - super(); - this.log = log; - this.manager = manager; - this.requestExecutor = requestExecutor; - this.cancellableAware = cancellableAware; - this.endpointRef = new AtomicReference<>(null); - this.validDuration = TimeValue.NEG_ONE_MILLISECONDS; - } - - @Override - public boolean isExecutionAborted() { - return cancellableAware != null && cancellableAware.isCancelled(); - } - - @Override - public boolean isConnectionAcquired() { - return endpointRef.get() != null; - } - - @Override - public void acquireConnection(final HttpRoute route, final Object object, final HttpClientContext context) throws IOException { - Args.notNull(route, "Route"); - if (endpointRef.get() == null) { - final RequestConfig requestConfig = context.getRequestConfig(); - final Timeout requestTimeout = requestConfig.getConnectionRequestTimeout(); - final LeaseRequest connRequest = manager.lease(route, requestTimeout, object); - state = object; - if (cancellableAware != null) { - if (cancellableAware.isCancelled()) { - connRequest.cancel(); - throw new RequestFailedException("Request aborted"); - } - cancellableAware.setCancellable(connRequest); - } - try { - final ConnectionEndpoint connectionEndpoint = connRequest.get(requestTimeout.getDuration(), requestTimeout.getTimeUnit()); - endpointRef.set(connectionEndpoint); - reusable = connectionEndpoint.isConnected(); - if (cancellableAware != null) { - cancellableAware.setCancellable(this); - } - } catch(final TimeoutException ex) { - throw new ConnectionRequestTimeoutException(ex.getMessage()); - } catch(final InterruptedException interrupted) { - Thread.currentThread().interrupt(); - throw new RequestFailedException("Request aborted", interrupted); - } catch(final ExecutionException ex) { - Throwable cause = ex.getCause(); - if (cause == null) { - cause = ex; - } - throw new RequestFailedException("Request execution failed", cause); - } - } else { - throw new IllegalStateException("Endpoint already acquired"); - } - } - - ConnectionEndpoint ensureValid() { - final ConnectionEndpoint endpoint = endpointRef.get(); - if (endpoint == null) { - throw new IllegalStateException("Endpoint not acquired / already released"); - } - return endpoint; - } - - @Override - public boolean isConnected() { - final ConnectionEndpoint endpoint = endpointRef.get(); - return endpoint != null && endpoint.isConnected(); - } - - private void connectEndpoint(final ConnectionEndpoint endpoint, final HttpClientContext context) throws IOException { - if (cancellableAware != null) { - if (cancellableAware.isCancelled()) { - throw new RequestFailedException("Request aborted"); - } - } - final RequestConfig requestConfig = context.getRequestConfig(); - final TimeValue timeout = requestConfig.getConnectionTimeout(); - manager.connect(endpoint, timeout, context); - if (TimeValue.isPositive(timeout)) { - endpoint.setSocketTimeout(timeout.toMillisIntBound()); - } - } - - @Override - public void connect(final HttpClientContext context) throws IOException { - final ConnectionEndpoint endpoint = ensureValid(); - if (!endpoint.isConnected()) { - connectEndpoint(endpoint, context); - } - } - - @Override - public void disconnect() throws IOException { - final ConnectionEndpoint endpoint = endpointRef.get(); - if (endpoint != null) { - endpoint.close(); - log.debug("Disconnected"); - } - } - - @Override - public void upgradeTls(final HttpClientContext context) throws IOException { - final ConnectionEndpoint endpoint = ensureValid(); - manager.upgrade(endpoint, context); - } - - @Override - public ClassicHttpResponse execute(final ClassicHttpRequest request, final HttpClientContext context) throws IOException, HttpException { - final ConnectionEndpoint endpoint = ensureValid(); - if (!endpoint.isConnected()) { - connectEndpoint(endpoint, context); - } - return endpoint.execute(request, requestExecutor, context); - } - - @Override - public boolean isConnectionReusable() { - return reusable; - } - - @Override - public void markConnectionReusable() { - reusable = true; - } - - @Override - public void markConnectionNonReusable() { - reusable = false; - } - - @Override - public void setConnectionState(final Object state) { - this.state = state; - } - - @Override - public void setConnectionValidFor(final TimeValue duration) { - validDuration = duration; - } - - @Override - public void releaseConnection() { - final ConnectionEndpoint endpoint = endpointRef.getAndSet(null); - if (endpoint != null) { - if (reusable) { - manager.release(endpoint, state, validDuration); - } else { - try { - endpoint.close(); - log.debug("Connection discarded"); - } catch (final IOException ex) { - if (log.isDebugEnabled()) { - log.debug(ex.getMessage(), ex); - } - } finally { - manager.release(endpoint, null, TimeValue.ZERO_MILLISECONDS); - } - } - } - } - - @Override - public void discardConnection() { - final ConnectionEndpoint endpoint = endpointRef.getAndSet(null); - if (endpoint != null) { - try { - endpoint.shutdown(ShutdownType.IMMEDIATE); - log.debug("Connection discarded"); - } finally { - manager.release(endpoint, null, TimeValue.ZERO_MILLISECONDS); - } - } - } - - @Override - public boolean cancel() { - final boolean alreadyReleased = endpointRef.get() == null; - log.debug("Cancelling request execution"); - discardConnection(); - return !alreadyReleased; - } - -} http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/26bb4b6b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalExecRuntime.java ---------------------------------------------------------------------- diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalExecRuntime.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalExecRuntime.java new file mode 100644 index 0000000..b47713a --- /dev/null +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalExecRuntime.java @@ -0,0 +1,258 @@ +/* + * ==================================================================== + * 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 + * . + * + */ + +package org.apache.hc.client5.http.impl.classic; + +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicReference; + +import org.apache.hc.client5.http.CancellableAware; +import org.apache.hc.client5.http.HttpRoute; +import org.apache.hc.client5.http.classic.ExecRuntime; +import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.io.ConnectionEndpoint; +import org.apache.hc.client5.http.io.HttpClientConnectionManager; +import org.apache.hc.client5.http.io.LeaseRequest; +import org.apache.hc.client5.http.protocol.HttpClientContext; +import org.apache.hc.core5.concurrent.Cancellable; +import org.apache.hc.core5.http.ClassicHttpRequest; +import org.apache.hc.core5.http.ClassicHttpResponse; +import org.apache.hc.core5.http.ConnectionRequestTimeoutException; +import org.apache.hc.core5.http.HttpException; +import org.apache.hc.core5.http.impl.io.HttpRequestExecutor; +import org.apache.hc.core5.io.ShutdownType; +import org.apache.hc.core5.util.Args; +import org.apache.hc.core5.util.TimeValue; +import org.apache.hc.core5.util.Timeout; +import org.apache.logging.log4j.Logger; + +class InternalExecRuntime implements ExecRuntime, Cancellable { + + private final Logger log; + + private final HttpClientConnectionManager manager; + private final HttpRequestExecutor requestExecutor; + private final CancellableAware cancellableAware; + private final AtomicReference endpointRef; + + private volatile boolean reusable; + private volatile Object state; + private volatile TimeValue validDuration; + + InternalExecRuntime( + final Logger log, + final HttpClientConnectionManager manager, + final HttpRequestExecutor requestExecutor, + final CancellableAware cancellableAware) { + super(); + this.log = log; + this.manager = manager; + this.requestExecutor = requestExecutor; + this.cancellableAware = cancellableAware; + this.endpointRef = new AtomicReference<>(null); + this.validDuration = TimeValue.NEG_ONE_MILLISECONDS; + } + + @Override + public boolean isExecutionAborted() { + return cancellableAware != null && cancellableAware.isCancelled(); + } + + @Override + public boolean isConnectionAcquired() { + return endpointRef.get() != null; + } + + @Override + public void acquireConnection(final HttpRoute route, final Object object, final HttpClientContext context) throws IOException { + Args.notNull(route, "Route"); + if (endpointRef.get() == null) { + final RequestConfig requestConfig = context.getRequestConfig(); + final Timeout requestTimeout = requestConfig.getConnectionRequestTimeout(); + final LeaseRequest connRequest = manager.lease(route, requestTimeout, object); + state = object; + if (cancellableAware != null) { + if (cancellableAware.isCancelled()) { + connRequest.cancel(); + throw new RequestFailedException("Request aborted"); + } + cancellableAware.setCancellable(connRequest); + } + try { + final ConnectionEndpoint connectionEndpoint = connRequest.get(requestTimeout.getDuration(), requestTimeout.getTimeUnit()); + endpointRef.set(connectionEndpoint); + reusable = connectionEndpoint.isConnected(); + if (cancellableAware != null) { + cancellableAware.setCancellable(this); + } + } catch(final TimeoutException ex) { + throw new ConnectionRequestTimeoutException(ex.getMessage()); + } catch(final InterruptedException interrupted) { + Thread.currentThread().interrupt(); + throw new RequestFailedException("Request aborted", interrupted); + } catch(final ExecutionException ex) { + Throwable cause = ex.getCause(); + if (cause == null) { + cause = ex; + } + throw new RequestFailedException("Request execution failed", cause); + } + } else { + throw new IllegalStateException("Endpoint already acquired"); + } + } + + ConnectionEndpoint ensureValid() { + final ConnectionEndpoint endpoint = endpointRef.get(); + if (endpoint == null) { + throw new IllegalStateException("Endpoint not acquired / already released"); + } + return endpoint; + } + + @Override + public boolean isConnected() { + final ConnectionEndpoint endpoint = endpointRef.get(); + return endpoint != null && endpoint.isConnected(); + } + + private void connectEndpoint(final ConnectionEndpoint endpoint, final HttpClientContext context) throws IOException { + if (cancellableAware != null) { + if (cancellableAware.isCancelled()) { + throw new RequestFailedException("Request aborted"); + } + } + final RequestConfig requestConfig = context.getRequestConfig(); + final TimeValue timeout = requestConfig.getConnectionTimeout(); + manager.connect(endpoint, timeout, context); + if (TimeValue.isPositive(timeout)) { + endpoint.setSocketTimeout(timeout.toMillisIntBound()); + } + } + + @Override + public void connect(final HttpClientContext context) throws IOException { + final ConnectionEndpoint endpoint = ensureValid(); + if (!endpoint.isConnected()) { + connectEndpoint(endpoint, context); + } + } + + @Override + public void disconnect() throws IOException { + final ConnectionEndpoint endpoint = endpointRef.get(); + if (endpoint != null) { + endpoint.close(); + log.debug("Disconnected"); + } + } + + @Override + public void upgradeTls(final HttpClientContext context) throws IOException { + final ConnectionEndpoint endpoint = ensureValid(); + manager.upgrade(endpoint, context); + } + + @Override + public ClassicHttpResponse execute(final ClassicHttpRequest request, final HttpClientContext context) throws IOException, HttpException { + final ConnectionEndpoint endpoint = ensureValid(); + if (!endpoint.isConnected()) { + connectEndpoint(endpoint, context); + } + return endpoint.execute(request, requestExecutor, context); + } + + @Override + public boolean isConnectionReusable() { + return reusable; + } + + @Override + public void markConnectionReusable() { + reusable = true; + } + + @Override + public void markConnectionNonReusable() { + reusable = false; + } + + @Override + public void setConnectionState(final Object state) { + this.state = state; + } + + @Override + public void setConnectionValidFor(final TimeValue duration) { + validDuration = duration; + } + + @Override + public void releaseConnection() { + final ConnectionEndpoint endpoint = endpointRef.getAndSet(null); + if (endpoint != null) { + if (reusable) { + manager.release(endpoint, state, validDuration); + } else { + try { + endpoint.close(); + log.debug("Connection discarded"); + } catch (final IOException ex) { + if (log.isDebugEnabled()) { + log.debug(ex.getMessage(), ex); + } + } finally { + manager.release(endpoint, null, TimeValue.ZERO_MILLISECONDS); + } + } + } + } + + @Override + public void discardConnection() { + final ConnectionEndpoint endpoint = endpointRef.getAndSet(null); + if (endpoint != null) { + try { + endpoint.shutdown(ShutdownType.IMMEDIATE); + log.debug("Connection discarded"); + } finally { + manager.release(endpoint, null, TimeValue.ZERO_MILLISECONDS); + } + } + } + + @Override + public boolean cancel() { + final boolean alreadyReleased = endpointRef.get() == null; + log.debug("Cancelling request execution"); + discardConnection(); + return !alreadyReleased; + } + +} http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/26bb4b6b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalHttpClient.java ---------------------------------------------------------------------- diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalHttpClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalHttpClient.java index 46d99e1..ecab405 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalHttpClient.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/InternalHttpClient.java @@ -159,7 +159,7 @@ class InternalHttpClient extends CloseableHttpClient implements Configurable { setupContext(localcontext); final HttpRoute route = determineRoute(target, request, localcontext); final String exchangeId = String.format("ex-%08X", ExecSupport.getNextExecNumber()); - final ExecRuntime execRuntime = new ExecRuntimeImpl(log, connManager, requestExecutor, + final ExecRuntime execRuntime = new InternalExecRuntime(log, connManager, requestExecutor, request instanceof CancellableAware ? (CancellableAware) request : null); final ExecChain.Scope scope = new ExecChain.Scope(exchangeId, route, request, execRuntime, localcontext); final ClassicHttpResponse response = this.execChain.execute(ClassicRequestCopier.INSTANCE.copy(request), scope); http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/26bb4b6b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/MinimalHttpClient.java ---------------------------------------------------------------------- diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/MinimalHttpClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/MinimalHttpClient.java index 4c39405..a34ea27 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/MinimalHttpClient.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/MinimalHttpClient.java @@ -121,7 +121,7 @@ public class MinimalHttpClient extends CloseableHttpClient { } final HttpRoute route = new HttpRoute(RoutingSupport.normalize(target, schemePortResolver)); - final ExecRuntime execRuntime = new ExecRuntimeImpl(log, connManager, requestExecutor, + final ExecRuntime execRuntime = new InternalExecRuntime(log, connManager, requestExecutor, request instanceof CancellableAware ? (CancellableAware) request : null); try { if (!execRuntime.isConnectionAcquired()) { http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/26bb4b6b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestExecRuntimeImpl.java ---------------------------------------------------------------------- diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestExecRuntimeImpl.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestExecRuntimeImpl.java deleted file mode 100644 index 07cc652..0000000 --- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestExecRuntimeImpl.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * ==================================================================== - * 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 - * . - * - */ -package org.apache.hc.client5.http.impl.classic; - -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import org.apache.hc.client5.http.CancellableAware; -import org.apache.hc.client5.http.HttpRoute; -import org.apache.hc.client5.http.config.RequestConfig; -import org.apache.hc.client5.http.io.ConnectionEndpoint; -import org.apache.hc.client5.http.io.HttpClientConnectionManager; -import org.apache.hc.client5.http.io.LeaseRequest; -import org.apache.hc.client5.http.protocol.HttpClientContext; -import org.apache.hc.core5.concurrent.Cancellable; -import org.apache.hc.core5.http.ConnectionRequestTimeoutException; -import org.apache.hc.core5.http.HttpHost; -import org.apache.hc.core5.http.impl.io.HttpRequestExecutor; -import org.apache.hc.core5.io.ShutdownType; -import org.apache.hc.core5.util.TimeValue; -import org.apache.hc.core5.util.Timeout; -import org.apache.logging.log4j.Logger; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.MockitoAnnotations; - -@SuppressWarnings({"static-access"}) // test code -public class TestExecRuntimeImpl { - - @Mock - private Logger log; - @Mock - private HttpClientConnectionManager mgr; - @Mock - private LeaseRequest leaseRequest; - @Mock - private HttpRequestExecutor requestExecutor; - @Mock - private CancellableAware cancellableAware; - @Mock - private ConnectionEndpoint connectionEndpoint; - - private HttpRoute route; - private ExecRuntimeImpl execRuntime; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - route = new HttpRoute(new HttpHost("host", 80)); - execRuntime = new ExecRuntimeImpl(log, mgr, requestExecutor, cancellableAware); - } - - @Test - public void testAcquireEndpoint() throws Exception { - final HttpClientContext context = HttpClientContext.create(); - final RequestConfig config = RequestConfig.custom() - .setConnectTimeout(123, TimeUnit.MILLISECONDS) - .setConnectionRequestTimeout(345, TimeUnit.MILLISECONDS) - .build(); - context.setRequestConfig(config); - final HttpRoute route = new HttpRoute(new HttpHost("host", 80)); - - Mockito.when(mgr.lease(Mockito.eq(route), Mockito.any(), Mockito.any())).thenReturn(leaseRequest); - Mockito.when(leaseRequest.get( - Mockito.anyLong(), Mockito.any())).thenReturn(connectionEndpoint); - - execRuntime.acquireConnection(route, null, context); - - Assert.assertTrue(execRuntime.isConnectionAcquired()); - Assert.assertSame(connectionEndpoint, execRuntime.ensureValid()); - Assert.assertFalse(execRuntime.isConnected()); - Assert.assertFalse(execRuntime.isConnectionReusable()); - - Mockito.verify(leaseRequest).get(345, TimeUnit.MILLISECONDS); - Mockito.verify(cancellableAware, Mockito.times(1)).setCancellable(leaseRequest); - Mockito.verify(cancellableAware, Mockito.times(1)).setCancellable(execRuntime); - Mockito.verify(cancellableAware, Mockito.times(2)).setCancellable(Mockito.any()); - } - - @Test(expected = IllegalStateException.class) - public void testAcquireEndpointAlreadyAcquired() throws Exception { - final HttpClientContext context = HttpClientContext.create(); - - Mockito.when(mgr.lease(Mockito.eq(route), Mockito.any(), Mockito.any())).thenReturn(leaseRequest); - Mockito.when(leaseRequest.get( - Mockito.anyLong(), Mockito.any())).thenReturn(connectionEndpoint); - - execRuntime.acquireConnection(route, null, context); - - Assert.assertTrue(execRuntime.isConnectionAcquired()); - Assert.assertSame(connectionEndpoint, execRuntime.ensureValid()); - - execRuntime.acquireConnection(route, null, context); - } - - @Test(expected = ConnectionRequestTimeoutException.class) - public void testAcquireEndpointLeaseRequestTimeout() throws Exception { - final HttpClientContext context = HttpClientContext.create(); - - Mockito.when(mgr.lease(Mockito.eq(route), Mockito.any(), Mockito.any())).thenReturn(leaseRequest); - Mockito.when(leaseRequest.get( - Mockito.anyLong(), Mockito.any())).thenThrow(new TimeoutException()); - - execRuntime.acquireConnection(route, null, context); - } - - @Test(expected = RequestFailedException.class) - public void testAcquireEndpointLeaseRequestFailure() throws Exception { - final HttpClientContext context = HttpClientContext.create(); - - Mockito.when(mgr.lease(Mockito.eq(route), Mockito.any(), Mockito.any())).thenReturn(leaseRequest); - Mockito.when(leaseRequest.get( - Mockito.anyLong(), Mockito.any())).thenThrow(new ExecutionException(new IllegalStateException())); - - execRuntime.acquireConnection(route, null, context); - } - - @Test - public void testAbortEndpoint() throws Exception { - final HttpClientContext context = HttpClientContext.create(); - Mockito.when(mgr.lease(Mockito.eq(route), Mockito.any(), Mockito.any())).thenReturn(leaseRequest); - Mockito.when(leaseRequest.get( - Mockito.anyLong(), Mockito.any())).thenReturn(connectionEndpoint); - - execRuntime.acquireConnection(new HttpRoute(new HttpHost("host", 80)), null, context); - Assert.assertTrue(execRuntime.isConnectionAcquired()); - execRuntime.discardConnection(); - - Assert.assertFalse(execRuntime.isConnectionAcquired()); - - Mockito.verify(connectionEndpoint).shutdown(ShutdownType.IMMEDIATE); - Mockito.verify(mgr).release(connectionEndpoint, null, TimeValue.ZERO_MILLISECONDS); - - execRuntime.discardConnection(); - - Mockito.verify(connectionEndpoint, Mockito.times(1)).shutdown(ShutdownType.IMMEDIATE); - Mockito.verify(mgr, Mockito.times(1)).release( - Mockito.any(), - Mockito.any(), - Mockito.any()); - } - - @Test - public void testCancell() throws Exception { - final HttpClientContext context = HttpClientContext.create(); - - Mockito.when(mgr.lease(Mockito.eq(route), Mockito.any(), Mockito.any())).thenReturn(leaseRequest); - Mockito.when(leaseRequest.get( - Mockito.anyLong(), Mockito.any())).thenReturn(connectionEndpoint); - - execRuntime.acquireConnection(route, null, context); - Assert.assertTrue(execRuntime.isConnectionAcquired()); - - Assert.assertTrue(execRuntime.cancel()); - - Assert.assertFalse(execRuntime.isConnectionAcquired()); - - Mockito.verify(connectionEndpoint).shutdown(ShutdownType.IMMEDIATE); - Mockito.verify(mgr).release(connectionEndpoint, null, TimeValue.ZERO_MILLISECONDS); - - Assert.assertFalse(execRuntime.cancel()); - - Mockito.verify(connectionEndpoint, Mockito.times(1)).shutdown(ShutdownType.IMMEDIATE); - Mockito.verify(mgr, Mockito.times(1)).release( - Mockito.any(), - Mockito.any(), - Mockito.any()); - } - - @Test - public void testReleaseEndpointReusable() throws Exception { - final HttpClientContext context = HttpClientContext.create(); - - Mockito.when(mgr.lease(Mockito.eq(route), Mockito.any(), Mockito.any())).thenReturn(leaseRequest); - Mockito.when(leaseRequest.get( - Mockito.anyLong(), Mockito.any())).thenReturn(connectionEndpoint); - - execRuntime.acquireConnection(route, null, context); - Assert.assertTrue(execRuntime.isConnectionAcquired()); - - execRuntime.setConnectionState("some state"); - execRuntime.setConnectionValidFor(TimeValue.ofMillis(100000)); - execRuntime.markConnectionReusable(); - - execRuntime.releaseConnection(); - - Assert.assertFalse(execRuntime.isConnectionAcquired()); - - Mockito.verify(connectionEndpoint, Mockito.never()).close(); - Mockito.verify(mgr).release(connectionEndpoint, "some state", TimeValue.ofMillis(100000)); - - execRuntime.releaseConnection(); - - Mockito.verify(mgr, Mockito.times(1)).release( - Mockito.any(), - Mockito.any(), - Mockito.any()); - } - - @Test - public void testReleaseEndpointNonReusable() throws Exception { - final HttpClientContext context = HttpClientContext.create(); - - Mockito.when(mgr.lease(Mockito.eq(route), Mockito.any(), Mockito.any())).thenReturn(leaseRequest); - Mockito.when(leaseRequest.get( - Mockito.anyLong(), Mockito.any())).thenReturn(connectionEndpoint); - - execRuntime.acquireConnection(route, null, context); - Assert.assertTrue(execRuntime.isConnectionAcquired()); - - execRuntime.setConnectionState("some state"); - execRuntime.setConnectionValidFor(TimeValue.ofMillis(100000)); - execRuntime.markConnectionNonReusable(); - - execRuntime.releaseConnection(); - - Assert.assertFalse(execRuntime.isConnectionAcquired()); - - Mockito.verify(connectionEndpoint, Mockito.times(1)).close(); - Mockito.verify(mgr).release(connectionEndpoint, null, TimeValue.ZERO_MILLISECONDS); - - execRuntime.releaseConnection(); - - Mockito.verify(mgr, Mockito.times(1)).release( - Mockito.any(), - Mockito.any(), - Mockito.any()); - } - - @Test - public void testConnectEndpoint() throws Exception { - final HttpClientContext context = HttpClientContext.create(); - final RequestConfig config = RequestConfig.custom() - .setConnectTimeout(123, TimeUnit.MILLISECONDS) - .setConnectionRequestTimeout(345, TimeUnit.MILLISECONDS) - .build(); - context.setRequestConfig(config); - - Mockito.when(mgr.lease(Mockito.eq(route), Mockito.any(), Mockito.any())).thenReturn(leaseRequest); - Mockito.when(leaseRequest.get( - Mockito.anyLong(), Mockito.any())).thenReturn(connectionEndpoint); - - execRuntime.acquireConnection(route, null, context); - Assert.assertTrue(execRuntime.isConnectionAcquired()); - - Mockito.when(connectionEndpoint.isConnected()).thenReturn(false); - Assert.assertFalse(execRuntime.isConnected()); - - execRuntime.connect(context); - - Mockito.verify(mgr).connect(connectionEndpoint, TimeValue.ofMillis(123), context); - Mockito.verify(connectionEndpoint).setSocketTimeout(123); - } - - @Test - public void testDisonnectEndpoint() throws Exception { - final HttpClientContext context = HttpClientContext.create(); - - Mockito.when(mgr.lease(Mockito.eq(route), Mockito.any(), Mockito.any())).thenReturn(leaseRequest); - Mockito.when(leaseRequest.get( - Mockito.anyLong(), Mockito.any())).thenReturn(connectionEndpoint); - - execRuntime.acquireConnection(route, null, context); - Assert.assertTrue(execRuntime.isConnectionAcquired()); - - Mockito.when(connectionEndpoint.isConnected()).thenReturn(true); - Assert.assertTrue(execRuntime.isConnected()); - - execRuntime.connect(context); - - Mockito.verify(mgr, Mockito.never()).connect( - Mockito.same(connectionEndpoint), Mockito.any(), Mockito.any()); - - execRuntime.disconnect(); - - Mockito.verify(connectionEndpoint).close(); - } - -} http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/26bb4b6b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestInternalExecRuntime.java ---------------------------------------------------------------------- diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestInternalExecRuntime.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestInternalExecRuntime.java new file mode 100644 index 0000000..e11a534 --- /dev/null +++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestInternalExecRuntime.java @@ -0,0 +1,307 @@ +/* + * ==================================================================== + * 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 + * . + * + */ +package org.apache.hc.client5.http.impl.classic; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.apache.hc.client5.http.CancellableAware; +import org.apache.hc.client5.http.HttpRoute; +import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.io.ConnectionEndpoint; +import org.apache.hc.client5.http.io.HttpClientConnectionManager; +import org.apache.hc.client5.http.io.LeaseRequest; +import org.apache.hc.client5.http.protocol.HttpClientContext; +import org.apache.hc.core5.concurrent.Cancellable; +import org.apache.hc.core5.http.ConnectionRequestTimeoutException; +import org.apache.hc.core5.http.HttpHost; +import org.apache.hc.core5.http.impl.io.HttpRequestExecutor; +import org.apache.hc.core5.io.ShutdownType; +import org.apache.hc.core5.util.TimeValue; +import org.apache.hc.core5.util.Timeout; +import org.apache.logging.log4j.Logger; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +@SuppressWarnings({"static-access"}) // test code +public class TestInternalExecRuntime { + + @Mock + private Logger log; + @Mock + private HttpClientConnectionManager mgr; + @Mock + private LeaseRequest leaseRequest; + @Mock + private HttpRequestExecutor requestExecutor; + @Mock + private CancellableAware cancellableAware; + @Mock + private ConnectionEndpoint connectionEndpoint; + + private HttpRoute route; + private InternalExecRuntime execRuntime; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + route = new HttpRoute(new HttpHost("host", 80)); + execRuntime = new InternalExecRuntime(log, mgr, requestExecutor, cancellableAware); + } + + @Test + public void testAcquireEndpoint() throws Exception { + final HttpClientContext context = HttpClientContext.create(); + final RequestConfig config = RequestConfig.custom() + .setConnectTimeout(123, TimeUnit.MILLISECONDS) + .setConnectionRequestTimeout(345, TimeUnit.MILLISECONDS) + .build(); + context.setRequestConfig(config); + final HttpRoute route = new HttpRoute(new HttpHost("host", 80)); + + Mockito.when(mgr.lease(Mockito.eq(route), Mockito.any(), Mockito.any())).thenReturn(leaseRequest); + Mockito.when(leaseRequest.get( + Mockito.anyLong(), Mockito.any())).thenReturn(connectionEndpoint); + + execRuntime.acquireConnection(route, null, context); + + Assert.assertTrue(execRuntime.isConnectionAcquired()); + Assert.assertSame(connectionEndpoint, execRuntime.ensureValid()); + Assert.assertFalse(execRuntime.isConnected()); + Assert.assertFalse(execRuntime.isConnectionReusable()); + + Mockito.verify(leaseRequest).get(345, TimeUnit.MILLISECONDS); + Mockito.verify(cancellableAware, Mockito.times(1)).setCancellable(leaseRequest); + Mockito.verify(cancellableAware, Mockito.times(1)).setCancellable(execRuntime); + Mockito.verify(cancellableAware, Mockito.times(2)).setCancellable(Mockito.any()); + } + + @Test(expected = IllegalStateException.class) + public void testAcquireEndpointAlreadyAcquired() throws Exception { + final HttpClientContext context = HttpClientContext.create(); + + Mockito.when(mgr.lease(Mockito.eq(route), Mockito.any(), Mockito.any())).thenReturn(leaseRequest); + Mockito.when(leaseRequest.get( + Mockito.anyLong(), Mockito.any())).thenReturn(connectionEndpoint); + + execRuntime.acquireConnection(route, null, context); + + Assert.assertTrue(execRuntime.isConnectionAcquired()); + Assert.assertSame(connectionEndpoint, execRuntime.ensureValid()); + + execRuntime.acquireConnection(route, null, context); + } + + @Test(expected = ConnectionRequestTimeoutException.class) + public void testAcquireEndpointLeaseRequestTimeout() throws Exception { + final HttpClientContext context = HttpClientContext.create(); + + Mockito.when(mgr.lease(Mockito.eq(route), Mockito.any(), Mockito.any())).thenReturn(leaseRequest); + Mockito.when(leaseRequest.get( + Mockito.anyLong(), Mockito.any())).thenThrow(new TimeoutException()); + + execRuntime.acquireConnection(route, null, context); + } + + @Test(expected = RequestFailedException.class) + public void testAcquireEndpointLeaseRequestFailure() throws Exception { + final HttpClientContext context = HttpClientContext.create(); + + Mockito.when(mgr.lease(Mockito.eq(route), Mockito.any(), Mockito.any())).thenReturn(leaseRequest); + Mockito.when(leaseRequest.get( + Mockito.anyLong(), Mockito.any())).thenThrow(new ExecutionException(new IllegalStateException())); + + execRuntime.acquireConnection(route, null, context); + } + + @Test + public void testAbortEndpoint() throws Exception { + final HttpClientContext context = HttpClientContext.create(); + Mockito.when(mgr.lease(Mockito.eq(route), Mockito.any(), Mockito.any())).thenReturn(leaseRequest); + Mockito.when(leaseRequest.get( + Mockito.anyLong(), Mockito.any())).thenReturn(connectionEndpoint); + + execRuntime.acquireConnection(new HttpRoute(new HttpHost("host", 80)), null, context); + Assert.assertTrue(execRuntime.isConnectionAcquired()); + execRuntime.discardConnection(); + + Assert.assertFalse(execRuntime.isConnectionAcquired()); + + Mockito.verify(connectionEndpoint).shutdown(ShutdownType.IMMEDIATE); + Mockito.verify(mgr).release(connectionEndpoint, null, TimeValue.ZERO_MILLISECONDS); + + execRuntime.discardConnection(); + + Mockito.verify(connectionEndpoint, Mockito.times(1)).shutdown(ShutdownType.IMMEDIATE); + Mockito.verify(mgr, Mockito.times(1)).release( + Mockito.any(), + Mockito.any(), + Mockito.any()); + } + + @Test + public void testCancell() throws Exception { + final HttpClientContext context = HttpClientContext.create(); + + Mockito.when(mgr.lease(Mockito.eq(route), Mockito.any(), Mockito.any())).thenReturn(leaseRequest); + Mockito.when(leaseRequest.get( + Mockito.anyLong(), Mockito.any())).thenReturn(connectionEndpoint); + + execRuntime.acquireConnection(route, null, context); + Assert.assertTrue(execRuntime.isConnectionAcquired()); + + Assert.assertTrue(execRuntime.cancel()); + + Assert.assertFalse(execRuntime.isConnectionAcquired()); + + Mockito.verify(connectionEndpoint).shutdown(ShutdownType.IMMEDIATE); + Mockito.verify(mgr).release(connectionEndpoint, null, TimeValue.ZERO_MILLISECONDS); + + Assert.assertFalse(execRuntime.cancel()); + + Mockito.verify(connectionEndpoint, Mockito.times(1)).shutdown(ShutdownType.IMMEDIATE); + Mockito.verify(mgr, Mockito.times(1)).release( + Mockito.any(), + Mockito.any(), + Mockito.any()); + } + + @Test + public void testReleaseEndpointReusable() throws Exception { + final HttpClientContext context = HttpClientContext.create(); + + Mockito.when(mgr.lease(Mockito.eq(route), Mockito.any(), Mockito.any())).thenReturn(leaseRequest); + Mockito.when(leaseRequest.get( + Mockito.anyLong(), Mockito.any())).thenReturn(connectionEndpoint); + + execRuntime.acquireConnection(route, null, context); + Assert.assertTrue(execRuntime.isConnectionAcquired()); + + execRuntime.setConnectionState("some state"); + execRuntime.setConnectionValidFor(TimeValue.ofMillis(100000)); + execRuntime.markConnectionReusable(); + + execRuntime.releaseConnection(); + + Assert.assertFalse(execRuntime.isConnectionAcquired()); + + Mockito.verify(connectionEndpoint, Mockito.never()).close(); + Mockito.verify(mgr).release(connectionEndpoint, "some state", TimeValue.ofMillis(100000)); + + execRuntime.releaseConnection(); + + Mockito.verify(mgr, Mockito.times(1)).release( + Mockito.any(), + Mockito.any(), + Mockito.any()); + } + + @Test + public void testReleaseEndpointNonReusable() throws Exception { + final HttpClientContext context = HttpClientContext.create(); + + Mockito.when(mgr.lease(Mockito.eq(route), Mockito.any(), Mockito.any())).thenReturn(leaseRequest); + Mockito.when(leaseRequest.get( + Mockito.anyLong(), Mockito.any())).thenReturn(connectionEndpoint); + + execRuntime.acquireConnection(route, null, context); + Assert.assertTrue(execRuntime.isConnectionAcquired()); + + execRuntime.setConnectionState("some state"); + execRuntime.setConnectionValidFor(TimeValue.ofMillis(100000)); + execRuntime.markConnectionNonReusable(); + + execRuntime.releaseConnection(); + + Assert.assertFalse(execRuntime.isConnectionAcquired()); + + Mockito.verify(connectionEndpoint, Mockito.times(1)).close(); + Mockito.verify(mgr).release(connectionEndpoint, null, TimeValue.ZERO_MILLISECONDS); + + execRuntime.releaseConnection(); + + Mockito.verify(mgr, Mockito.times(1)).release( + Mockito.any(), + Mockito.any(), + Mockito.any()); + } + + @Test + public void testConnectEndpoint() throws Exception { + final HttpClientContext context = HttpClientContext.create(); + final RequestConfig config = RequestConfig.custom() + .setConnectTimeout(123, TimeUnit.MILLISECONDS) + .setConnectionRequestTimeout(345, TimeUnit.MILLISECONDS) + .build(); + context.setRequestConfig(config); + + Mockito.when(mgr.lease(Mockito.eq(route), Mockito.any(), Mockito.any())).thenReturn(leaseRequest); + Mockito.when(leaseRequest.get( + Mockito.anyLong(), Mockito.any())).thenReturn(connectionEndpoint); + + execRuntime.acquireConnection(route, null, context); + Assert.assertTrue(execRuntime.isConnectionAcquired()); + + Mockito.when(connectionEndpoint.isConnected()).thenReturn(false); + Assert.assertFalse(execRuntime.isConnected()); + + execRuntime.connect(context); + + Mockito.verify(mgr).connect(connectionEndpoint, TimeValue.ofMillis(123), context); + Mockito.verify(connectionEndpoint).setSocketTimeout(123); + } + + @Test + public void testDisonnectEndpoint() throws Exception { + final HttpClientContext context = HttpClientContext.create(); + + Mockito.when(mgr.lease(Mockito.eq(route), Mockito.any(), Mockito.any())).thenReturn(leaseRequest); + Mockito.when(leaseRequest.get( + Mockito.anyLong(), Mockito.any())).thenReturn(connectionEndpoint); + + execRuntime.acquireConnection(route, null, context); + Assert.assertTrue(execRuntime.isConnectionAcquired()); + + Mockito.when(connectionEndpoint.isConnected()).thenReturn(true); + Assert.assertTrue(execRuntime.isConnected()); + + execRuntime.connect(context); + + Mockito.verify(mgr, Mockito.never()).connect( + Mockito.same(connectionEndpoint), Mockito.any(), Mockito.any()); + + execRuntime.disconnect(); + + Mockito.verify(connectionEndpoint).close(); + } + +}