Permalink
Showing
with
331 additions
and 0 deletions.
- +169 −0 .../src/test/java/org/jboss/as/test/clustering/cluster/web/AbstractImmutableWebFailoverTestCase.java
- +74 −0 ...ng/src/test/java/org/jboss/as/test/clustering/cluster/web/CoarseImmutableWebFailoverTestCase.java
- +74 −0 ...ring/src/test/java/org/jboss/as/test/clustering/cluster/web/FineImmutableWebFailoverTestCase.java
- +7 −0 ...ing/src/test/java/org/jboss/as/test/clustering/cluster/web/distributable-web_immutable_coarse.xml
- +7 −0 ...ering/src/test/java/org/jboss/as/test/clustering/cluster/web/distributable-web_immutable_fine.xml
| @@ -0,0 +1,169 @@ | ||
| /* | ||
| * JBoss, Home of Professional Open Source. | ||
| * Copyright 2011, Red Hat, Inc., and individual contributors | ||
| * as indicated by the @author tags. See the copyright.txt file in the | ||
| * distribution for a full listing of individual contributors. | ||
| * | ||
| * This is free software; you can redistribute it and/or modify it | ||
| * under the terms of the GNU Lesser General Public License as | ||
| * published by the Free Software Foundation; either version 2.1 of | ||
| * the License, or (at your option) any later version. | ||
| * | ||
| * This software is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| * Lesser General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU Lesser General Public | ||
| * License along with this software; if not, write to the Free | ||
| * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| * 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
| */ | ||
| package org.jboss.as.test.clustering.cluster.web; | ||
|
|
||
| import java.io.IOException; | ||
| import java.net.URI; | ||
| import java.net.URISyntaxException; | ||
| import java.net.URL; | ||
| import java.util.Map; | ||
|
|
||
| import javax.servlet.http.HttpServletResponse; | ||
|
|
||
| import org.apache.http.HttpResponse; | ||
| import org.apache.http.client.methods.HttpGet; | ||
| import org.apache.http.client.utils.HttpClientUtils; | ||
| import org.apache.http.impl.client.CloseableHttpClient; | ||
| import org.jboss.arquillian.container.test.api.OperateOnDeployment; | ||
| import org.jboss.arquillian.junit.Arquillian; | ||
| import org.jboss.arquillian.test.api.ArquillianResource; | ||
| import org.jboss.as.test.clustering.ClusterHttpClientUtil; | ||
| import org.jboss.as.test.clustering.cluster.AbstractClusteringTestCase; | ||
| import org.jboss.as.test.clustering.single.web.SimpleServlet; | ||
| import org.jboss.as.test.http.util.TestHttpClientUtils; | ||
| import org.junit.Assert; | ||
| import org.junit.Test; | ||
| import org.junit.runner.RunWith; | ||
|
|
||
| /** | ||
| * Validates behavior of immutable session attributes. | ||
| * | ||
| * @author Paul Ferraro | ||
| */ | ||
| @RunWith(Arquillian.class) | ||
| public abstract class AbstractImmutableWebFailoverTestCase extends AbstractClusteringTestCase { | ||
|
|
||
| private final String deploymentName; | ||
|
|
||
| protected AbstractImmutableWebFailoverTestCase(String deploymentName) { | ||
| super(THREE_NODES); | ||
|
|
||
| this.deploymentName = deploymentName; | ||
| } | ||
|
|
||
| @Test | ||
| public void test( | ||
| @ArquillianResource(SimpleServlet.class) @OperateOnDeployment(DEPLOYMENT_1) URL baseURL1, | ||
| @ArquillianResource(SimpleServlet.class) @OperateOnDeployment(DEPLOYMENT_2) URL baseURL2, | ||
| @ArquillianResource(SimpleServlet.class) @OperateOnDeployment(DEPLOYMENT_3) URL baseURL3) throws Exception { | ||
| this.testGracefulUndeployFailover(baseURL1, baseURL2, baseURL3); | ||
| this.testGracefulSimpleFailover(baseURL1, baseURL2, baseURL3); | ||
| } | ||
|
|
||
| protected void testGracefulSimpleFailover(URL baseURL1, URL baseURL2, URL baseURL3) throws Exception { | ||
| this.testFailover(new RestartLifecycle(), baseURL1, baseURL2, baseURL3); | ||
| } | ||
|
|
||
| protected void testGracefulUndeployFailover(URL baseURL1, URL baseURL2, URL baseURL3) throws Exception { | ||
| this.testFailover(new RedeployLifecycle(), baseURL1, baseURL2, baseURL3); | ||
| } | ||
|
|
||
| private void testFailover(Lifecycle lifecycle, URL baseURL1, URL baseURL2, URL baseURL3) throws Exception { | ||
| URI uri1 = SimpleServlet.createURI(baseURL1); | ||
| URI uri2 = SimpleServlet.createURI(baseURL2); | ||
| URI uri3 = SimpleServlet.createURI(baseURL3); | ||
|
|
||
| this.establishTopology(baseURL1, THREE_NODES); | ||
|
|
||
| try (CloseableHttpClient client = TestHttpClientUtils.promiscuousCookieHttpClient()) { | ||
| HttpResponse response = client.execute(new HttpGet(uri1)); | ||
| try { | ||
| Assert.assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode()); | ||
| Assert.assertEquals(1, Integer.parseInt(response.getFirstHeader(SimpleServlet.VALUE_HEADER).getValue())); | ||
| Map.Entry<String, String> entry = parseSessionRoute(response); | ||
| Assert.assertNotNull(entry); | ||
| Assert.assertEquals(NODE_1, entry.getValue()); | ||
| Assert.assertEquals(entry.getKey(), response.getFirstHeader(SimpleServlet.SESSION_ID_HEADER).getValue()); | ||
| } finally { | ||
| HttpClientUtils.closeQuietly(response); | ||
| } | ||
|
|
||
| response = client.execute(new HttpGet(uri1)); | ||
| try { | ||
| Assert.assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode()); | ||
| Assert.assertEquals(2, Integer.parseInt(response.getFirstHeader(SimpleServlet.VALUE_HEADER).getValue())); | ||
| Map.Entry<String, String> entry = parseSessionRoute(response); | ||
| // Ensure routing is not changed on 2nd query | ||
| Assert.assertNull(entry); | ||
| } finally { | ||
| HttpClientUtils.closeQuietly(response); | ||
| } | ||
|
|
||
| response = client.execute(new HttpGet(uri2)); | ||
| try { | ||
| Assert.assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode()); | ||
| // Because session attribute is defined to be immutable, the previous updates should be lost | ||
| Assert.assertEquals(2, Integer.parseInt(response.getFirstHeader(SimpleServlet.VALUE_HEADER).getValue())); | ||
| Map.Entry<String, String> entry = parseSessionRoute(response); | ||
| Assert.assertNotNull(entry); | ||
| Assert.assertEquals(NODE_2, entry.getValue()); | ||
| Assert.assertEquals(entry.getKey(), response.getFirstHeader(SimpleServlet.SESSION_ID_HEADER).getValue()); | ||
| } finally { | ||
| HttpClientUtils.closeQuietly(response); | ||
| } | ||
|
|
||
| response = client.execute(new HttpGet(uri2)); | ||
| try { | ||
| Assert.assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode()); | ||
| Assert.assertEquals(3, Integer.parseInt(response.getFirstHeader(SimpleServlet.VALUE_HEADER).getValue())); | ||
| Map.Entry<String, String> entry = parseSessionRoute(response); | ||
| // Ensure routing is not changed on 2nd query | ||
| Assert.assertNull(entry); | ||
| } finally { | ||
| HttpClientUtils.closeQuietly(response); | ||
| } | ||
|
|
||
| response = client.execute(new HttpGet(uri3)); | ||
| try { | ||
| Assert.assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode()); | ||
| // Because session attribute is defined to be immutable, the previous updates should be lost | ||
| Assert.assertEquals(2, Integer.parseInt(response.getFirstHeader(SimpleServlet.VALUE_HEADER).getValue())); | ||
| Map.Entry<String, String> entry = parseSessionRoute(response); | ||
| Assert.assertNotNull(entry); | ||
| Assert.assertEquals(NODE_3, entry.getValue()); | ||
| Assert.assertEquals(entry.getKey(), response.getFirstHeader(SimpleServlet.SESSION_ID_HEADER).getValue()); | ||
| } finally { | ||
| HttpClientUtils.closeQuietly(response); | ||
| } | ||
|
|
||
| response = client.execute(new HttpGet(uri3)); | ||
| try { | ||
| Assert.assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode()); | ||
| Assert.assertEquals(3, Integer.parseInt(response.getFirstHeader(SimpleServlet.VALUE_HEADER).getValue())); | ||
| Map.Entry<String, String> entry = parseSessionRoute(response); | ||
| // Ensure routing is not changed on 2nd query | ||
| Assert.assertNull(entry); | ||
| } finally { | ||
| HttpClientUtils.closeQuietly(response); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private void establishTopology(URL baseURL, String... nodes) throws URISyntaxException, IOException, InterruptedException { | ||
| ClusterHttpClientUtil.establishTopology(baseURL, "web", this.deploymentName, nodes); | ||
|
|
||
| // TODO we should be able to speed this up by observing changes in the routing registry | ||
| // prevents failing assertions when topology information is expected, e.g.: | ||
| //java.lang.AssertionError: expected null, but was:<bpAmUlICzeXMtFiOJvTiOCASbXNivRdHTIlQC00c=node-2> | ||
| Thread.sleep(GRACE_TIME_TOPOLOGY_CHANGE); | ||
| } | ||
| } |
| @@ -0,0 +1,74 @@ | ||
| /* | ||
| * JBoss, Home of Professional Open Source. | ||
| * Copyright 2019, Red Hat, Inc., and individual contributors | ||
| * as indicated by the @author tags. See the copyright.txt file in the | ||
| * distribution for a full listing of individual contributors. | ||
| * | ||
| * This is free software; you can redistribute it and/or modify it | ||
| * under the terms of the GNU Lesser General Public License as | ||
| * published by the Free Software Foundation; either version 2.1 of | ||
| * the License, or (at your option) any later version. | ||
| * | ||
| * This software is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| * Lesser General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU Lesser General Public | ||
| * License along with this software; if not, write to the Free | ||
| * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| * 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
| */ | ||
|
|
||
| package org.jboss.as.test.clustering.cluster.web; | ||
|
|
||
| import org.jboss.arquillian.container.test.api.Deployment; | ||
| import org.jboss.arquillian.container.test.api.TargetsContainer; | ||
| import org.jboss.as.test.clustering.ClusterTestUtil; | ||
| import org.jboss.as.test.clustering.single.web.Mutable; | ||
| import org.jboss.as.test.clustering.single.web.SimpleServlet; | ||
| import org.jboss.shrinkwrap.api.Archive; | ||
| import org.jboss.shrinkwrap.api.ShrinkWrap; | ||
| import org.jboss.shrinkwrap.api.spec.WebArchive; | ||
|
|
||
| /** | ||
| * Validates behavior of immutable session attributes using SESSION granularity. | ||
| * @author Paul Ferraro | ||
| */ | ||
| public class CoarseImmutableWebFailoverTestCase extends AbstractImmutableWebFailoverTestCase { | ||
|
|
||
| private static final String MODULE_NAME = CoarseImmutableWebFailoverTestCase.class.getSimpleName(); | ||
| private static final String DEPLOYMENT_NAME = MODULE_NAME + ".war"; | ||
|
|
||
| public CoarseImmutableWebFailoverTestCase() { | ||
| super(DEPLOYMENT_NAME); | ||
| } | ||
|
|
||
| @Deployment(name = DEPLOYMENT_1, managed = false, testable = false) | ||
| @TargetsContainer(NODE_1) | ||
| public static Archive<?> deployment1() { | ||
| return getDeployment(); | ||
| } | ||
|
|
||
| @Deployment(name = DEPLOYMENT_2, managed = false, testable = false) | ||
| @TargetsContainer(NODE_2) | ||
| public static Archive<?> deployment2() { | ||
| return getDeployment(); | ||
| } | ||
|
|
||
| @Deployment(name = DEPLOYMENT_3, managed = false, testable = false) | ||
| @TargetsContainer(NODE_3) | ||
| public static Archive<?> deployment3() { | ||
| return getDeployment(); | ||
| } | ||
|
|
||
| private static Archive<?> getDeployment() { | ||
| WebArchive war = ShrinkWrap.create(WebArchive.class, DEPLOYMENT_NAME); | ||
| war.addClasses(SimpleServlet.class, Mutable.class); | ||
| ClusterTestUtil.addTopologyListenerDependencies(war); | ||
| // Take web.xml from the managed test. | ||
| war.setWebXML(CoarseImmutableWebFailoverTestCase.class.getPackage(), "web.xml"); | ||
| war.addAsWebInfResource(CoarseImmutableWebFailoverTestCase.class.getPackage(), "distributable-web_immutable_coarse.xml", "distributable-web.xml"); | ||
| return war; | ||
| } | ||
| } |
| @@ -0,0 +1,74 @@ | ||
| /* | ||
| * JBoss, Home of Professional Open Source. | ||
| * Copyright 2019, Red Hat, Inc., and individual contributors | ||
| * as indicated by the @author tags. See the copyright.txt file in the | ||
| * distribution for a full listing of individual contributors. | ||
| * | ||
| * This is free software; you can redistribute it and/or modify it | ||
| * under the terms of the GNU Lesser General Public License as | ||
| * published by the Free Software Foundation; either version 2.1 of | ||
| * the License, or (at your option) any later version. | ||
| * | ||
| * This software is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| * Lesser General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU Lesser General Public | ||
| * License along with this software; if not, write to the Free | ||
| * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| * 02110-1301 USA, or see the FSF site: http://www.fsf.org. | ||
| */ | ||
|
|
||
| package org.jboss.as.test.clustering.cluster.web; | ||
|
|
||
| import org.jboss.arquillian.container.test.api.Deployment; | ||
| import org.jboss.arquillian.container.test.api.TargetsContainer; | ||
| import org.jboss.as.test.clustering.ClusterTestUtil; | ||
| import org.jboss.as.test.clustering.single.web.Mutable; | ||
| import org.jboss.as.test.clustering.single.web.SimpleServlet; | ||
| import org.jboss.shrinkwrap.api.Archive; | ||
| import org.jboss.shrinkwrap.api.ShrinkWrap; | ||
| import org.jboss.shrinkwrap.api.spec.WebArchive; | ||
|
|
||
| /** | ||
| * Validates behavior of immutable session attributes using ATTRIBUTE granularity. | ||
| * @author Paul Ferraro | ||
| */ | ||
| public class FineImmutableWebFailoverTestCase extends AbstractImmutableWebFailoverTestCase { | ||
|
|
||
| private static final String MODULE_NAME = FineImmutableWebFailoverTestCase.class.getSimpleName(); | ||
| private static final String DEPLOYMENT_NAME = MODULE_NAME + ".war"; | ||
|
|
||
| public FineImmutableWebFailoverTestCase() { | ||
| super(DEPLOYMENT_NAME); | ||
| } | ||
|
|
||
| @Deployment(name = DEPLOYMENT_1, managed = false, testable = false) | ||
| @TargetsContainer(NODE_1) | ||
| public static Archive<?> deployment1() { | ||
| return getDeployment(); | ||
| } | ||
|
|
||
| @Deployment(name = DEPLOYMENT_2, managed = false, testable = false) | ||
| @TargetsContainer(NODE_2) | ||
| public static Archive<?> deployment2() { | ||
| return getDeployment(); | ||
| } | ||
|
|
||
| @Deployment(name = DEPLOYMENT_3, managed = false, testable = false) | ||
| @TargetsContainer(NODE_3) | ||
| public static Archive<?> deployment3() { | ||
| return getDeployment(); | ||
| } | ||
|
|
||
| private static Archive<?> getDeployment() { | ||
| WebArchive war = ShrinkWrap.create(WebArchive.class, DEPLOYMENT_NAME); | ||
| war.addClasses(SimpleServlet.class, Mutable.class); | ||
| ClusterTestUtil.addTopologyListenerDependencies(war); | ||
| // Take web.xml from the managed test. | ||
| war.setWebXML(FineImmutableWebFailoverTestCase.class.getPackage(), "web.xml"); | ||
| war.addAsWebInfResource(FineImmutableWebFailoverTestCase.class.getPackage(), "distributable-web_immutable_fine.xml", "distributable-web.xml"); | ||
| return war; | ||
| } | ||
| } |
| @@ -0,0 +1,7 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <distributable-web xmlns="urn:jboss:distributable-web:1.0"> | ||
| <infinispan-session-management cache-container="web" cache="sso" granularity="SESSION"> | ||
| <local-affinity/> | ||
| <immutable-class>org.jboss.as.test.clustering.single.web.Mutable</immutable-class> | ||
| </infinispan-session-management> | ||
| </distributable-web> |
| @@ -0,0 +1,7 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <distributable-web xmlns="urn:jboss:distributable-web:1.0"> | ||
| <infinispan-session-management cache-container="web" cache="sso" granularity="ATTRIBUTE"> | ||
| <local-affinity/> | ||
| <immutable-class>org.jboss.as.test.clustering.single.web.Mutable</immutable-class> | ||
| </infinispan-session-management> | ||
| </distributable-web> |