diff --git a/docbook/src/main/doc/adoc/content/chapter-3-JAX_WS_User_Guide.adoc b/docbook/src/main/doc/adoc/content/chapter-3-JAX_WS_User_Guide.adoc index 8694b2ac4..1708e82e7 100644 --- a/docbook/src/main/doc/adoc/content/chapter-3-JAX_WS_User_Guide.adoc +++ b/docbook/src/main/doc/adoc/content/chapter-3-JAX_WS_User_Guide.adoc @@ -521,6 +521,25 @@ public void testConfigureTimeout() throws Exception } .... +==== HTTP/2 Support + +Starting from JBossWS 7.1.0, the new default CXF HTTP client transport supports HTTP/2 by default. +The client automatically uses HTTP/2 if the HTTP/2 is supported by server. Otherwise, it falls back to +HTTP/1.1. +The client http version can be defined with the `org.apache.cxf.transport.http.forceVersion` property. +This property can be set to system or bus property. Below is an example illustrating how +to enforce http version to 1.1: +``` + BusFactory.getDefaultBus().setProperty("org.apache.cxf.transport.http.forceVersion", "1"); + HelloWorld port = getPort(); + String response = port.echo("hello"); +``` +CXF offers the contextual property `force.urlconnection.http.conduit"` to switch to the old cxf +client that is using java.net.HttpURLConnection/javax.net.ssl.HttpsURLConnection. It supports +HTTP/1.1 by default and has better performance. If client performance is a priority and HTTP/2 support is unnecessary, +this option provides a means to switch back to the previous default client. +For more information, please check out [CXF documentation](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=49941#ClientHTTPTransport(includingSSLsupport)-DefaultClientTransport). + === Common API diff --git a/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/http2/HelloWorld.java b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/http2/HelloWorld.java new file mode 100644 index 000000000..1e05cbc0a --- /dev/null +++ b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/http2/HelloWorld.java @@ -0,0 +1,27 @@ +/* + * 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.jboss.test.ws.jaxws.cxf.http2; + +import jakarta.jws.WebService; + +@WebService(targetNamespace = "http://org.jboss.ws/jaxws/cxf/http2") +public interface HelloWorld +{ + String echo(String input); +} diff --git a/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/http2/HelloWorldImpl.java b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/http2/HelloWorldImpl.java new file mode 100644 index 000000000..0c425efc3 --- /dev/null +++ b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/http2/HelloWorldImpl.java @@ -0,0 +1,35 @@ +/* + * 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.jboss.test.ws.jaxws.cxf.http2; + +import jakarta.jws.WebService; + +@WebService +( + serviceName = "HelloWorldService", + endpointInterface = "org.jboss.test.ws.jaxws.cxf.http2.HelloWorld", + targetNamespace = "http://org.jboss.ws/jaxws/cxf/http2" +) +public class HelloWorldImpl implements HelloWorld +{ + public String echo(String input) + { + return input; + } +} diff --git a/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/http2/Http2EndpointTestCaseForked.java b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/http2/Http2EndpointTestCaseForked.java new file mode 100644 index 000000000..06b81c826 --- /dev/null +++ b/modules/testsuite/cxf-tests/src/test/java/org/jboss/test/ws/jaxws/cxf/http2/Http2EndpointTestCaseForked.java @@ -0,0 +1,110 @@ +/* + * 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.jboss.test.ws.jaxws.cxf.http2; + +import jakarta.xml.ws.Service; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.PrintStream; +import java.net.MalformedURLException; +import java.net.URL; +import javax.xml.namespace.QName; +import org.apache.cxf.BusFactory; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.container.test.api.RunAsClient; +import org.jboss.arquillian.junit5.ArquillianExtension; +import org.jboss.arquillian.test.api.ArquillianResource; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.wsf.test.JBossWSTest; +import org.jboss.wsf.test.JBossWSTestHelper; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +@ExtendWith(ArquillianExtension.class) +public class Http2EndpointTestCaseForked extends JBossWSTest { + @ArquillianResource + private URL baseURL; + + @Deployment(testable = false) + public static WebArchive createDeployment() { + WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxws-cxf-http2.war") + .addClass(HelloWorld.class) + .addClass(HelloWorldImpl.class) + .setWebXML(new File(JBossWSTestHelper.getTestResourcesDir() + "/jaxws/cxf/http2/WEB-INF/web.xml")); + return archive; + } + + @Test + @RunAsClient + public void testHttp2() throws Exception { + BusFactory.setDefaultBus(null); + BusFactory.getDefaultBus().setProperty("org.apache.cxf.transport.http.forceVersion", "2"); + //enable jdk httpclient debug and it prints debug log message to system.err + System.setProperty("jdk.internal.httpclient.debug", "true"); + PrintStream old = System.err; + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintStream ps = new PrintStream(baos); + System.setErr(ps); + HelloWorld port = getPort(); + String response = port.echo("hello"); + Assertions.assertEquals("hello", response,"hello is expected"); + ps.flush(); + Assertions.assertTrue( baos.toString().contains("ExchangeImpl get: Trying to get HTTP/2 connection"), "HTTP2Connection is expected to use"); + }finally { + System.setErr(old); + System.clearProperty("jdk.internal.httpclient.debug"); + } + } + + @Test + @RunAsClient + public void testHttp11() throws Exception { + System.setProperty("jdk.internal.httpclient.debug", "true"); + BusFactory.setDefaultBus(null); + BusFactory.getDefaultBus().setProperty("org.apache.cxf.transport.http.forceVersion", "1.1"); + PrintStream old = System.err; + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintStream ps = new PrintStream(baos); + System.setErr(ps); + HelloWorld port = getPort(); + String response = port.echo("hello"); + Assertions.assertEquals("hello", response,"hello is expected"); + ps.flush(); + Assertions.assertTrue(baos.toString().contains("ExchangeImpl get: HTTP/1.1: new Http1Exchange"), "HTTP2Connection isn't expected to use"); + }finally { + System.setErr(old); + System.clearProperty("jdk.internal.httpclient.debug"); + } + } + + private HelloWorld getPort() throws MalformedURLException + { + URL wsdlURL = new URL(baseURL.toString() + "/jaxws-cxf-http2?wsdl"); + QName serviceName = new QName("http://org.jboss.ws/jaxws/cxf/http2", "HelloWorldService"); + Service service = Service.create(wsdlURL, serviceName); + QName portQName = new QName("http://org.jboss.ws/jaxws/cxf/http2", "HelloWorldImplPort"); + HelloWorld port = (HelloWorld) service.getPort(portQName, HelloWorld.class); + return port; + } +} \ No newline at end of file diff --git a/modules/testsuite/cxf-tests/src/test/resources/jaxws/cxf/http2/WEB-INF/web.xml b/modules/testsuite/cxf-tests/src/test/resources/jaxws/cxf/http2/WEB-INF/web.xml new file mode 100644 index 000000000..03f687940 --- /dev/null +++ b/modules/testsuite/cxf-tests/src/test/resources/jaxws/cxf/http2/WEB-INF/web.xml @@ -0,0 +1,17 @@ + + + + + + HelloService + org.jboss.test.ws.jaxws.cxf.http2.HelloWorldImpl + + + + HelloService + /* + + \ No newline at end of file