CXFServletTest.java
/**
* 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.servlet;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLReader;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import jakarta.jws.WebService;
import jakarta.xml.ws.Endpoint;
import jakarta.xml.ws.soap.SOAPBinding;
import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.jaxrs.model.AbstractResourceInfo;
import org.apache.cxf.staxutils.StaxUtils;
import org.apache.hello_world_soap_http.BaseGreeterImpl;
import org.apache.html.dom.HTMLAnchorElementImpl;
import org.apache.html.dom.HTMLDocumentImpl;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
public class CXFServletTest extends AbstractServletTest {
@Ignore
public static class EmbeddedJettyServer extends AbstractJettyServer {
public static final int PORT = allocatePortAsInt(EmbeddedJettyServer.class);
public EmbeddedJettyServer() {
super("/org/apache/cxf/systest/servlet/web.xml", "/", CONTEXT, PORT);
}
}
@BeforeClass
public static void startServers() throws Exception {
AbstractResourceInfo.clearAllMaps();
assertTrue("server did not launch correctly", launchServer(EmbeddedJettyServer.class, true));
createStaticBus();
}
@AfterClass
public static void tearDown() throws Exception {
stopAllServers();
}
@Test
public void testPostInvokeServices() throws Exception {
invoke(StandardCharsets.UTF_8.name());
invoke("iso-8859-1");
}
private void invoke(String encoding) throws Exception {
try (CloseableHttpClient client = newClient()) {
final HttpPost method = new HttpPost(uri("/services/greeter"));
method.setEntity(new InputStreamEntity(getClass().getResourceAsStream("GreeterMessage.xml"),
ContentType.create("text/xml", encoding)));
try (CloseableHttpResponse response = client.execute(method)) {
assertEquals("text/xml", getContentType(response));
assertEquals(encoding.toUpperCase(), getCharset(response));
Document doc = StaxUtils.read(response.getEntity().getContent());
assertNotNull(doc);
addNamespace("h", "http://apache.org/hello_world_soap_http/types");
assertValid("/s:Envelope/s:Body", doc);
assertValid("//h:sayHiResponse", doc);
}
}
}
@Test
public void testGetServiceList() throws Exception {
try (CloseableHttpClient client = newClient()) {
final HttpGet method = new HttpGet(uri("/services"));
try (CloseableHttpResponse res = client.execute(method)) {
HTMLDocumentImpl doc = parse(res.getEntity().getContent());
Collection<HTMLAnchorElementImpl> links = getLinks(doc);
assertEquals("Wrong number of service links", 6, links.size());
Set<String> links2 = new HashSet<>();
for (HTMLAnchorElementImpl l : links) {
links2.add(l.getHref());
}
assertTrue(links2.contains(uri("/services/greeter?wsdl")));
assertTrue(links2.contains(uri("/services/greeter2?wsdl")));
assertTrue(links2.contains("http://cxf.apache.org/MyGreeter?wsdl"));
assertEquals("text/html", getContentType(res));
}
try (CloseableHttpResponse res = client.execute(method)) {
HTMLDocumentImpl doc = parse(res.getEntity().getContent());
Collection<HTMLAnchorElementImpl> links = getLinks(doc);
Set<String> links2 = new HashSet<>();
for (HTMLAnchorElementImpl l : links) {
links2.add(l.getHref());
}
assertEquals("Wrong number of service links", 6, links.size());
assertTrue(links2.contains(uri("/services/greeter?wsdl")));
assertTrue(links2.contains(uri("/services/greeter2?wsdl")));
assertTrue(links2.contains("http://cxf.apache.org/MyGreeter?wsdl"));
assertEquals("text/html", getContentType(res));
// Ensure that the Bus is available for people doing an Endpoint.publish() or similar.
assertNotNull(BusFactory.getDefaultBus(false));
}
}
}
@Test
public void testGetUnformatServiceList() throws Exception {
try (CloseableHttpClient client = newClient()) {
final HttpGet method = new HttpGet(uri("/services?formatted=false"));
try (CloseableHttpResponse res = client.execute(method)) {
final String content = IOUtils.readStringFromStream(res.getEntity().getContent());
assertTrue(content.contains(uri("/services/greeter3")));
assertTrue(content.contains(uri("/services/greeter2")));
assertTrue(content.contains(uri("/services/greeter")));
}
}
}
@Test
public void testServiceListWithLoopAddress() throws Exception {
try (CloseableHttpClient client = newClient()) {
final HttpGet method = new HttpGet(uri("/services"));
try (CloseableHttpResponse res = client.execute(method)) {
final String content = IOUtils.readStringFromStream(res.getEntity().getContent());
assertTrue(content.contains(uri("/services/greeter3")));
assertTrue(content.contains(uri("/services/greeter2")));
assertTrue(content.contains(uri("/services/greeter")));
}
final HttpGet greeter = new HttpGet(uri("/services/greeter?wsdl"));
try (CloseableHttpResponse res = client.execute(greeter)) {
assertThat(res.getStatusLine().getStatusCode(), equalTo(200));
}
final HttpGet greeter2 = new HttpGet(uri("/services/greeter2?wsdl"));
try (CloseableHttpResponse res = client.execute(greeter2)) {
assertThat(res.getStatusLine().getStatusCode(), equalTo(200));
}
final HttpGet greeter3 = new HttpGet(uri("/services/greeter3?wsdl"));
try (CloseableHttpResponse res = client.execute(greeter3)) {
assertThat(res.getStatusLine().getStatusCode(), equalTo(200));
}
final HttpGet loopback = new HttpGet("http://127.0.0.1:" + getPort() + "/mycontext/services");
try (CloseableHttpResponse res = client.execute(loopback)) {
final String content = IOUtils.readStringFromStream(res.getEntity().getContent());
assertTrue(content.contains("http://127.0.0.1:" + getPort() + "/mycontext/services"));
}
}
}
@Test
public void testGetWSDL() throws Exception {
try (CloseableHttpClient client = newClient()) {
final HttpGet method = new HttpGet(uri("/services/greeter?wsdl"));
try (CloseableHttpResponse res = client.execute(method)) {
assertEquals(200, res.getStatusLine().getStatusCode());
assertEquals("text/xml", getContentType(res));
Document doc = StaxUtils.read(res.getEntity().getContent());
assertNotNull(doc);
assertValid("//wsdl:operation[@name='greetMe']", doc);
assertValid("//wsdlsoap:address[@location='" + uri("/services/greeter") + "']", doc);
}
}
}
@Test
public void testGetWSDLWithMultiplePublishedEndpointUrl() throws Exception {
try (CloseableHttpClient client = newClient()) {
final HttpGet method = new HttpGet(uri("/services/greeter5?wsdl"));
try (CloseableHttpResponse res = client.execute(method)) {
assertEquals(200, res.getStatusLine().getStatusCode());
assertEquals("text/xml", getContentType(res));
Document doc = StaxUtils.read(res.getEntity().getContent());
assertNotNull(doc);
WSDLReader wsdlReader = WSDLFactory.newInstance().newWSDLReader();
wsdlReader.setFeature("javax.wsdl.verbose", false);
assertValid(
"//wsdl:service[@name='SOAPService']/wsdl:port[@name='SoapPort']/wsdlsoap:address[@location='"
+ "http://cxf.apache.org/publishedEndpointUrl1']", doc);
assertValid(
"//wsdl:service[@name='SOAPService']/wsdl:port[@name='SoapPort1']/wsdlsoap:address[@location='"
+ "http://cxf.apache.org/publishedEndpointUrl2']", doc);
}
}
}
@Test
public void testGetWSDLWithIncludes() throws Exception {
try (CloseableHttpClient client = newClient()) {
final HttpGet wsdl = new HttpGet(uri("/services/greeter3?wsdl"));
try (CloseableHttpResponse res = client.execute(wsdl)) {
assertEquals(200, res.getStatusLine().getStatusCode());
assertEquals("text/xml", getContentType(res));
Document doc = StaxUtils.read(res.getEntity().getContent());
assertNotNull(doc);
assertXPathEquals("//xsd:include/@schemaLocation",
uri("/services/greeter3?xsd=hello_world_includes2.xsd"),
doc.getDocumentElement());
}
final HttpGet xsd = new HttpGet(uri("/services/greeter3?xsd=hello_world_includes2.xsd"));
try (CloseableHttpResponse res = client.execute(xsd)) {
assertEquals(200, res.getStatusLine().getStatusCode());
assertEquals("text/xml", getContentType(res));
Document doc = StaxUtils.read(res.getEntity().getContent());
assertNotNull(doc);
assertValid("//xsd:complexType[@name='ErrorCode']", doc);
}
}
}
@Test
public void testGetWSDLWithXMLBinding() throws Exception {
try (CloseableHttpClient client = newClient()) {
final HttpGet method = new HttpGet(uri("/services/greeter2?wsdl"));
try (CloseableHttpResponse res = client.execute(method)) {
assertEquals(200, res.getStatusLine().getStatusCode());
assertEquals("text/xml", getContentType(res));
Document doc = StaxUtils.read(res.getEntity().getContent());
assertNotNull(doc);
addNamespace("http", "http://schemas.xmlsoap.org/wsdl/http/");
assertValid("//wsdl:operation[@name='greetMe']", doc);
NodeList addresses = assertValid("//http:address/@location", doc);
boolean found = true;
for (int i = 0; i < addresses.getLength(); i++) {
String address = addresses.item(i).getLocalName();
if (address.startsWith("http://localhost") && address.endsWith("/services/greeter2")) {
found = true;
break;
}
}
assertTrue(found);
}
}
}
@Test
public void testInvalidServiceUrl() throws Exception {
try (CloseableHttpClient client = newClient()) {
final HttpGet method = new HttpGet(uri("/services/NoSuchService"));
try (CloseableHttpResponse res = client.execute(method)) {
assertEquals(404, res.getStatusLine().getStatusCode());
assertEquals("text/html", getContentType(res));
}
}
}
@Test
public void testServiceWsdlNotFound() throws Exception {
final HttpGet method = new HttpGet(uri("/services/NoSuchService?wsdl"));
expectErrorCode(method, 404, "Response code 404 required for invalid WSDL url.");
}
@Test
public void testGetImportedXSD() throws Exception {
try (CloseableHttpClient client = newClient()) {
final HttpGet wsdl = new HttpGet(uri("/services/greeter?wsdl"));
try (CloseableHttpResponse res = client.execute(wsdl)) {
assertEquals(200, res.getStatusLine().getStatusCode());
final String text = IOUtils.readStringFromStream(res.getEntity().getContent());
assertEquals("text/xml", getContentType(res));
assertTrue(text.contains(uri("/services/greeter?wsdl=test_import.xsd")));
}
final HttpGet xsd = new HttpGet(uri("/services/greeter?wsdl=test_import.xsd"));
try (CloseableHttpResponse res = client.execute(xsd)) {
assertEquals(200, res.getStatusLine().getStatusCode());
final String text = IOUtils.readStringFromStream(res.getEntity().getContent());
assertEquals("text/xml", getContentType(res));
assertTrue("the xsd should contain the completType SimpleStruct",
text.contains("<complexType name=\"SimpleStruct\">"));
}
}
}
@Test
public void testGetBinding() throws Exception {
final Bus bus = BusFactory.getDefaultBus();
try {
BusFactory.setDefaultBus(null);
Endpoint ep = Endpoint.create("http://schemas.xmlsoap.org/wsdl/soap/http", new HelloImpl());
assertTrue(ep.getBinding() instanceof SOAPBinding);
} finally {
BusFactory.setDefaultBus(bus);
}
}
@WebService(name = "Hello", portName = "HelloPort",
serviceName = "HelloService", targetNamespace = "http://cxf.apache.org/hello")
public static class HelloImpl {
public String hello(String name) {
return "Hello " + name;
}
}
@WebService(serviceName = "SOAPService",
portName = "SoapPort",
endpointInterface = "org.apache.hello_world_soap_http.Greeter",
targetNamespace = "http://apache.org/hello_world_soap_http")
public static class NoWsdlGreeter extends BaseGreeterImpl {
}
@Override
protected int getPort() {
return EmbeddedJettyServer.PORT;
}
}