package org.jboss.resteasy.test.spring.inmodule; import static org.junit.Assert.*; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.HttpException; import org.apache.http.client.methods.HttpGet; import org.apache.http.HttpStatus; import org.apache.http.util.EntityUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.OperateOnDeployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.resteasy.plugins.spring.SpringContextLoaderListener; import org.jboss.resteasy.utils.PortProviderUtil; import org.jboss.resteasy.utils.TestUtil; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.exporter.ZipExporter; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.context.ApplicationContext; import org.jboss.resteasy.test.spring.inmodule.resource.TestResource; /** * @tpSubChapter Spring * @tpChapter Integration tests * @tpTestCaseDetails Tests adding spring as resource root with dependency for server module * @tpSince RESTEasy 3.0.16 */ @RunWith(Arquillian.class) @RunAsClient public class AddSpringResteasyAsResourceRootInModuleTest { private CloseableHttpClient client; private String deploymentName; private static String deploymentWithoutSpringMvcDispatcherOrListenerSpringInModule = "deploymentWithoutSpringMvcDispatcherOrListenerSpringInModule"; private static String deploymentWithSpringContextLoaderListenerSpringInModule = "deploymentWithSpringContextLoaderListenerSpringInModule"; private static String deploymentWithSpringMvcDispatcherSpringInModule = "deploymentWithSpringMvcDispatcherSpringInModule"; @Before public void before() throws Exception { client = HttpClients.createDefault(); } /** * @tpTestDetails Add dependency to spring libraries. Spring libraries are available as server module. * Deployment is configured with SpringMVC Dispatcher Servlet. * @tpPassCrit The application is successfully deployed, resource is available, and Spring classes are on the path. * @tpSince RESTEasy 3.0.16 */ @Test @OperateOnDeployment("dep3") public void testDeploymentWithSpringMvcDispatcherAddsResourceRoot() throws Exception { deploymentName = deploymentWithSpringMvcDispatcherSpringInModule; assertResponse(deploymentName); assertTrue("Spring classes are not available in deployment", springClassesAreAvailableToDeployment(deploymentName)); assertTrue("Resteasy Spring classes are not available in deployment", resteasySpringClassesAreAvailableToDeployment(deploymentName)); } @Deployment(name = "dep3") private static WebArchive createDeploymentWithSpringMvcDispatcher() { WebArchive archive = ShrinkWrap.create(WebArchive.class, deploymentWithSpringMvcDispatcherSpringInModule + ".war") .addClass(TestResource.class) .addAsWebInfResource(AddSpringResteasyAsResourceRootInModuleTest.class.getPackage(), "mvc-dispatcher-servlet/web.xml", "web.xml") .addAsWebInfResource(AddSpringResteasyAsResourceRootInModuleTest.class.getPackage(), "mvc-dispatcher-servlet/mvc-dispatcher-servlet.xml", "mvc-dispatcher-servlet.xml") .addAsWebInfResource(AddSpringResteasyAsResourceRootInModuleTest.class.getPackage(), "mvc-dispatcher-servlet/applicationContext.xml", "applicationContext.xml"); addSpringLibraries(archive); archive.as(ZipExporter.class).exportTo(new File("target", deploymentWithSpringMvcDispatcherSpringInModule + ".war"), true); return archive; } /** * @tpTestDetails Add dependency to spring libraries. Spring libraries are available as server module. * Deployment is configured with Spring context loader listener. * @tpPassCrit The application is successfully deployed, resource is available, and Spring classes are on the path. * @tpSince RESTEasy 3.0.16 */ @Test @OperateOnDeployment("dep2") public void testDeploymentWithSpringContextLoaderListenerAddsResourceRoot() throws Exception { deploymentName = deploymentWithSpringContextLoaderListenerSpringInModule; assertResponse(deploymentName); assertTrue("Spring classes are not available in deployment", springClassesAreAvailableToDeployment(deploymentName)); assertTrue("Resteasy Spring classes are not available in deployment", resteasySpringClassesAreAvailableToDeployment(deploymentName)); } @Deployment(name = "dep2") private static Archive<?> createDeploymentWithSpringContextLoaderListener() { WebArchive archive = ShrinkWrap.create(WebArchive.class, deploymentWithSpringContextLoaderListenerSpringInModule + ".war") .addClass(TestResource.class) .addAsWebInfResource(AddSpringResteasyAsResourceRootInModuleTest.class.getPackage(), "web.xml", "web.xml") .addAsWebInfResource(AddSpringResteasyAsResourceRootInModuleTest.class.getPackage(), "applicationContext.xml", "applicationContext.xml"); addSpringLibraries(archive); archive.as(ZipExporter.class).exportTo(new File("target", deploymentWithSpringContextLoaderListenerSpringInModule + ".war"), true); return archive; } /** * @tpTestDetails Add dependency to spring libraries. Spring libraries are available as server module. * Deployment is configured without Spring context loader listener or MVC dispatcher. * @tpPassCrit The application is successfully deployed, resource is available, and Spring classes are on the path. * @tpSince RESTEasy 3.0.16 */ @Test @OperateOnDeployment("dep1") public void testDeploymentWithoutSpringMvcDispatcherOrListenerDoesNotAddResourceRoot() throws Exception { deploymentName = deploymentWithoutSpringMvcDispatcherOrListenerSpringInModule; assertResponse(deploymentName); assertTrue("Spring classes are not available in deployment", springClassesAreAvailableToDeployment(deploymentName)); assertFalse("Resteasy Spring classes are available in deployment, which is not expected", resteasySpringClassesAreAvailableToDeployment(deploymentName)); } @Deployment(name = "dep1") private static Archive<?> createDeploymentWithoutSpringMvcDispatcherOrListener() { WebArchive archive = TestUtil.prepareArchive(deploymentWithoutSpringMvcDispatcherOrListenerSpringInModule); archive.addAsWebInfResource(AddSpringResteasyAsResourceRootInModuleTest.class.getPackage(), "web-no-mvc-no-listener.xml", "web.xml") .addAsWebInfResource(AddSpringResteasyAsResourceRootInModuleTest.class.getPackage(), "applicationContext.xml", "applicationContext.xml"); addSpringLibraries(archive); archive.as(ZipExporter.class).exportTo(new File("target", deploymentWithoutSpringMvcDispatcherOrListenerSpringInModule + ".war"), true); return TestUtil.finishContainerPrepare(archive, null, TestResource.class); } private boolean resteasySpringClassesAreAvailableToDeployment(String deploymentName) throws IOException, HttpException { return isClassAvailableToDeployment(deploymentName, SpringContextLoaderListener.class); } private boolean isClassAvailableToDeployment(String deploymentName, Class<?> clazz) throws IOException, HttpException { String className = clazz.getName(); String CONTEXT_URL = PortProviderUtil.generateURL("/", deploymentName); HttpGet httpget = new HttpGet(CONTEXT_URL + TestResource.LOAD_CLASS_PATH + "?" + TestResource.CLASSNAME_PARAM + "=" + className); try { String responseString = new String(); HttpClientContext context = HttpClientContext.create(); CloseableHttpResponse response = client.execute(httpget, context); HttpEntity entity = response.getEntity(); if (entity != null) { responseString = EntityUtils.toString(entity, StandardCharsets.UTF_8); } return (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) && (className.equals(responseString)); } finally { httpget.releaseConnection(); } } private boolean springClassesAreAvailableToDeployment(String deploymentName) throws IOException, HttpException { return isClassAvailableToDeployment(deploymentName, ApplicationContext.class); } private void assertResponse(String deploymentName) throws IOException, HttpException { String CONTEXT_URL = PortProviderUtil.generateURL("/", deploymentName); HttpGet httpget = new HttpGet(CONTEXT_URL + TestResource.TEST_PATH); HttpClientContext context = HttpClientContext.create(); CloseableHttpResponse response = client.execute(httpget, context); assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode()); HttpEntity entity = response.getEntity(); String responseString = EntityUtils.toString(entity, StandardCharsets.UTF_8); assertEquals("The server resource didn't send correct response", TestResource.TEST_RESPONSE, responseString); httpget.releaseConnection(); } private static void addSpringLibraries(WebArchive archive) { // you need to use the 'meta-inf' attribute to import the contents of meta-inf so spring can find the correct namespace handlers if (isDefinedSystemProperty("use-jboss-deployment-structure")) { archive.addAsManifestResource("jboss-deployment-structure.xml"); } else { archive.addAsManifestResource(new StringAsset("Dependencies: org.springframework.spring meta-inf\n"), "MANIFEST.MF"); } } private static boolean isDefinedSystemProperty(String name) { String value = System.getProperty(name); return (value != null); } }