package org.jboss.resteasy.test.client; import org.apache.commons.io.IOUtils; import org.apache.http.HttpEntity; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.dmr.ModelNode; import org.jboss.resteasy.client.jaxrs.ResteasyClient; import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder; import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine; import org.jboss.resteasy.client.jaxrs.internal.ClientInvocation; import org.jboss.resteasy.test.client.resource.EntityBufferingInFileResource; import org.jboss.resteasy.util.HttpResponseCodes; import org.jboss.resteasy.utils.PermissionUtil; import org.jboss.resteasy.utils.TestUtil; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.BeforeClass; import org.junit.AfterClass; import org.junit.Ignore; import javax.ws.rs.client.Entity; import javax.ws.rs.core.Response; import java.io.FilePermission; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import java.nio.charset.StandardCharsets; import java.util.PropertyPermission; import org.jboss.logging.Logger; import org.junit.runner.RunWith; import org.wildfly.extras.creaper.core.online.OnlineManagementClient; import org.wildfly.extras.creaper.core.online.operations.Address; import org.wildfly.extras.creaper.core.online.operations.Operations; import org.wildfly.extras.creaper.core.online.operations.admin.Administration; /** * @tpSubChapter Resteasy-client * @tpChapter Integration tests * @tpSince RESTEasy 3.0.16 */ @RunWith(Arquillian.class) @RunAsClient public class EntityBufferingInFileTest extends ClientTestBase{ private static final Logger logger = Logger.getLogger(EntityBufferingInFileTest.class); private static final long MAX_POST_SIZE = 2147483647; private static ModelNode origMaxPostSizeValue; private static Address address = Address.subsystem("undertow").and("server", "default-server").and("http-listener", "default"); @BeforeClass public static void setMaxPostSize() throws Exception { OnlineManagementClient client = TestUtil.clientInit(); Administration admin = new Administration(client); Operations ops = new Operations(client); // get original 'max-post-size' value origMaxPostSizeValue = ops.readAttribute(address, "max-post-size").value(); // set 'max-post-size' - max size of the object send in the post request ops.writeAttribute(address, "max-post-size", MAX_POST_SIZE); // reload server admin.reload(); client.close(); } @AfterClass public static void resetToDefault() throws Exception { OnlineManagementClient client = TestUtil.clientInit(); Administration admin = new Administration(client); Operations ops = new Operations(client); // write original 'disallowed methods' value ops.writeAttribute(address, "max-post-size", origMaxPostSizeValue); // reload server admin.reload(); client.close(); } @Deployment public static Archive<?> deploy() { WebArchive war = TestUtil.prepareArchive(EntityBufferingInFileTest.class.getSimpleName()); war.addClass(EntityBufferingInFileTest.class); // DataSource provider creates tmp file in the filesystem war.addAsManifestResource(PermissionUtil.createPermissionsXmlAsset(new FilePermission("/tmp/-", "read")), "permissions.xml"); return TestUtil.finishContainerPrepare(war, null, EntityBufferingInFileResource.class); } /** * @tpTestDetails Custom ApacheHttpClient4Engine is created which defines maximum file size allowed in memory - 16 bytes * (defined by memoryUnit and threshold size in doTest() method). Client then sends POST request with String entity * of defined size (10 bytes), * @tpPassCrit Successful response is returned, the entity stream returned is same as original string * Response entity is type of ByteArrayEntity. * @tpSince RESTEasy 3.0.16 */ @Test public void testBytes1() throws Exception { doTest(ApacheHttpClient4Engine.MemoryUnit.BY, 16, 10, true); } /** * @tpTestDetails Custom ApacheHttpClient4Engine is created which defines maximum file size allowed in memory - 16 bytes * (defined by memoryUnit and threshold size in doTest() method). Client then sends POST request with String entity * of defined size (20 bytes) * @tpPassCrit Successful response is returned, the entity stream returned is same as original string * @tpSince RESTEasy 3.0.16 */ @Test public void testBytes2() throws Exception { doTest(ApacheHttpClient4Engine.MemoryUnit.BY, 16, 20, false); } /** * @tpTestDetails Custom ApacheHttpClient4Engine is created which defines maximum file size allowed in memory - 1 KB * (defined by memoryUnit and threshold size in doTest() method). Client then sends POST request with String entity * of defined size (500 bytes) * @tpPassCrit Successful response is returned, the entity stream returned is same as original string * @tpSince RESTEasy 3.0.16 */ @Test public void testKilobytes1() throws Exception { doTest(ApacheHttpClient4Engine.MemoryUnit.KB, 1, 500, true); } /** * @tpTestDetails Custom ApacheHttpClient4Engine is created which defines maximum file size allowed in memory - 1 KB * (defined by memoryUnit and threshold size in doTest() method). Client then sends POST request with String entity * of defined size (2000 bytes) * @tpPassCrit Successful response is returned, the entity stream returned is same as original string * @tpSince RESTEasy 3.0.16 */ @Test public void testKilobytes2() throws Exception { doTest(ApacheHttpClient4Engine.MemoryUnit.KB, 1, 2000, false); } /** * @tpTestDetails Custom ApacheHttpClient4Engine is created which defines maximum file size allowed in memory - 1 MB * (defined by memoryUnit and threshold size in doTest() method). Client then sends POST request with String entity * of defined size (500000 bytes) * @tpPassCrit Successful response is returned, the entity stream returned is same as original string * @tpSince RESTEasy 3.0.16 */ @Test public void testMegabytes1() throws Exception { doTest(ApacheHttpClient4Engine.MemoryUnit.MB, 1, 500000, true); } /** * @tpTestDetails Custom ApacheHttpClient4Engine is created which defines maximum file size allowed in memory - 1 GB * (defined by memoryUnit and threshold size in doTest() method). Client then sends POST request with String entity * of defined size (2000000000 bytes) * @tpPassCrit Successful response is returned, the entity stream returned is same as original string * @tpSince RESTEasy 3.0.16 */ @Test public void testMegabytes2() throws Exception { doTest(ApacheHttpClient4Engine.MemoryUnit.MB, 1, 2000000, false); } /** * @tpTestDetails Custom ApacheHttpClient4Engine is created which defines maximum file size allowed in memory - 1 GB * (defined by memoryUnit and threshold size in doTest() method). Client then sends POST request with String entity * of defined size (500000000 bytes) * @tpPassCrit Successful response is returned, the entity stream returned is same as original string * @tpSince RESTEasy 3.0.16 */ @Ignore("The tests fails on some machines on client side. As this is performance test and performance tests were dropped" + "from EAP7 rfe list, this is not priority now.") @Test public void testGigabytes1() throws Exception { doTest(ApacheHttpClient4Engine.MemoryUnit.GB, 1, 500000000, true); } protected void doTest(ApacheHttpClient4Engine.MemoryUnit memoryUnit, int threshold, int length, boolean inMemory) throws Exception { try { TestClientExecutor executor = new TestClientExecutor(); executor.setFileUploadMemoryUnit(memoryUnit); executor.setFileUploadInMemoryThresholdLimit(threshold); StringBuffer sb = new StringBuffer(); for (int i = 0; i < length; i++) { sb.append("0"); } String body = sb.toString(); ResteasyClient client = new ResteasyClientBuilder().httpEngine(executor).build(); Response response = client.target(generateURL("/hello")).request().header("content-type", "text/plain; charset=UTF-8").post(Entity.text(body)); logger.info("Received response"); Assert.assertEquals(HttpResponseCodes.SC_OK, response.getStatus()); InputStream in = response.readEntity(InputStream.class); StringWriter writer = new StringWriter(); IOUtils.copy(in, writer, StandardCharsets.UTF_8); String responseString = writer.toString(); Assert.assertEquals(body, responseString); response.close(); } catch (OutOfMemoryError e) { logger.info("OutOfMemoryError on " + memoryUnit + " test."); } } static class TestClientExecutor extends ApacheHttpClient4Engine { private HttpEntity entityToBuild; protected HttpEntity buildEntity(final ClientInvocation request) throws IOException { entityToBuild = super.buildEntity(request); return entityToBuild; } public HttpEntity getBuildEntity() { return entityToBuild; } } }