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);
}
}