ConnectorConfigTest.java
/*
* Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package org.glassfish.jersey.netty.connector;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpRequest;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientProperties;
import org.glassfish.jersey.client.ClientRequest;
import org.glassfish.jersey.client.ClientResponse;
import org.glassfish.jersey.client.RequestEntityProcessing;
import org.glassfish.jersey.client.innate.ClientProxy;
import org.glassfish.jersey.http.HttpHeaders;
import org.glassfish.jersey.internal.MapPropertiesDelegate;
import org.glassfish.jersey.internal.util.collection.Ref;
import org.glassfish.jersey.client.innate.ConnectorConfiguration;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import javax.net.ssl.SSLContext;
import javax.ws.rs.ProcessingException;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.Configuration;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.InetSocketAddress;
import java.net.URI;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class ConnectorConfigTest {
private static final String PREFIX = "test.";
private static ClientRequest createRequest(Client client) {
return new ClientRequest(URI.create("http://localhost:8080"),
(ClientConfig) client.getConfiguration(), new MapPropertiesDelegate()) {
};
}
@Test
public void testPrefixedConfig() {
ConnectorConfig.RW r = new ConnectorConfig.RW();
Configuration prefixed, unprefixed;
unprefixed = r.config();
unprefixed.getProperties().put(ClientProperties.CONNECT_TIMEOUT, 1000);
prefixed = r.prefix(PREFIX).prefixedConfiguration(unprefixed);
Assertions.assertNull(prefixed.getProperty(ClientProperties.CONNECT_TIMEOUT));
Assertions.assertNull(prefixed.getProperties().get(ClientProperties.CONNECT_TIMEOUT));
unprefixed = r.config();
unprefixed.getProperties().put(PREFIX + ClientProperties.CONNECT_TIMEOUT, 2000);
prefixed = r.prefix(PREFIX).prefixedConfiguration(unprefixed);
Assertions.assertEquals(2000, prefixed.getProperty(ClientProperties.CONNECT_TIMEOUT));
Assertions.assertEquals(2000, prefixed.getProperties().get(ClientProperties.CONNECT_TIMEOUT));
unprefixed = r.config();
prefixed = r.prefix(PREFIX).prefixedConfiguration(unprefixed);
unprefixed.getProperties().put(ClientProperties.CONNECT_TIMEOUT, 2000);
prefixed.getProperties().putAll(unprefixed.getProperties());
Assertions.assertNull(prefixed.getProperty(ClientProperties.CONNECT_TIMEOUT));
Assertions.assertNull(prefixed.getProperties().get(ClientProperties.CONNECT_TIMEOUT));
unprefixed = r.config();
prefixed = r.prefix(PREFIX).prefixedConfiguration(unprefixed);
unprefixed.getProperties().put(PREFIX + ClientProperties.CONNECT_TIMEOUT, 2000);
prefixed.getProperties().putAll(unprefixed.getProperties());
Assertions.assertEquals(2000, prefixed.getProperty(ClientProperties.CONNECT_TIMEOUT));
Assertions.assertEquals(2000, prefixed.getProperties().get(ClientProperties.CONNECT_TIMEOUT));
unprefixed = r.config();
prefixed = r.prefix(PREFIX).prefixedConfiguration(unprefixed);
prefixed.getProperties().put(PREFIX + ClientProperties.PROXY_USERNAME, "USERNAME");
Assertions.assertEquals("USERNAME", prefixed.getProperty(ClientProperties.PROXY_USERNAME));
prefixed.getProperties().put(ClientProperties.PROXY_PASSWORD, "PASSWORD");
Assertions.assertNull(prefixed.getProperty(ClientProperties.PROXY_PASSWORD));
}
@Test
public void testAsyncThreadPoolSize() {
AtomicInteger result = new AtomicInteger(0);
class RWAsync extends RW {
@Override
public Integer asyncThreadPoolSize() {
result.set(super.asyncThreadPoolSize());
return super.asyncThreadPoolSize();
}
@Override
public RWAsync instance() {
return new RWAsync();
}
}
Client client = ClientBuilder.newClient();
NettyConnectorProvider.Config.RW rw0 = new RWAsync().asyncThreadPoolSize(10);
new NettyConnector(client, rw0);
Assertions.assertEquals(10, result.get());
result.set(0);
NettyConnectorProvider.Config.RW rw1 = new RWAsync().asyncThreadPoolSize(20);
client.property(ClientProperties.CONNECTOR_CONFIGURATION, rw1);
new NettyConnector(client, rw0);
Assertions.assertEquals(20, result.get());
result.set(0);
client.property(ClientProperties.ASYNC_THREADPOOL_SIZE, 30);
new NettyConnector(client, rw0);
Assertions.assertEquals(30, result.get());
}
@Test
public void testConnectTimeout() {
final AtomicInteger result = new AtomicInteger(0);
class RWConnect extends NettyConnectorProvider.Config.RW {
@Override
public int connectTimeout() {
result.set(super.connectTimeout());
throw new IllegalStateException();
}
@Override
public RWConnect instance() {
return new RWConnect();
}
}
new TestClient(new RWConnect()).rw(rw -> rw.connectTimeout(1000)).request().apply();
Assertions.assertEquals(1000, result.get());
result.set(0);
new TestClient(new RWConnect()).rw(rw -> rw.connectTimeout(1000))
.client(c -> c.property(ClientProperties.CONNECT_TIMEOUT, 3000))
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWConnect().connectTimeout(2000)))
.request().apply();
Assertions.assertEquals(3000, result.get());
result.set(0);
new TestClient(new RWConnect()).rw(rw -> rw.connectTimeout(1000))
.client(c -> c.property(ClientProperties.CONNECT_TIMEOUT, 3000))
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWConnect().connectTimeout(2000)))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION, new RWConnect().connectTimeout(4000)))
.apply();
Assertions.assertEquals(3000, result.get());
result.set(0);
new TestClient(new RWConnect()).rw(rw -> rw.connectTimeout(1000))
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWConnect().connectTimeout(2000)))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION, new RWConnect().connectTimeout(4000)))
.apply();
Assertions.assertEquals(4000, result.get());
result.set(0);
new TestClient(new RWConnect()).rw(rw -> rw.connectTimeout(1000))
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWConnect().connectTimeout(2000)))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION, new RWConnect().connectTimeout(4000)))
.request(r -> r.setProperty(ClientProperties.CONNECT_TIMEOUT, 5000))
.apply();
Assertions.assertEquals(5000, result.get());
result.set(0);
new TestClient(new RWConnect().prefix(PREFIX)).rw(rw -> rw.connectTimeout(1000))
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
new RWConnect().connectTimeout(2000).prefix(PREFIX)))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWConnect().connectTimeout(4000)))
.apply();
Assertions.assertEquals(2000, result.get());
result.set(0);
new TestClient(new RWConnect()).rw(rw -> rw.connectTimeout(1000).prefix(PREFIX))
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWConnect().connectTimeout(2000)))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWConnect().connectTimeout(4000).prefix(PREFIX)))
.request(r -> r.setProperty(ClientProperties.CONNECT_TIMEOUT, 5000))
.apply();
Assertions.assertEquals(4000, result.get());
}
@Test
public void testExpect100Continue() {
final AtomicReference<Boolean> result = new AtomicReference<>();
final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
class RWExpect extends RW {
@Override
public Boolean expect100Continue(ClientRequest request) {
result.set(super.expect100Continue(request));
return result.get();
}
@Override
public int connectTimeout() {
config.set(this);
return super.connectTimeout();
}
@Override
public RWExpect instance() {
return new RWExpect();
}
}
Request req = new TestClient(new RWExpect()).request(r -> r.setEntity(PREFIX)).apply();
try {
new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, null);
} catch (NullPointerException expected) {
}
Assertions.assertNull(result.get());
result.set(null);
req = new TestClient(new RWExpect().expect100Continue(true)).request(r -> r.setEntity(PREFIX)).apply();
try {
new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(true, result.get());
result.set(null);
req = new TestClient(new RWExpect().expect100Continue(true).prefix(PREFIX))
.request(r -> r.setProperty(PREFIX + ClientProperties.EXPECT_100_CONTINUE, false))
.request(r -> r.setEntity(PREFIX)).apply();
try {
new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(false, result.get());
result.set(null);
req = new TestClient(new RWExpect().expect100Continue(true).prefix(PREFIX))
.request(r -> r.setProperty(
PREFIX + ClientProperties.CONNECTOR_CONFIGURATION, new RWExpect().expect100Continue(false)))
.request(r -> r.setEntity(PREFIX)).apply();
try {
new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(false, result.get());
result.set(null);
req = new TestClient(new RWExpect())
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWExpect().expect100Continue(true)))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION, new RWExpect().expect100Continue(false)))
.request(r -> r.setEntity(PREFIX)).apply();
try {
new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(false, result.get());
result.set(null);
req = new TestClient(new RWExpect().prefix(PREFIX))
.client(c -> c.property(PREFIX + ClientProperties.EXPECT_100_CONTINUE, true))
.request(r -> r.setProperty(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
new RWExpect().expect100Continue(false)))
.request(r -> r.setEntity(PREFIX)).apply();
try {
new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(true, result.get());
}
@Test
public void testExpect100ContinueThreshold() {
final AtomicReference<Long> result = new AtomicReference<>();
final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
class RWExpect extends RW {
@Override
public long expect100ContinueThreshold(ClientRequest request) {
result.set(super.expect100ContinueThreshold(request));
return result.get();
}
@Override
public int connectTimeout() {
config.set(this);
return super.connectTimeout();
}
@Override
public RWExpect instance() {
return new RWExpect();
}
}
Request req = new TestClient(new RWExpect()).request(r -> r.setEntity(PREFIX)).apply();
try {
new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, (HttpRequest) null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(ClientProperties.DEFAULT_EXPECT_100_CONTINUE_THRESHOLD_SIZE, result.get());
result.set(null);
req = new TestClient(new RWExpect().expect100ContinueThreshold(1000)).request(r -> r.setEntity(PREFIX)).apply();
try {
new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, (HttpRequest) null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(1000, result.get());
result.set(null);
req = new TestClient(new RWExpect().expect100ContinueThreshold(1000).prefix(PREFIX))
.request(r -> r.setProperty(PREFIX + ClientProperties.EXPECT_100_CONTINUE_THRESHOLD_SIZE, 2000))
.request(r -> r.setEntity(PREFIX)).apply();
try {
new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, (HttpRequest) null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(2000, result.get());
result.set(null);
req = new TestClient(new RWExpect().expect100ContinueThreshold(1000).prefix(PREFIX))
.request(r -> r.setProperty(
PREFIX + ClientProperties.CONNECTOR_CONFIGURATION, new RWExpect().expect100ContinueThreshold(2000)))
.request(r -> r.setEntity(PREFIX)).apply();
try {
new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, (HttpRequest) null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(2000, result.get());
result.set(null);
req = new TestClient(new RWExpect())
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
new RWExpect().expect100ContinueThreshold(1000)))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWExpect().expect100ContinueThreshold(2000)))
.request(r -> r.setEntity(PREFIX)).apply();
try {
new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, (HttpRequest) null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(2000, result.get());
result.set(null);
req = new TestClient(new RWExpect().prefix(PREFIX))
.client(c -> c.property(PREFIX + ClientProperties.EXPECT_100_CONTINUE_THRESHOLD_SIZE, 1000))
.request(r -> r.setProperty(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
new RWExpect().expect100ContinueThreshold(2000)))
.request(r -> r.setEntity(PREFIX)).apply();
try {
new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, (HttpRequest) null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(1000, result.get());
}
@Test
public void testExpect100ContinueTimeout() {
final AtomicReference<Integer> result = new AtomicReference<>();
final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
class RWExpect extends RW {
@Override
public NettyConnectorProvider.Config.RW expect100ContinueTimeout(ClientRequest request) {
super.expect100ContinueTimeout(request);
result.set(this.expect100ContTimeout.get());
return this;
}
@Override
public int connectTimeout() {
config.set(this);
return super.connectTimeout();
}
@Override
public RWExpect instance() {
return new RWExpect();
}
}
Request req = new TestClient(new RWExpect()).request(r -> r.setEntity(PREFIX)).apply();
try {
new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, (HttpRequest) null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(NettyClientProperties.DEFAULT_EXPECT_100_CONTINUE_TIMEOUT_VALUE, result.get());
result.set(null);
req = new TestClient(new RWExpect().expect100ContinueTimeout(1000)).request(r -> r.setEntity(PREFIX)).apply();
try {
new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, (HttpRequest) null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(1000, result.get());
result.set(null);
req = new TestClient(new RWExpect().expect100ContinueTimeout(1000).prefix(PREFIX))
.request(r -> r.setProperty(PREFIX + NettyClientProperties.EXPECT_100_CONTINUE_TIMEOUT, 2000))
.request(r -> r.setEntity(PREFIX)).apply();
try {
new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, (HttpRequest) null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(2000, result.get());
result.set(null);
req = new TestClient(new RWExpect().expect100ContinueTimeout(1000).prefix(PREFIX))
.request(r -> r.setProperty(
PREFIX + ClientProperties.CONNECTOR_CONFIGURATION, new RWExpect().expect100ContinueTimeout(2000)))
.request(r -> r.setEntity(PREFIX)).apply();
try {
new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, (HttpRequest) null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(2000, result.get());
result.set(null);
req = new TestClient(new RWExpect())
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWExpect().expect100ContinueTimeout(1000)))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWExpect().expect100ContinueTimeout(2000)))
.request(r -> r.setEntity(PREFIX)).apply();
try {
new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(2000, result.get());
result.set(null);
req = new TestClient(new RWExpect().prefix(PREFIX))
.client(c -> c.property(PREFIX + NettyClientProperties.EXPECT_100_CONTINUE_TIMEOUT, 1000))
.request(r -> r.setProperty(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
new RWExpect().expect100ContinueTimeout(2000)))
.request(r -> r.setEntity(PREFIX)).apply();
try {
new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(1000, result.get());
}
@Test
public void testFollowRedirects() {
final AtomicReference<Boolean> result = new AtomicReference<>();
final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
class RWFollow extends RW {
@Override
public boolean followRedirects() {
result.set(super.followRedirects());
return result.get();
}
@Override
public int connectTimeout() {
config.set(this);
return super.connectTimeout();
}
@Override
public RWFollow instance() {
return new RWFollow();
}
}
Request req;
req = new TestClient(new RWFollow()).request().apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
config.get().followRedirects();
Assertions.assertEquals(new RWFollow().copy().followRedirects(), result.get());
result.set(null);
req = new TestClient(new RWFollow().followRedirects(false)).request().apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
config.get().followRedirects();
Assertions.assertEquals(false, result.get());
result.set(null);
req = new TestClient(new RWFollow().followRedirects(false).prefix(PREFIX))
.request(r -> r.setProperty(PREFIX + ClientProperties.FOLLOW_REDIRECTS, true))
.request(r -> r.setEntity(PREFIX)).apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
config.get().followRedirects();
Assertions.assertEquals(true, result.get());
result.set(null);
req = new TestClient(new RWFollow().followRedirects(false).prefix(PREFIX))
.request(r -> r.setProperty(
PREFIX + ClientProperties.CONNECTOR_CONFIGURATION, new RWFollow().followRedirects(true)))
.apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
config.get().followRedirects();
Assertions.assertEquals(true, result.get());
result.set(null);
req = new TestClient(new RWFollow())
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWFollow().followRedirects(false)))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWFollow().followRedirects(true)))
.request(r -> r.setEntity(PREFIX)).apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
config.get().followRedirects();
Assertions.assertEquals(true, result.get());
result.set(null);
req = new TestClient(new RWFollow().prefix(PREFIX))
.client(c -> c.property(PREFIX + ClientProperties.FOLLOW_REDIRECTS, false))
.request(r -> r.setProperty(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
new RWFollow().followRedirects(true)))
.request(r -> r.setEntity(PREFIX)).apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
config.get().followRedirects();
Assertions.assertEquals(false, result.get());
}
@Test
public void testProxy() {
final AtomicReference<ClientProxy> result = new AtomicReference<>();
final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
class RWProxy extends RW {
@Override
public Optional<ClientProxy> proxy(ClientRequest request, URI requestUri) {
Optional<ClientProxy> proxy = super.proxy(request, requestUri);
result.set(proxy.orElse(null));
return proxy;
}
@Override
public RWProxy instance() {
return new RWProxy();
}
}
String proxyUri = "http://proxy.org:8080";
String userName = "USERNAME";
String password = "PASSWORD";
new TestClient(new RWProxy()).request().apply();
Assertions.assertNull(result.get());
result.set(null);
new TestClient(new RWProxy().proxyUri(proxyUri).proxyUserName(userName).proxyPassword(password)).request().apply();
Assertions.assertEquals(proxyUri, result.get().uri().toASCIIString());
Assertions.assertEquals(userName, result.get().userName());
Assertions.assertEquals(password, result.get().password());
result.set(null);
new TestClient(new RWProxy().prefix(PREFIX).proxyUri(proxyUri).proxyUserName("XXX").proxyPassword(password))
.request(r -> r.setProperty(PREFIX + ClientProperties.PROXY_USERNAME, userName))
.request(r -> r.setProperty(ClientProperties.PROXY_PASSWORD, "XXX"))
.apply();
Assertions.assertEquals(proxyUri, result.get().uri().toASCIIString());
Assertions.assertEquals(userName, result.get().userName());
Assertions.assertEquals(password, result.get().password());
result.set(null);
new TestClient(new RWProxy().prefix(PREFIX).proxyUri(proxyUri).proxyUserName("XXX").proxyPassword(password))
.request(r -> r.setProperty(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
new RWProxy().proxyUserName(userName).proxyPassword(null)))
.apply();
Assertions.assertEquals(proxyUri, result.get().uri().toASCIIString());
Assertions.assertEquals(userName, result.get().userName());
Assertions.assertNull(result.get().password());
result.set(null);
new TestClient(new RWProxy().prefix(PREFIX)
.proxy(new java.net.Proxy(java.net.Proxy.Type.HTTP,
new InetSocketAddress(proxyUri.split("g:")[0] + "g", Integer.parseInt(proxyUri.split("g:")[1])))))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWProxy().proxyUserName(userName).proxyPassword(password).prefix(PREFIX)))
.apply();
Assertions.assertEquals(proxyUri, result.get().uri().toASCIIString());
Assertions.assertEquals(userName, result.get().userName());
Assertions.assertEquals(password, result.get().password());
}
@Test
public void testReadTimeout() {
final AtomicInteger result = new AtomicInteger(0);
class RWRead extends NettyConnectorProvider.Config.RW {
@Override
public int readTimeout() {
result.set(super.readTimeout());
throw new IllegalStateException();
}
@Override
public RWRead instance() {
return new RWRead();
}
}
new TestClient(new RWRead()).rw(rw -> rw.readTimeout(1000)).request().apply();
Assertions.assertEquals(1000, result.get());
result.set(0);
new TestClient(new RWRead()).rw(rw -> rw.readTimeout(1000))
.client(c -> c.property(ClientProperties.READ_TIMEOUT, 3000))
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().readTimeout(2000)))
.request().apply();
Assertions.assertEquals(3000, result.get());
result.set(0);
new TestClient(new RWRead()).rw(rw -> rw.readTimeout(1000))
.client(c -> c.property(ClientProperties.READ_TIMEOUT, 3000))
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().connectTimeout(2000)))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().readTimeout(4000)))
.apply();
Assertions.assertEquals(3000, result.get());
result.set(0);
new TestClient(new RWRead()).rw(rw -> rw.readTimeout(1000))
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().readTimeout(2000)))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().readTimeout(4000)))
.apply();
Assertions.assertEquals(4000, result.get());
result.set(0);
new TestClient(new RWRead()).rw(rw -> rw.readTimeout(1000))
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().readTimeout(2000)))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().readTimeout(4000)))
.request(r -> r.setProperty(ClientProperties.READ_TIMEOUT, 5000))
.apply();
Assertions.assertEquals(5000, result.get());
result.set(0);
new TestClient(new RWRead()).rw(rw -> rw.readTimeout(1000).prefix(PREFIX))
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
new RWRead().readTimeout(2000).prefix(PREFIX)))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWRead().readTimeout(4000)))
.apply();
Assertions.assertEquals(2000, result.get());
result.set(0);
new TestClient(new RWRead()).rw(rw -> rw.readTimeout(1000).prefix(PREFIX))
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().readTimeout(2000)))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWRead().readTimeout(4000).prefix(PREFIX)))
.request(r -> r.setProperty(ClientProperties.READ_TIMEOUT, 5000))
.apply();
Assertions.assertEquals(4000, result.get());
}
@Test
public void testRequestEntityProcessing() {
final AtomicReference<RequestEntityProcessing> result = new AtomicReference<>();
final AtomicReference<RW> config = new AtomicReference<>();
class RWRP extends RW {
@Override
public RequestEntityProcessing requestEntityProcessing(ClientRequest request) {
result.set(super.requestEntityProcessing(request));
return result.get();
}
@Override
public RWRP instance() {
config.set(new RWRP());
return (RWRP) config.get();
}
}
Request req;
req = new TestClient(new RWRP().requestEntityProcessing(RequestEntityProcessing.CHUNKED))
.request(r -> r.setEntity(PREFIX)).apply();
try {
req.connector.nettyEntityWriter(req.request, null, config.get());
} catch (NullPointerException ignore) {
}
Assertions.assertEquals(RequestEntityProcessing.CHUNKED, result.get());
result.set(null);
req = new TestClient(new RWRP().prefix(PREFIX).requestEntityProcessing(RequestEntityProcessing.CHUNKED))
.request(r -> r.setEntity(PREFIX))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWRP().requestEntityProcessing(RequestEntityProcessing.BUFFERED).prefix(PREFIX)))
.apply();
try {
req.connector.nettyEntityWriter(req.request, null, config.get());
} catch (NullPointerException ignore) {
}
Assertions.assertEquals(RequestEntityProcessing.BUFFERED, result.get());
result.set(null);
req = new TestClient(new RWRP().prefix(PREFIX).requestEntityProcessing(RequestEntityProcessing.CHUNKED))
.request(r -> r.setEntity(PREFIX))
.request(r -> r.setProperty(PREFIX + ClientProperties.REQUEST_ENTITY_PROCESSING,
RequestEntityProcessing.BUFFERED))
.apply();
try {
req.connector.nettyEntityWriter(req.request, null, config.get());
} catch (NullPointerException ignore) {
}
Assertions.assertEquals(RequestEntityProcessing.BUFFERED, result.get());
}
@Test
public void testSniHostName() {
final String sniHost = "sun.oracle.com";
final AtomicReference<String> sniRef = new AtomicReference<>();
final NettyConnectionController controller = new NettyConnectionController() {
@Override
public String getConnectionGroup(ClientRequest clientRequest, URI uri, String hostName, int port) {
sniRef.set(hostName);
return super.getConnectionGroup(clientRequest, uri, hostName, port);
}
};
final class RWSni extends RW {
@Override
public RWSni instance() {
return new RWSni();
}
}
new TestClient(new RWSni().connectionController(controller))
.request(r -> r.getRequestHeaders().add(HttpHeaders.HOST, sniHost))
.apply();
Assertions.assertEquals(sniHost, sniRef.get());
new TestClient(new RWSni().connectionController(controller).sniHostName(sniHost))
.request(r -> r.getRequestHeaders().add(HttpHeaders.HOST, "moon.oracle.com"))
.apply();
Assertions.assertEquals(sniHost, sniRef.get());
new TestClient(new RWSni().connectionController(controller).prefix(PREFIX))
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
NettyConnectorProvider.config().sniHostName("moon.oracle.com")))
.request(r -> r.getRequestHeaders().add(HttpHeaders.HOST, sniHost))
.apply();
Assertions.assertEquals(sniHost, sniRef.get());
new TestClient(new RWSni().connectionController(controller).prefix(PREFIX))
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
NettyConnectorProvider.config().sniHostName(sniHost).prefix(PREFIX)))
.request(r -> r.getRequestHeaders().add(HttpHeaders.HOST, "moon.oracle.com"))
.apply();
Assertions.assertEquals(sniHost, sniRef.get());
new TestClient(new RWSni().connectionController(controller).prefix(PREFIX))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
NettyConnectorProvider.config().sniHostName("moon.oracle.com")))
.request(r -> r.getRequestHeaders().add(HttpHeaders.HOST, sniHost))
.apply();
Assertions.assertEquals(sniHost, sniRef.get());
new TestClient(new RWSni().connectionController(controller).prefix(PREFIX))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
NettyConnectorProvider.config().sniHostName(sniHost).prefix(PREFIX)))
.request(r -> r.getRequestHeaders().add(HttpHeaders.HOST, "moon.oracle.com"))
.apply();
Assertions.assertEquals(sniHost, sniRef.get());
}
@Test
public void testSslContext() {
final SSLContext testContext = new SSLContext(null, null, null){};
final AtomicReference<SSLContext> result = new AtomicReference<>();
final AtomicReference<RW> config = new AtomicReference<>();
class RWSsl extends RW {
@Override
public SSLContext sslContext(Client client, ClientRequest request) {
result.set(super.sslContext(client, request));
return result.get();
}
@Override
public RWSsl instance() {
RWSsl rw = new RWSsl();
config.set(rw);
return rw;
}
}
Request req;
req = new TestClient(new RWSsl().sslContextSupplier(() -> testContext)).request().apply();
config.get().sslContext(req.client, req.request);
Assertions.assertEquals(testContext, result.get());
result.set(null);
req = new TestClient(new RWSsl().prefix(PREFIX))
.request(r -> r.setProperty(PREFIX + ClientProperties.SSL_CONTEXT_SUPPLIER,
(Supplier<SSLContext>) () -> testContext)).apply();
config.get().sslContext(req.client, req.request);
Assertions.assertEquals(testContext, result.get());
result.set(null);
req = new TestClient(new RWSsl().prefix(PREFIX))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWSsl().prefix(PREFIX).sslContextSupplier(() -> testContext))).apply();
config.get().sslContext(req.client, req.request);
Assertions.assertEquals(testContext, result.get());
}
@Test
public void testConnectionController() {
final NettyConnectionController connectionController = new NettyConnectionController();
final AtomicReference<NettyConnectionController> result = new AtomicReference<>();
class RWController extends RW {
@Override
NettyConnectionController connectionController() {
result.set(super.connectionController());
return result.get();
}
@Override
public RWController instance() {
return new RWController();
}
}
new TestClient(new RWController().connectionController(connectionController)).request().apply();
Assertions.assertEquals(connectionController, result.get());
result.set(null);
new TestClient(new RWController().prefix(PREFIX).connectionController(new NettyConnectionController()))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWController().connectionController(connectionController).prefix(PREFIX))).apply();
Assertions.assertEquals(connectionController, result.get());
}
@Test
public void testEnableSslHostnameVerification() {
final AtomicReference<Boolean> result = new AtomicReference<>();
final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
class RWEnabled extends RW {
@Override
boolean isSslHostnameVerificationEnabled(Map<String, Object> properties) {
result.set(super.isSslHostnameVerificationEnabled(properties));
return result.get();
}
@Override
public RWEnabled instance() {
RWEnabled enabled = new RWEnabled();
config.set(enabled);
return enabled;
}
}
Request req;
req = new TestClient(new RWEnabled()).request().apply();
config.get().isSslHostnameVerificationEnabled(req.request.getConfiguration().getProperties());
Assertions.assertEquals(new RWEnabled().copy().followRedirects(), result.get());
result.set(null);
req = new TestClient(new RWEnabled().enableSslHostnameVerification(false)).request().apply();
config.get().isSslHostnameVerificationEnabled(req.request.getConfiguration().getProperties());
Assertions.assertEquals(false, result.get());
// NOT PER REQUEST
// result.set(null);
// req = new TestClient(new RWEnabled().enableSslHostnameVerification(false).prefix(PREFIX))
// .request(r -> r.setProperty(PREFIX + NettyClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION, true))
// .apply();
// config.get().isSslHostnameVerificationEnabled(req.request.getConfiguration().getProperties());
// Assertions.assertEquals(true, result.get());
result.set(null);
req = new TestClient(new RWEnabled().enableSslHostnameVerification(false).prefix(PREFIX))
.request(r -> r.setProperty(
PREFIX + ClientProperties.CONNECTOR_CONFIGURATION, new RWEnabled().enableSslHostnameVerification(true)))
.apply();
config.get().isSslHostnameVerificationEnabled(req.request.getConfiguration().getProperties());
Assertions.assertEquals(true, result.get());
result.set(null);
req = new TestClient(new RWEnabled())
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
new RWEnabled().enableSslHostnameVerification(false)))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWEnabled().enableSslHostnameVerification(true)))
.apply();
config.get().isSslHostnameVerificationEnabled(req.request.getConfiguration().getProperties());
Assertions.assertEquals(true, result.get());
result.set(null);
req = new TestClient(new RWEnabled().prefix(PREFIX))
.client(c -> c.property(PREFIX + NettyClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION, false))
.request(r -> r.setProperty(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
new RWEnabled().enableSslHostnameVerification(true)))
.request(r -> r.setEntity(PREFIX)).apply();
config.get().isSslHostnameVerificationEnabled(req.request.getConfiguration().getProperties());
Assertions.assertEquals(false, result.get());
}
@Test
public void testMaxRedirects() {
final AtomicReference<Integer> result = new AtomicReference<>();
final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
class RWMaxRed extends RW {
@Override
int maxRedirects(ClientRequest request) {
result.set(super.maxRedirects(request));
return result.get();
}
@Override
public RWMaxRed instance() {
RWMaxRed max = new RWMaxRed();
config.set(max);
return max;
}
}
Request req = new TestClient(new RWMaxRed()).request().apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
Assertions.assertEquals(new RWMaxRed().copy().maxRedirects(req.request), result.get());
result.set(null);
req = new TestClient(new RWMaxRed().maxRedirects(2)).request().apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
Assertions.assertEquals(2, result.get());
result.set(null);
req = new TestClient(new RWMaxRed().maxRedirects(2).prefix(PREFIX))
.request(r -> r.setProperty(PREFIX + NettyClientProperties.MAX_REDIRECTS, 3))
.request(r -> r.setEntity(PREFIX)).apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
Assertions.assertEquals(3, result.get());
result.set(null);
req = new TestClient(new RWMaxRed().maxRedirects(2).prefix(PREFIX))
.request(r -> r.setProperty(
PREFIX + ClientProperties.CONNECTOR_CONFIGURATION, new RWMaxRed().maxRedirects(3)))
.apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
Assertions.assertEquals(3, result.get());
result.set(null);
req = new TestClient(new RWMaxRed())
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWMaxRed().maxRedirects(2)))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWMaxRed().maxRedirects(3)))
.request(r -> r.setEntity(PREFIX)).apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
Assertions.assertEquals(3, result.get());
result.set(null);
req = new TestClient(new RWMaxRed().prefix(PREFIX))
.client(c -> c.property(PREFIX + NettyClientProperties.MAX_REDIRECTS, 2))
.request(r -> r.setProperty(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
new RWMaxRed().maxRedirects(3)))
.request(r -> r.setEntity(PREFIX)).apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
Assertions.assertEquals(2, result.get());
}
@Test
public void testRedirectController() {
final NettyHttpRedirectController controller = new NettyHttpRedirectController();
final AtomicReference<NettyHttpRedirectController> result = new AtomicReference<>();
final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
class RWController extends RW {
@Override
NettyHttpRedirectController redirectController(ClientRequest request) {
result.set(super.redirectController(request));
return result.get();
}
@Override
public RWController instance() {
RWController max = new RWController();
config.set(max);
return max;
}
}
Request req;
result.set(null);
req = new TestClient(new RWController().redirectController(controller)).request().apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
config.get().redirectController(req.request);
Assertions.assertEquals(controller, result.get());
result.set(null);
req = new TestClient(new RWController().redirectController(new NettyHttpRedirectController()).prefix(PREFIX))
.request(r -> r.setProperty(PREFIX + NettyClientProperties.HTTP_REDIRECT_CONTROLLER, controller))
.request(r -> r.setEntity(PREFIX)).apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
config.get().redirectController(req.request);
Assertions.assertEquals(controller, result.get());
result.set(null);
req = new TestClient(new RWController().redirectController(new NettyHttpRedirectController()).prefix(PREFIX))
.request(r -> r.setProperty(
PREFIX + ClientProperties.CONNECTOR_CONFIGURATION, new RWController().redirectController(controller)))
.apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
config.get().redirectController(req.request);
Assertions.assertEquals(controller, result.get());
result.set(null);
req = new TestClient(new RWController())
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
new RWController().redirectController(new NettyHttpRedirectController())))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWController().redirectController(controller)))
.request(r -> r.setEntity(PREFIX)).apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
// config.get().redirectController(req.request);
Assertions.assertEquals(controller, result.get());
result.set(null);
req = new TestClient(new RWController().prefix(PREFIX))
.client(c -> c.property(PREFIX + NettyClientProperties.HTTP_REDIRECT_CONTROLLER, controller))
.request(r -> r.setProperty(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
new RWController().redirectController(new NettyHttpRedirectController())))
.request(r -> r.setEntity(PREFIX)).apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
// config.get().redirectController(req.request);
Assertions.assertEquals(controller, result.get());
}
@Test
public void testPreserveMethodOnRedirect() {
final AtomicReference<Boolean> result = new AtomicReference<>();
final AtomicReference<NettyHttpRedirectController> controller = new AtomicReference<>();
final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
class RWController extends RW {
@Override
boolean preserveMethodOnRedirect(ClientRequest request) {
result.set(super.preserveMethodOnRedirect(request));
return result.get();
}
@Override
NettyHttpRedirectController redirectController(ClientRequest request) {
controller.set(super.redirectController(request));
return controller.get();
}
@Override
public RWController instance() {
RWController max = new RWController();
config.set(max);
return max;
}
}
Request req;
req = new TestClient(new RWController()).request().apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
try {
controller.get().prepareRedirect(req.request, null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(new RWController().copy().preserveMethodOnRedirect(req.request), result.get());
result.set(null);
req = new TestClient(new RWController().preserveMethodOnRedirect(false)).request().apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
try {
controller.get().prepareRedirect(req.request, null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(false, result.get());
result.set(null);
req = new TestClient(new RWController().preserveMethodOnRedirect(true).prefix(PREFIX))
.request(r -> r.setProperty(PREFIX + NettyClientProperties.PRESERVE_METHOD_ON_REDIRECT, false))
.request(r -> r.setEntity(PREFIX)).apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
try {
controller.get().prepareRedirect(req.request, null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(false, result.get());
result.set(null);
req = new TestClient(new RWController().preserveMethodOnRedirect(true).prefix(PREFIX))
.request(r -> r.setProperty(
PREFIX + ClientProperties.CONNECTOR_CONFIGURATION, new RWController().preserveMethodOnRedirect(false)))
.apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
try {
controller.get().prepareRedirect(req.request, null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(false, result.get());
result.set(null);
req = new TestClient(new RWController())
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
new RWController().preserveMethodOnRedirect(true)))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWController().preserveMethodOnRedirect(false)))
.request(r -> r.setEntity(PREFIX)).apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
try {
controller.get().prepareRedirect(req.request, null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(false, result.get());
result.set(null);
req = new TestClient(new RWController().prefix(PREFIX))
.client(c -> c.property(PREFIX + NettyClientProperties.PRESERVE_METHOD_ON_REDIRECT, false))
.request(r -> r.setProperty(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
new RWController().preserveMethodOnRedirect(true)))
.request(r -> r.setEntity(PREFIX)).apply();
new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
try {
controller.get().prepareRedirect(req.request, null);
} catch (NullPointerException expected) {
}
Assertions.assertEquals(false, result.get());
}
@Test
public void testFilterHeadersForProxy() {
final AtomicReference<ClientProxy> proxy = new AtomicReference<>();
final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
class RWProxy extends RW {
@Override
public Optional<ClientProxy> proxy(ClientRequest request, URI requestUri) {
Optional<ClientProxy> oProxy = super.proxy(request, requestUri);
proxy.set(oProxy.orElse(null));
return oProxy;
}
@Override
public RWProxy instance() {
RWProxy rw = new RWProxy();
config.set(rw);
return rw;
}
}
String proxyUri = "http://proxy.org:8080";
String userName = "USERNAME";
String password = "PASSWORD";
Request req;
req = new TestClient(new RWProxy().proxyUri(proxyUri).proxyUserName(userName).proxyPassword(password)).request().apply();
config.get().createProxyHandler(proxy.get(), req.request);
Assertions.assertEquals(((Ref<Boolean>) new RWProxy().copy().filterHeadersForProxy).get(),
((Ref<Boolean>) config.get().filterHeadersForProxy).get());
config.set(null);
req = new TestClient(new RWProxy().proxyUri(proxyUri).proxyUserName(userName).proxyPassword(password)
.filterHeadersForProxy(false)).request().apply();
config.get().createProxyHandler(proxy.get(), req.request);
Assertions.assertEquals(false, ((Ref<Boolean>) config.get().filterHeadersForProxy).get());
config.set(null);
req = new TestClient(new RWProxy().proxyUri(proxyUri).proxyUserName(userName).proxyPassword(password)
.prefix(PREFIX))
.request(r -> r.setProperty(PREFIX + NettyClientProperties.FILTER_HEADERS_FOR_PROXY, false))
.apply();
config.get().createProxyHandler(proxy.get(), req.request);
Assertions.assertEquals(false, ((Ref<Boolean>) config.get().filterHeadersForProxy).get());
config.set(null);
new TestClient(new RWProxy().proxyUri(proxyUri).proxyUserName(userName).proxyPassword(password)
.prefix(PREFIX))
.client(c -> c.property(PREFIX + NettyClientProperties.FILTER_HEADERS_FOR_PROXY, false))
.request().apply();
config.get().createProxyHandler(proxy.get(), req.request);
Assertions.assertEquals(false, ((Ref<Boolean>) config.get().filterHeadersForProxy).get());
config.set(null);
new TestClient(new RWProxy().proxyUri(proxyUri).proxyUserName(userName).proxyPassword(password)
.prefix(PREFIX))
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
NettyConnectorProvider.config().filterHeadersForProxy(false).prefix(PREFIX)))
.request().apply();
config.get().createProxyHandler(proxy.get(), req.request);
Assertions.assertEquals(false, ((Ref<Boolean>) config.get().filterHeadersForProxy).get());
config.set(null);
new TestClient(new RWProxy().proxyUri(proxyUri).proxyUserName(userName).proxyPassword(password)
.prefix(PREFIX))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
NettyConnectorProvider.config().filterHeadersForProxy(false).prefix(PREFIX)))
.apply();
config.get().createProxyHandler(proxy.get(), req.request);
Assertions.assertEquals(false, ((Ref<Boolean>) config.get().filterHeadersForProxy).get());
}
@Test
public void testFirstHttpHeaderLineLength() {
final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
final AtomicReference<Integer> result = new AtomicReference<>();
class RWFHHLL extends RW {
@Override
HttpClientCodec createHttpClientCodec(Map<String, Object> properties) {
HttpClientCodec codec = super.createHttpClientCodec(properties);
result.set(firstHttpHeaderLineLength.get());
return codec;
}
@Override
public RWFHHLL instance() {
RWFHHLL rw = new RWFHHLL();
config.set(rw);
return rw;
}
}
Request req;
req = new TestClient(new RWFHHLL()).request().apply();
config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
Assertions.assertEquals(NettyClientProperties.DEFAULT_INITIAL_LINE_LENGTH, result.get());
result.set(null);
req = new TestClient(new RWFHHLL().initialHttpHeaderLineLength(5555)).request().apply();
config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
Assertions.assertEquals(5555, result.get());
result.set(null);
req = new TestClient(new RWFHHLL().initialHttpHeaderLineLength(1111).prefix(PREFIX))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWFHHLL().initialHttpHeaderLineLength(5555).prefix(PREFIX))).apply();
config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
Assertions.assertEquals(5555, result.get());
result.set(null);
req = new TestClient(new RWFHHLL().initialHttpHeaderLineLength(1111).prefix(PREFIX))
.client(c -> c.property(PREFIX + NettyClientProperties.MAX_INITIAL_LINE_LENGTH, 5555))
.request().apply();
config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
Assertions.assertEquals(5555, result.get());
result.set(null);
req = new TestClient(new RWFHHLL().prefix(PREFIX))
.client(c -> c.property(PREFIX + NettyClientProperties.MAX_INITIAL_LINE_LENGTH, 5555))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWFHHLL().initialHttpHeaderLineLength(8888).prefix(PREFIX)))
.apply();
config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
Assertions.assertEquals(5555, result.get());
}
@Test
public void testLoggingHandler() {
final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
class RWLog extends RW {
@Override
public RWLog instance() {
RWLog rw = new RWLog();
config.set(rw);
return rw;
}
}
new TestClient(new RWLog()).request().apply();
Assertions.assertFalse(config.get().loggingEnabled.get());
new TestClient(new RWLog().enableLoggingHandler(true)).request().apply();
Assertions.assertTrue(config.get().loggingEnabled.get());
new TestClient(new RWLog().enableLoggingHandler(false).prefix(PREFIX))
.request(r -> r.setProperty(NettyClientProperties.LOGGING_ENABLED, true))
.apply();
Assertions.assertFalse(config.get().loggingEnabled.get());
new TestClient(new RWLog().enableLoggingHandler(false).prefix(PREFIX))
.client(c -> c.property(PREFIX + NettyClientProperties.LOGGING_ENABLED, true))
.request()
.apply();
Assertions.assertTrue(config.get().loggingEnabled.get());
new TestClient(new RWLog().enableLoggingHandler(false).prefix(PREFIX))
.request(r -> r.setProperty(PREFIX + NettyClientProperties.LOGGING_ENABLED, true))
.apply();
Assertions.assertTrue(config.get().loggingEnabled.get());
new TestClient(new RWLog().enableLoggingHandler(false).prefix(PREFIX))
.client(c -> c.property(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
new RWLog().enableLoggingHandler(true)))
.request()
.apply();
Assertions.assertTrue(config.get().loggingEnabled.get());
new TestClient(new RWLog().enableLoggingHandler(false).prefix(PREFIX))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWLog().enableLoggingHandler(true).prefix(PREFIX)))
.apply();
Assertions.assertTrue(config.get().loggingEnabled.get());
}
@Test
public void testMaxHeaderSize() {
final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
final AtomicReference<Integer> result = new AtomicReference<>();
class RWSize extends RW {
@Override
HttpClientCodec createHttpClientCodec(Map<String, Object> properties) {
HttpClientCodec codec = super.createHttpClientCodec(properties);
result.set(maxHeaderSize.get());
return codec;
}
@Override
public RWSize instance() {
RWSize rw = new RWSize();
config.set(rw);
return rw;
}
}
Request req;
req = new TestClient(new RWSize()).request().apply();
config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
Assertions.assertEquals(NettyClientProperties.DEFAULT_HEADER_SIZE, result.get());
result.set(null);
req = new TestClient(new RWSize().maxHeaderSize(5555)).request().apply();
config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
Assertions.assertEquals(5555, result.get());
result.set(null);
req = new TestClient(new RWSize().maxHeaderSize(1111).prefix(PREFIX))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWSize().maxHeaderSize(5555).prefix(PREFIX))).apply();
config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
Assertions.assertEquals(5555, result.get());
result.set(null);
req = new TestClient(new RWSize().maxHeaderSize(1111).prefix(PREFIX))
.client(c -> c.property(PREFIX + NettyClientProperties.MAX_HEADER_SIZE, 5555))
.request().apply();
config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
Assertions.assertEquals(5555, result.get());
result.set(null);
req = new TestClient(new RWSize().prefix(PREFIX))
.client(c -> c.property(PREFIX + NettyClientProperties.MAX_HEADER_SIZE, 5555))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWSize().maxHeaderSize(8888).prefix(PREFIX)))
.apply();
config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
Assertions.assertEquals(5555, result.get());
}
@Test
public void testMaxChunkSize() {
final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
final AtomicReference<Integer> result = new AtomicReference<>();
class RWSize extends RW {
@Override
HttpClientCodec createHttpClientCodec(Map<String, Object> properties) {
HttpClientCodec codec = super.createHttpClientCodec(properties);
result.set(maxChunkSize.get());
return codec;
}
@Override
public RWSize instance() {
RWSize rw = new RWSize();
config.set(rw);
return rw;
}
}
Request req;
req = new TestClient(new RWSize()).request().apply();
config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
Assertions.assertEquals(NettyClientProperties.DEFAULT_CHUNK_SIZE, result.get());
result.set(null);
req = new TestClient(new RWSize().maxChunkSize(5555)).request().apply();
config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
Assertions.assertEquals(5555, result.get());
result.set(null);
req = new TestClient(new RWSize().maxChunkSize(1111).prefix(PREFIX))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWSize().maxChunkSize(5555).prefix(PREFIX))).apply();
config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
Assertions.assertEquals(5555, result.get());
result.set(null);
req = new TestClient(new RWSize().maxChunkSize(1111).prefix(PREFIX))
.client(c -> c.property(PREFIX + NettyClientProperties.MAX_CHUNK_SIZE, 5555))
.request().apply();
config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
Assertions.assertEquals(5555, result.get());
result.set(null);
req = new TestClient(new RWSize().prefix(PREFIX))
.client(c -> c.property(PREFIX + NettyClientProperties.MAX_CHUNK_SIZE, 5555))
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
new RWSize().maxChunkSize(8888).prefix(PREFIX)))
.apply();
config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
Assertions.assertEquals(5555, result.get());
}
@Test
public void testMaxTotalConnections() {
final AtomicReference<Integer> result = new AtomicReference<>();
class RWConn extends RW {
@Override
NettyConnectorProvider.Config.RW fromClient(Client client) {
NettyConnectorProvider.Config.RW rw = super.fromClient(client);
result.set(rw.maxPoolSizeTotal.get());
return rw;
}
@Override
public RWConn instance() {
return new RWConn();
}
}
new TestClient(new RWConn().maxTotalConnections(55)).request().apply();
Assertions.assertEquals(55, result.get());
result.set(null);
new TestClient(new RWConn().prefix(PREFIX))
.client(c -> c.property(PREFIX + NettyClientProperties.MAX_CONNECTIONS_TOTAL, 55))
.request().apply();
Assertions.assertEquals(55, result.get());
result.set(null);
new TestClient(new RWConn().prefix(PREFIX))
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
NettyConnectorProvider.config().prefix(PREFIX).maxTotalConnections(55)))
.request().apply();
Assertions.assertEquals(55, result.get());
result.set(null);
new TestClient(new RWConn().prefix(PREFIX))
// NOT PER REQUEST
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
NettyConnectorProvider.config().prefix(PREFIX).maxTotalConnections(55)))
.apply();
Assertions.assertEquals(new RWConn().copy().maxPoolSizeTotal.get(), result.get());
}
@Test
public void testMaxConnectionsPerDestination() {
final AtomicReference<Integer> result = new AtomicReference<>();
class RWConn extends RW {
@Override
NettyConnectorProvider.Config.RW fromClient(Client client) {
NettyConnectorProvider.Config.RW rw = super.fromClient(client);
result.set(rw.maxPoolSize.get());
return rw;
}
@Override
public RWConn instance() {
return new RWConn();
}
}
new TestClient(new RWConn().maxConnectionsPerDestination(15)).request().apply();
Assertions.assertEquals(15, result.get());
result.set(null);
new TestClient(new RWConn().prefix(PREFIX))
.client(c -> c.property(PREFIX + NettyClientProperties.MAX_CONNECTIONS, 15))
.request().apply();
Assertions.assertEquals(15, result.get());
result.set(null);
new TestClient(new RWConn().prefix(PREFIX))
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
NettyConnectorProvider.config().prefix(PREFIX).maxConnectionsPerDestination(15)))
.request().apply();
Assertions.assertEquals(15, result.get());
result.set(null);
new TestClient(new RWConn().prefix(PREFIX))
// NOT PER REQUEST
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
NettyConnectorProvider.config().prefix(PREFIX).maxConnectionsPerDestination(15)))
.apply();
Assertions.assertEquals(new RWConn().copy().maxPoolSize.get(), result.get());
}
@Test
public void testIdleConnectionPruneTimeout() {
final AtomicReference<Integer> result = new AtomicReference<>();
class RWConn extends RW {
@Override
NettyConnectorProvider.Config.RW fromClient(Client client) {
NettyConnectorProvider.Config.RW rw = super.fromClient(client);
result.set(rw.maxPoolIdle.get());
return rw;
}
@Override
public RWConn instance() {
return new RWConn();
}
}
new TestClient(new RWConn().idleConnectionPruneTimeout(15)).request().apply();
Assertions.assertEquals(15, result.get());
result.set(null);
new TestClient(new RWConn().prefix(PREFIX))
.client(c -> c.property(PREFIX + NettyClientProperties.IDLE_CONNECTION_PRUNE_TIMEOUT, 15))
.request().apply();
Assertions.assertEquals(15, result.get());
result.set(null);
new TestClient(new RWConn().prefix(PREFIX))
.client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
NettyConnectorProvider.config().prefix(PREFIX).idleConnectionPruneTimeout(15)))
.request().apply();
Assertions.assertEquals(15, result.get());
result.set(null);
new TestClient(new RWConn().prefix(PREFIX))
// NOT PER REQUEST
.request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
NettyConnectorProvider.config().prefix(PREFIX).idleConnectionPruneTimeout(15)))
.apply();
Assertions.assertEquals(new RWConn().copy().maxPoolIdle.get(), result.get());
}
@Test
public void testPrecedence() {
NettyConnectorProvider.Config.RW builderLower = NettyConnectorProvider.config().rw();
builderLower.maxTotalConnections(55);
NettyConnectorProvider.Config.RW builderUpper = builderLower.copy();
builderUpper.maxTotalConnections(56);
Assertions.assertEquals(56, builderUpper.maxPoolSizeTotal.get());
Client client = ClientBuilder.newClient();
client.property(NettyClientProperties.MAX_CONNECTIONS_TOTAL, 57);
NettyConnectorProvider.Config.RW result = builderUpper.fromClient(client);
Assertions.assertEquals(57, result.maxPoolSizeTotal.get());
Assertions.assertEquals(60, result.maxPoolIdle.get());
}
private static class ConnectorConfig extends ConnectorConfiguration<ConnectorConfig> {
private static class RW extends ConnectorConfiguration<RW> implements Read<RW> {
@Override
public RW instance() {
return new RW();
}
@Override
public RW me() {
return this;
}
public Configuration config() {
Map<String, Object> empty = new HashMap<>();
Configuration configuration = (Configuration) Proxy.newProxyInstance(
getClass().getClassLoader(),
new Class[]{Configuration.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
switch (method.getName()) {
case "getProperties":
return empty;
case "getProperty":
return empty.get(args[0]);
}
return null;
}
});
return configuration;
}
}
}
private static class RW extends NettyConnectorProvider.Config.RW {
@Override
public int connectTimeout() {
throw new IllegalStateException();
}
}
private static class TestClient {
private final NettyConnectorProvider.Config.RW rw;
private final Client client;
private TestClient(NettyConnectorProvider.Config.RW rw) {
this.rw = rw;
this.client = ClientBuilder.newClient(new ClientConfig().connectorProvider(new NettyConnectorProvider()));
}
public TestClient client(Consumer<Client> consumer) {
consumer.accept(client);
return this;
}
public TestClient rw(Consumer<NettyConnectorProvider.Config.RW> consumer) {
consumer.accept(rw);
return this;
}
public Request request() {
return new Request(client, rw);
}
public Request request(Consumer<ClientRequest> consumer) {
return request().request(consumer);
}
}
private static class Request {
final ClientRequest request;
final Client client;
final NettyConnectorProvider.Config.RW rw;
NettyConnector connector;
Request(Client client, NettyConnectorProvider.Config.RW rw) {
this.client = client;
this.rw = rw;
request = createRequest(client);
}
public Request request(Consumer<ClientRequest> consumer) {
consumer.accept(request);
return this;
}
public Request apply() {
try {
connector = new NettyConnector(client, rw);
connector.apply(request);
} catch (ProcessingException expected) {
}
return this;
}
}
}