/** * 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; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.Socket; import java.net.URL; import java.net.URLConnection; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.xml.xpath.XPathConstants; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.apache.cxf.ext.logging.LoggingInInterceptor; import org.apache.cxf.helpers.DOMUtils; import org.apache.cxf.helpers.IOUtils; import org.apache.cxf.helpers.XPathUtils; import org.apache.cxf.jaxrs.client.WebClient; import org.apache.cxf.jaxrs.model.AbstractResourceInfo; import org.apache.cxf.jaxrs.model.wadl.WadlGenerator; import org.apache.cxf.jaxrs.provider.JAXBElementProvider; import org.apache.cxf.staxutils.StaxUtils; import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase; import org.apache.cxf.transport.http.HTTPConduit; import org.junit.BeforeClass; import org.junit.Test; public class JAXRSClientServerResourceCreatedSpringProviderTest extends AbstractBusClientServerTestBase { public static final String PORT = BookServerResourceCreatedSpringProviders.PORT; @BeforeClass public static void startServers() throws Exception { AbstractResourceInfo.clearAllMaps(); assertTrue("server did not launch correctly", launchServer(BookServerResourceCreatedSpringProviders.class, true)); createStaticBus(); } @Test public void testBasePetStoreWithoutTrailingSlash() throws Exception { String endpointAddress = "http://localhost:" + PORT + "/webapp/pets"; WebClient client = WebClient.create(endpointAddress); HTTPConduit conduit = WebClient.getConfig(client).getHttpConduit(); conduit.getClient().setReceiveTimeout(1000000); conduit.getClient().setConnectionTimeout(1000000); String value = client.accept("text/plain").get(String.class); assertEquals(PetStore.CLOSED, value); } @Test public void testBasePetStore() throws Exception { String endpointAddress = "http://localhost:" + PORT + "/webapp/pets/"; WebClient client = WebClient.create(endpointAddress); HTTPConduit conduit = WebClient.getConfig(client).getHttpConduit(); conduit.getClient().setReceiveTimeout(1000000); conduit.getClient().setConnectionTimeout(1000000); String value = client.accept("text/plain").get(String.class); assertEquals(PetStore.CLOSED, value); } @Test public void testMultipleRootsWadl() throws Exception { List<Element> resourceEls = getWadlResourcesInfo("http://localhost:" + PORT + "/webapp/resources", "http://localhost:" + PORT + "/webapp/resources", 2); String path1 = resourceEls.get(0).getAttribute("path"); int bookStoreInd = path1.contains("/bookstore") ? 0 : 1; int petStoreInd = bookStoreInd == 0 ? 1 : 0; checkBookStoreInfo(resourceEls.get(bookStoreInd)); checkServletInfo(resourceEls.get(petStoreInd)); } @Test public void testBookStoreWadl() throws Exception { List<Element> resourceEls = getWadlResourcesInfo("http://localhost:" + PORT + "/webapp/resources", "http://localhost:" + PORT + "/webapp/resources/bookstore", 1); checkBookStoreInfo(resourceEls.get(0)); } private void assertValidType(XPathUtils xpu, String xpath, String type, Element el) { String s = (String)xpu.getValue(xpath, el, XPathConstants.STRING); assertNotNull(s); assertTrue("Expected " + type + " but found " + s, s.endsWith(type)); } private void assertValid(XPathUtils xpu, String xpath, Element el) { assertNotNull(xpu.getValue(xpath, el, XPathConstants.NODE)); } @Test public void testPetStoreWadl() throws Exception { List<Element> resourceEls = getWadlResourcesInfo("http://localhost:" + PORT + "/webapp/pets", "http://localhost:" + PORT + "/webapp/pets/", 1); checkPetStoreInfo(resourceEls.get(0)); Element el = (Element)resourceEls.get(0).getParentNode().getParentNode(); Map<String, String> namespaces = new HashMap<>(); namespaces.put("xsd", "http://www.w3.org/2001/XMLSchema"); namespaces.put("ns", "http://pets"); namespaces.put("wadl", "http://wadl.dev.java.net/2009/02"); XPathUtils xpu = new XPathUtils(namespaces); assertValidType(xpu, "//xsd:element[@name='elstatus']/@type", "petStoreStatusElement", el); assertValidType(xpu, "//xsd:schema[@targetNamespace='http://pets']/xsd:element[@name='status']/@type", "status", el); assertValidType(xpu, "//xsd:element[@name='statusType']/@type", "statusType", el); assertValidType(xpu, "//xsd:element[@name='statusImpl1']/@type", "petStoreStatusImpl1", el); assertValidType(xpu, "//xsd:element[@name='statusImpl1']/@substitutionGroup", "statusType", el); assertValidType(xpu, "//xsd:element[@name='statusImpl2']/@type", "petStoreStatusImpl2", el); assertValidType(xpu, "//xsd:element[@name='statusImpl2']/@substitutionGroup", "statusType", el); assertValid(xpu, "//wadl:representation[@element='prefix1:status']", el); assertValid(xpu, "//wadl:representation[@element='prefix1:elstatus']", el); assertValid(xpu, "//wadl:representation[@element='prefix1:statuses']", el); assertValid(xpu, "//wadl:representation[@element='prefix1:statusType']", el); } @Test public void testWadlPublishedEndpointUrl() throws Exception { String requestURI = "http://localhost:" + PORT + "/webapp/resources2"; WebClient client = WebClient.create(requestURI + "?_wadl&_type=xml"); Document doc = StaxUtils.read(new InputStreamReader(client.get(InputStream.class), StandardCharsets.UTF_8)); Element root = doc.getDocumentElement(); assertEquals(WadlGenerator.WADL_NS, root.getNamespaceURI()); assertEquals("application", root.getLocalName()); List<Element> resourcesEls = DOMUtils.getChildrenWithName(root, WadlGenerator.WADL_NS, "resources"); assertEquals(1, resourcesEls.size()); Element resourcesEl = resourcesEls.get(0); assertEquals("http://proxy", resourcesEl.getAttribute("base")); } private void checkBookStoreInfo(Element resource) { assertEquals("/bookstore", resource.getAttribute("path")); } private void checkServletInfo(Element resource) { assertEquals("/servlet", resource.getAttribute("path")); } private void checkPetStoreInfo(Element resource) { assertEquals("/", resource.getAttribute("path")); } private List<Element> getWadlResourcesInfo(String baseURI, String requestURI, int size) throws Exception { WebClient client = WebClient.create(requestURI + "?_wadl&_type=xml"); WebClient.getConfig(client).getHttpConduit().getClient().setReceiveTimeout(10000000); Document doc = StaxUtils.read(new InputStreamReader(client.get(InputStream.class), StandardCharsets.UTF_8)); Element root = doc.getDocumentElement(); assertEquals(WadlGenerator.WADL_NS, root.getNamespaceURI()); assertEquals("application", root.getLocalName()); List<Element> resourcesEls = DOMUtils.getChildrenWithName(root, WadlGenerator.WADL_NS, "resources"); assertEquals(1, resourcesEls.size()); Element resourcesEl = resourcesEls.get(0); assertEquals(baseURI, resourcesEl.getAttribute("base")); List<Element> resourceEls = DOMUtils.getChildrenWithName(resourcesEl, WadlGenerator.WADL_NS, "resource"); assertEquals(size, resourceEls.size()); return resourceEls; } @Test public void testServletConfigInitParam() throws Exception { String endpointAddress = "http://localhost:" + PORT + "/webapp/resources/servlet/config/a"; WebClient wc = WebClient.create(endpointAddress); wc.accept("text/plain"); assertEquals("avalue", wc.get(String.class)); } @Test public void testGetBook123() throws Exception { String endpointAddress = "http://localhost:" + PORT + "/webapp/resources/bookstore/books/123"; URL url = new URL(endpointAddress); URLConnection connect = url.openConnection(); connect.addRequestProperty("Accept", "application/json"); connect.addRequestProperty("Content-Language", "badgerFishLanguage"); InputStream in = connect.getInputStream(); assertNotNull(in); //Ensure BadgerFish output as this should have replaced the standard JSONProvider InputStream expected = getClass() .getResourceAsStream("resources/expected_get_book123badgerfish.txt"); assertEquals("BadgerFish output not correct", stripXmlInstructionIfNeeded(getStringFromInputStream(expected).trim()), stripXmlInstructionIfNeeded(getStringFromInputStream(in).trim())); } private String stripXmlInstructionIfNeeded(String str) { if (str != null && str.startsWith("<?xml")) { int index = str.indexOf("?>"); str = str.substring(index + 2); } return str; } @Test public void testGetBookNotFound() throws Exception { String endpointAddress = "http://localhost:" + PORT + "/webapp/resources/bookstore/books/12345"; URL url = new URL(endpointAddress); HttpURLConnection connect = (HttpURLConnection)url.openConnection(); connect.addRequestProperty("Accept", "text/plain,application/xml"); assertEquals(500, connect.getResponseCode()); InputStream in = connect.getErrorStream(); assertNotNull(in); InputStream expected = getClass() .getResourceAsStream("resources/expected_get_book_notfound_mapped.txt"); assertEquals("Exception is not mapped correctly", stripXmlInstructionIfNeeded(getStringFromInputStream(expected).trim()), stripXmlInstructionIfNeeded(getStringFromInputStream(in).trim())); } @Test public void testGetBookNotExistent() throws Exception { String endpointAddress = "http://localhost:" + PORT + "/webapp/resources/bookstore/nonexistent"; URL url = new URL(endpointAddress); HttpURLConnection connect = (HttpURLConnection)url.openConnection(); connect.addRequestProperty("Accept", "application/xml"); assertEquals(405, connect.getResponseCode()); InputStream in = connect.getErrorStream(); assertNotNull(in); assertEquals("Exception is not mapped correctly", "StringTextWriter - Nonexistent method", getStringFromInputStream(in).trim()); } @Test public void testPostPetStatus() throws Exception { String endpointAddress = "http://localhost:" + PORT + "/webapp/pets/petstore/pets"; URL url = new URL(endpointAddress); HttpURLConnection httpUrlConnection = (HttpURLConnection)url.openConnection(); httpUrlConnection.setUseCaches(false); httpUrlConnection.setDefaultUseCaches(false); httpUrlConnection.setDoOutput(true); httpUrlConnection.setDoInput(true); httpUrlConnection.setRequestMethod("POST"); httpUrlConnection.setRequestProperty("Accept", "text/xml"); httpUrlConnection.setRequestProperty("Content-type", "application/x-www-form-urlencoded"); httpUrlConnection.setRequestProperty("Connection", "close"); OutputStream outputstream = httpUrlConnection.getOutputStream(); File inputFile = new File(getClass().getResource("resources/singleValPostBody.txt").toURI()); byte[] tmp = new byte[4096]; int i = 0; try (InputStream is = new FileInputStream(inputFile)) { while ((i = is.read(tmp)) >= 0) { outputstream.write(tmp, 0, i); } } outputstream.flush(); int responseCode = httpUrlConnection.getResponseCode(); assertEquals(200, responseCode); assertEquals("Wrong status returned", "open", getStringFromInputStream(httpUrlConnection .getInputStream())); httpUrlConnection.disconnect(); } @Test public void testPostPetStatus2() throws Exception { Socket s = new Socket("localhost", Integer.parseInt(PORT)); IOUtils.copyAndCloseInput(getClass().getResource("resources/formRequest.txt").openStream(), s.getOutputStream()); s.getOutputStream().flush(); try { assertTrue("Wrong status returned", getStringFromInputStream(s.getInputStream()) .contains("open")); } finally { s.close(); } } private String getStringFromInputStream(InputStream in) throws Exception { return IOUtils.toString(in); } @Test public void testPostPetStatusType() throws Exception { JAXBElementProvider<Object> p = new JAXBElementProvider<Object>(); p.setUnmarshallAsJaxbElement(true); WebClient wc = WebClient.create("http://localhost:" + PORT + "/webapp/pets/petstore/jaxb/statusType/", Collections.singletonList(p)); WebClient.getConfig(wc).getInInterceptors().add(new LoggingInInterceptor()); wc.accept("text/xml"); PetStore.PetStoreStatusType type = wc.get(PetStore.PetStoreStatusType.class); assertEquals(PetStore.CLOSED, type.getStatus()); } }