This is an automated email from the ASF dual-hosted git repository. dkulp pushed a commit to branch 3.6.x-fixes in repository https://gitbox.apache.org/repos/asf/cxf.git
commit 5e7f4272c98df43c37a7a96bbf3cbb3a321cb871 Author: Andriy Redko <drr...@gmail.com> AuthorDate: Sun Mar 26 20:14:06 2023 -0400 Fix NullPointerException when reactive clients are configured with SSL/TLS, add tests (#1206) --- .../cxf/transport/http/HttpClientHTTPConduit.java | 4 +- ...r.java => AbstractCompletableFutureServer.java} | 12 +++-- ....java => AbstractJAXRSCompletionStageTest.java} | 37 ++++++--------- .../reactive/CompletableFutureHttpServer.java | 37 +++++++++++++++ .../reactive/CompletableFutureHttpsServer.java | 37 +++++++++++++++ .../reactive/JAXRSCompletionStageHttpTest.java | 43 ++++++++++++++++++ .../reactive/JAXRSCompletionStageHttpsTest.java | 52 ++++++++++++++++++++++ .../jaxrs/reactive/reactive-https-client.xml | 37 +++++++++++++++ .../jaxrs/reactive/reactive-https-server.xml | 40 +++++++++++++++++ 9 files changed, 267 insertions(+), 32 deletions(-) diff --git a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpClientHTTPConduit.java b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpClientHTTPConduit.java index da1e0d9717..e228893a9b 100644 --- a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpClientHTTPConduit.java +++ b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpClientHTTPConduit.java @@ -111,7 +111,9 @@ public class HttpClientHTTPConduit extends URLConnectionHTTPConduit { if (clientParameters == null) { clientParameters = tlsClientParameters; } - + if (clientParameters == null) { + clientParameters = new TLSClientParameters(); + } Object o = message.getContextualProperty("force.urlconnection.http.conduit"); //o = true; if ("https".equals(uri.getScheme()) && clientParameters != null) { diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/CompletableFutureServer.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/AbstractCompletableFutureServer.java similarity index 92% rename from systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/CompletableFutureServer.java rename to systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/AbstractCompletableFutureServer.java index 37a19ccefa..e590842e33 100644 --- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/CompletableFutureServer.java +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/AbstractCompletableFutureServer.java @@ -40,22 +40,20 @@ import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider; import org.apache.cxf.testutil.common.AbstractServerTestServerBase; -public class CompletableFutureServer extends AbstractServerTestServerBase { - public static final String PORT = allocatePort(CompletableFutureServer.class); - +public abstract class AbstractCompletableFutureServer extends AbstractServerTestServerBase { @Override protected Server createServer(Bus bus) throws Exception { JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean(); sf.setResourceClasses(CompletableFutureService.class); sf.setResourceProvider(CompletableFutureService.class, new SingletonResourceProvider(new CompletableFutureService(), true)); - sf.setAddress("http://localhost:" + PORT + "/"); + sf.setAddress(getProtocol() + "://localhost:" + getPort() + "/"); sf.setProvider(new MappedExceptionMapper()); return sf.create(); } public static void main(String[] args) throws Exception { - new CompletableFutureServer().start(); + new CompletableFutureHttpServer().start(); } @Consumes("text/boolean") @@ -95,8 +93,8 @@ public class CompletableFutureServer extends AbstractServerTestServerBase { os.write(bytes); } - - } + public abstract String getPort(); + public abstract String getProtocol(); } diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/JAXRSCompletionStageTest.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/AbstractJAXRSCompletionStageTest.java similarity index 80% rename from systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/JAXRSCompletionStageTest.java rename to systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/AbstractJAXRSCompletionStageTest.java index 76ebeb914b..4672cdc333 100644 --- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/JAXRSCompletionStageTest.java +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/AbstractJAXRSCompletionStageTest.java @@ -29,11 +29,9 @@ import javax.ws.rs.NotFoundException; import javax.xml.ws.Holder; import org.apache.cxf.jaxrs.client.WebClient; -import org.apache.cxf.jaxrs.model.AbstractResourceInfo; import org.apache.cxf.systest.jaxrs.Book; import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase; -import org.junit.BeforeClass; import org.junit.Test; import static org.hamcrest.CoreMatchers.instanceOf; @@ -42,20 +40,10 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -public class JAXRSCompletionStageTest extends AbstractBusClientServerTestBase { - public static final String PORT = CompletableFutureServer.PORT; - - @BeforeClass - public static void startServers() throws Exception { - AbstractResourceInfo.clearAllMaps(); - assertTrue("server did not launch correctly", - launchServer(CompletableFutureServer.class, true)); - createStaticBus(); - } - +public abstract class AbstractJAXRSCompletionStageTest extends AbstractBusClientServerTestBase { @Test public void testGetBookAsyncStage() throws Exception { - String address = "http://localhost:" + PORT + "/completable/books"; + String address = getAddress() + "/completable/books"; WebClient wc = createWebClient(address); CompletionStage<Book> stage = wc.path("123").rx().get(Book.class); Book book = stage.toCompletableFuture().join(); @@ -63,7 +51,7 @@ public class JAXRSCompletionStageTest extends AbstractBusClientServerTestBase { } @Test public void testGetBookAsyncStageAsyncResponse() throws Exception { - String address = "http://localhost:" + PORT + "/completable/booksAsync"; + String address = getAddress() + "/completable/booksAsync"; WebClient wc = createWebClient(address); CompletionStage<Book> stage = wc.path("123").rx().get(Book.class); Book book = stage.toCompletableFuture().join(); @@ -71,7 +59,7 @@ public class JAXRSCompletionStageTest extends AbstractBusClientServerTestBase { } @Test public void testGetBookAsyncStageThenAcceptAsync() throws Exception { - String address = "http://localhost:" + PORT + "/completable/books"; + String address = getAddress() + "/completable/books"; WebClient wc = createWebClient(address); CompletionStage<Book> stage = wc.path("123").rx().get(Book.class); Holder<Book> holder = new Holder<>(); @@ -87,7 +75,7 @@ public class JAXRSCompletionStageTest extends AbstractBusClientServerTestBase { @Test public void testGetBookAsyncStage404() throws Exception { - String address = "http://localhost:" + PORT + "/completable/books"; + String address = getAddress() + "/completable/books"; WebClient wc = createWebClient(address); CompletionStage<Book> stage = wc.path("124").rx().get(Book.class); try { @@ -100,7 +88,7 @@ public class JAXRSCompletionStageTest extends AbstractBusClientServerTestBase { @Test public void testGetBookAsyncStageThrowsBadRequestException() throws Exception { - String address = "http://localhost:" + PORT + "/completable/badRequest"; + String address = getAddress() + "/completable/badRequest"; WebClient wc = createWebClient(address); CompletionStage<Book> stage = wc.path("123").rx().get(Book.class); try { @@ -113,7 +101,7 @@ public class JAXRSCompletionStageTest extends AbstractBusClientServerTestBase { @Test public void testGetBookAsyncStageThrowsForbiddenException() throws Exception { - String address = "http://localhost:" + PORT + "/completable/forbidden"; + String address = getAddress() + "/completable/forbidden"; WebClient wc = createWebClient(address); CompletionStage<Book> stage = wc.path("123").rx().get(Book.class); try { @@ -126,7 +114,7 @@ public class JAXRSCompletionStageTest extends AbstractBusClientServerTestBase { @Test public void testGetBookAsyncStageThrowsNotAuthorizedException() throws Exception { - String address = "http://localhost:" + PORT + "/completable/unauthorized"; + String address = getAddress() + "/completable/unauthorized"; WebClient wc = createWebClient(address); CompletionStage<Book> stage = wc.path("123").rx().get(Book.class); try { @@ -139,7 +127,7 @@ public class JAXRSCompletionStageTest extends AbstractBusClientServerTestBase { @Test public void testGetBookAsyncStageThrowsBadRequestMappedException() throws Exception { - String address = "http://localhost:" + PORT + "/completable/mapped/badRequest"; + String address = getAddress() + "/completable/mapped/badRequest"; WebClient wc = createWebClient(address); CompletionStage<Book> stage = wc.path("123").rx().get(Book.class); try { @@ -152,7 +140,7 @@ public class JAXRSCompletionStageTest extends AbstractBusClientServerTestBase { @Test public void testGetBookAsyncStageThrowsForbiddenMappedException() throws Exception { - String address = "http://localhost:" + PORT + "/completable/mapped/forbidden"; + String address = getAddress() + "/completable/mapped/forbidden"; WebClient wc = createWebClient(address); CompletionStage<Book> stage = wc.path("123").rx().get(Book.class); try { @@ -165,7 +153,7 @@ public class JAXRSCompletionStageTest extends AbstractBusClientServerTestBase { @Test public void testGetBookAsyncStageThrowsNotAuthorizedMappedException() throws Exception { - String address = "http://localhost:" + PORT + "/completable/mapped/unauthorized"; + String address = getAddress() + "/completable/mapped/unauthorized"; WebClient wc = createWebClient(address); CompletionStage<Book> stage = wc.path("123").rx().get(Book.class); try { @@ -176,8 +164,9 @@ public class JAXRSCompletionStageTest extends AbstractBusClientServerTestBase { } } - private WebClient createWebClient(String address) { + protected WebClient createWebClient(String address) { return WebClient.create(address); } + protected abstract String getAddress(); } diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/CompletableFutureHttpServer.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/CompletableFutureHttpServer.java new file mode 100644 index 0000000000..07dc4d29b4 --- /dev/null +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/CompletableFutureHttpServer.java @@ -0,0 +1,37 @@ +/** + * 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. + */ + +package org.apache.cxf.systest.jaxrs.reactive; + +import org.apache.cxf.testutil.common.TestUtil; + +public class CompletableFutureHttpServer extends AbstractCompletableFutureServer { + public static final String PORT = TestUtil.getPortNumber("reactive-http"); + + + @Override + public String getPort() { + return PORT; + } + + @Override + public String getProtocol() { + return "http"; + } +} diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/CompletableFutureHttpsServer.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/CompletableFutureHttpsServer.java new file mode 100644 index 0000000000..c84ca508d1 --- /dev/null +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/CompletableFutureHttpsServer.java @@ -0,0 +1,37 @@ +/** + * 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. + */ + +package org.apache.cxf.systest.jaxrs.reactive; + +import org.apache.cxf.testutil.common.TestUtil; + +public class CompletableFutureHttpsServer extends AbstractCompletableFutureServer { + public static final String PORT = TestUtil.getPortNumber("reactive-https"); + + + @Override + public String getPort() { + return PORT; + } + + @Override + public String getProtocol() { + return "https"; + } +} diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/JAXRSCompletionStageHttpTest.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/JAXRSCompletionStageHttpTest.java new file mode 100644 index 0000000000..32abbe76be --- /dev/null +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/JAXRSCompletionStageHttpTest.java @@ -0,0 +1,43 @@ +/** + * 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. + */ + +package org.apache.cxf.systest.jaxrs.reactive; + +import org.apache.cxf.jaxrs.model.AbstractResourceInfo; + +import org.junit.BeforeClass; + +import static org.junit.Assert.assertTrue; + +public class JAXRSCompletionStageHttpTest extends AbstractJAXRSCompletionStageTest { + public static final String PORT = CompletableFutureHttpServer.PORT; + + @BeforeClass + public static void startServers() throws Exception { + AbstractResourceInfo.clearAllMaps(); + createStaticBus(); + assertTrue("server did not launch correctly", + launchServer(CompletableFutureHttpServer.class, true)); + } + + @Override + protected String getAddress() { + return "http://localhost:" + PORT; + } +} diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/JAXRSCompletionStageHttpsTest.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/JAXRSCompletionStageHttpsTest.java new file mode 100644 index 0000000000..f04fec9022 --- /dev/null +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/JAXRSCompletionStageHttpsTest.java @@ -0,0 +1,52 @@ +/** + * 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. + */ + +package org.apache.cxf.systest.jaxrs.reactive; + +import java.util.List; + +import org.apache.cxf.jaxrs.client.WebClient; +import org.apache.cxf.jaxrs.model.AbstractResourceInfo; + +import org.junit.BeforeClass; + +import static org.junit.Assert.assertTrue; + +public class JAXRSCompletionStageHttpsTest extends AbstractJAXRSCompletionStageTest { + public static final String PORT = CompletableFutureHttpsServer.PORT; + + @BeforeClass + public static void startServers() throws Exception { + AbstractResourceInfo.clearAllMaps(); + createStaticBus("org/apache/cxf/systest/jaxrs/reactive/reactive-https-server.xml"); + assertTrue("server did not launch correctly", + launchServer(CompletableFutureHttpsServer.class, true)); + } + + @Override + protected String getAddress() { + return "https://localhost:" + PORT; + } + + + @Override + protected WebClient createWebClient(String address) { + return WebClient.create(address, List.of(), "org/apache/cxf/systest/jaxrs/reactive/reactive-https-client.xml"); + } +} diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/reactive-https-client.xml b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/reactive-https-client.xml new file mode 100644 index 0000000000..716170f5f1 --- /dev/null +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/reactive-https-client.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +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. +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:http="http://cxf.apache.org/transports/http/configuration" + xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration" + xmlns:sec="http://cxf.apache.org/configuration/security" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/transports/http-jetty/configuration http://cxf.apache.org/schemas/configuration/http-jetty.xsd http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd"> + <http:conduit name="\{https://localhost\:.*\}WebClient\.http-conduit"> + <http:client ConnectionTimeout="3000000" ReceiveTimeout="3000000"/> + <http:tlsClientParameters disableCNCheck="true"> + <sec:keyManagers keyPassword="password"> + <sec:keyStore type="JKS" password="password" resource="keys/Morpit.jks"/> + </sec:keyManagers> + <sec:trustManagers> + <sec:keyStore type="JKS" password="password" resource="keys/Truststore.jks"/> + </sec:trustManagers> + </http:tlsClientParameters> + </http:conduit> +</beans> \ No newline at end of file diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/reactive-https-server.xml b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/reactive-https-server.xml new file mode 100644 index 0000000000..5e0047406d --- /dev/null +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/reactive/reactive-https-server.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +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. +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:http="http://cxf.apache.org/transports/http/configuration" + xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration" + xmlns:sec="http://cxf.apache.org/configuration/security" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd http://cxf.apache.org/transports/http-jetty/configuration http://cxf.apache.org/schemas/configuration/http-jetty.xsd http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd"> + <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"/> + <httpj:engine-factory id="port-9095-tls-config"> + <httpj:engine port="${testutil.ports.reactive-https}"> + <httpj:tlsServerParameters> + <sec:keyManagers keyPassword="password"> + <sec:keyStore type="JKS" password="password" resource="keys/Bethal.jks"/> + </sec:keyManagers> + <sec:trustManagers> + <sec:keyStore type="JKS" password="password" resource="keys/Truststore.jks"/> + </sec:trustManagers> + <sec:clientAuthentication want="false" required="false"/> + </httpj:tlsServerParameters> + </httpj:engine> + </httpj:engine-factory> +</beans> \ No newline at end of file