@Override public void stop() throws ServletException { ThreadSetupAction.Handle handle = deployment.getThreadSetupAction().setup(null); try { try { for (Lifecycle object : deployment.getLifecycleObjects()) { object.stop(); } } finally { if (executor != null) { executor.release(); } if (asyncExecutor != null) { asyncExecutor.release(); } executor = null; asyncExecutor = null; } } finally { handle.tearDown(); if (executor != null) { executor.release(); } if (asyncExecutor != null) { asyncExecutor.release(); } executor = null; asyncExecutor = null; } deployment.getDeploymentInfo().getSessionManager().stop(); state = State.DEPLOYED; }
/** Launch process and waits until it's down */ public void launch(Monitored mp) { if (!lifecycle.tryToMoveTo(Lifecycle.State.STARTING)) { throw new IllegalStateException("Already started"); } monitored = mp; try { LoggerFactory.getLogger(getClass()).info("Starting " + getKey()); Runtime.getRuntime().addShutdownHook(shutdownHook); stopWatcher.start(); monitored.start(); boolean ready = false; while (!ready) { ready = monitored.isReady(); Thread.sleep(20L); } // notify monitor that process is ready commands.setReady(); if (lifecycle.tryToMoveTo(Lifecycle.State.STARTED)) { monitored.awaitStop(); } } catch (Exception e) { LoggerFactory.getLogger(getClass()).warn("Fail to start " + getKey(), e); } finally { stop(); } }
@Override public void start() throws Exception { this.lifecycles = loadLifecycles(); for (Lifecycle lifecycle : this.lifecycles) { lifecycle.start(); } super.start(); }
/** * Set the Valve instance that has been distinguished as the basic Valve for this Pipeline (if * any). Prior to setting the basic Valve, the Valve's <code>setContainer()</code> will be called, * if it implements <code>Contained</code>, with the owning Container as an argument. The method * may throw an <code>IllegalArgumentException</code> if this Valve chooses not to be associated * with this Container, or <code>IllegalStateException</code> if it is already associated with a * different Container. * * @param valve Valve to be distinguished as the basic Valve */ public void setBasic(GlassFishValve valve) { // Change components if necessary GlassFishValve oldBasic = null; synchronized (this) { oldBasic = this.basic; } if (oldBasic == valve) { return; } // Stop the old component if necessary if (oldBasic != null) { synchronized (this) { if (started && (oldBasic instanceof Lifecycle)) { try { ((Lifecycle) oldBasic).stop(); } catch (LifecycleException e) { log.log(Level.SEVERE, SET_BASIC_STOP_EXCEPTION, e); } } } if (oldBasic instanceof Contained) { try { ((Contained) oldBasic).setContainer(null); } catch (Throwable t) { // Ignore } } } // Start the new component if necessary if (valve == null) { return; } if (valve instanceof Contained) { ((Contained) valve).setContainer(this.container); } /** CR 6411114 if (valve instanceof Lifecycle) { */ // START CR 6411114 // Start the valve if the pipeline has already been started if (started && (valve instanceof Lifecycle)) { // END CR 6411114 try { ((Lifecycle) valve).start(); } catch (LifecycleException e) { log.log(Level.SEVERE, SET_BASIC_START_EXCEPTION, e); return; } } synchronized (this) { this.basic = valve; } }
@Override public void stop() throws Exception { for (Lifecycle lifecycle : reverseLifecycles()) { try { lifecycle.stop(); } catch (Throwable t) { LOG.error("Failed to stop Lifecycle: " + lifecycle.getClass().getName(), t); } } super.stop(); }
/** * Remove the specified Valve from the pipeline associated with this Container, if it is found; * otherwise, do nothing. If the Valve is found and removed, the Valve's <code>setContainer(null) * </code> method will be called if it implements <code>Contained</code>. * * @param valve Valve to be removed */ public void removeValve(GlassFishValve valve) { // Locate this Valve in our list int j = -1; for (int i = 0; i < valves.length; i++) { if (valve == valves[i]) { j = i; break; } } if (j < 0) return; // Remove this valve from our list GlassFishValve results[] = new GlassFishValve[valves.length - 1]; int n = 0; for (int i = 0; i < valves.length; i++) { if (i == j) continue; results[n++] = valves[i]; } valves = results; try { if (valve instanceof Contained) ((Contained) valve).setContainer(null); } catch (Throwable t) {; } // Stop this valve if necessary if (started) { if (valve instanceof ValveBase) { if (((ValveBase) valve).isStarted()) { try { ((Lifecycle) valve).stop(); } catch (LifecycleException e) { log.log(Level.SEVERE, REMOVE_VALVE_EXCEPTION, e); } } } else if (valve instanceof Lifecycle) { try { ((Lifecycle) valve).stop(); } catch (LifecycleException e) { log.log(Level.SEVERE, REMOVE_VALVE_EXCEPTION, e); } } /** * CR 6411114 (MBean deregistration moved to ValveBase.stop()) // Unregister the removed valve * unregisterValve(valve); */ } }
/** * Add a new Valve to the end of the pipeline associated with this Container. Prior to adding the * Valve, the Valve's <code>setContainer()</code> method will be called, if it implements <code> * Contained</code>, with the owning Container as an argument. The method may throw an <code> * IllegalArgumentException</code> if this Valve chooses not to be associated with this Container, * or <code>IllegalStateException</code> if it is already associated with a different Container. * * @param valve Valve to be added * @exception IllegalArgumentException if this Container refused to accept the specified Valve * @exception IllegalArgumentException if the specified Valve refuses to be associated with this * Container * @exception IllegalStateException if the specified Valve is already associated with a different * Container */ public void addValve(GlassFishValve valve) { if (firstTcValve != null) { // Wrap GlassFish-style valve inside Tomcat-style valve addValve(new TomcatValveAdapter(valve)); return; } // Validate that we can add this Valve if (valve instanceof Contained) ((Contained) valve).setContainer(this.container); // Start the new component if necessary if (started) { if (valve instanceof Lifecycle) { try { ((Lifecycle) valve).start(); } catch (LifecycleException e) { log.log(Level.SEVERE, ADD_VALVE_EXCEPTION, e); } } /** * CR 6411114 (MBean registration moved to ValveBase.start()) // Register the newly added * valve registerValve(valve); */ } // Add this Valve to the set associated with this Pipeline GlassFishValve results[] = new GlassFishValve[valves.length + 1]; System.arraycopy(valves, 0, results, 0, valves.length); results[valves.length] = valve; valves = results; }
/** * Gracefully shut down active use of the public methods of this Component. * * @exception IllegalStateException if this component has not been started * @exception LifecycleException if this component detects a fatal error that needs to be reported */ public synchronized void stop() throws LifecycleException { // Validate and update our current component state if (!started) throw new LifecycleException(rb.getString(PIPLINE_NOT_STARTED)); started = false; // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(STOP_EVENT, null); // Stop the Valves in our pipeline (including the basic), if any if ((basic != null) && (basic instanceof Lifecycle)) ((Lifecycle) basic).stop(); /** * CR 6411114 (MBean deregistration moved to ValveBase.stop()) if( basic!=null ) { * unregisterValve(basic); } */ for (int i = 0; i < valves.length; i++) { if (valves[i] instanceof Lifecycle) ((Lifecycle) valves[i]).stop(); /** CR 6411114 (MBean deregistration moved to ValveBase.stop()) unregisterValve(valves[i]); */ } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null); }
public void testPojoStyleBean() throws Exception { List expected = Arrays.asList(Lifecycle.values()); InitialContext ctx = new InitialContext(); { WidgetBean.lifecycle.clear(); Object object = ctx.lookup("WidgetBeanLocal"); assertTrue("instanceof widget", object instanceof Widget); Widget widget = (Widget) object; // Do a business method... Stack<Lifecycle> lifecycle = widget.getLifecycle(); assertNotNull("lifecycle", lifecycle); assertSame("lifecycle", lifecycle, WidgetBean.lifecycle); // Check the lifecycle of the bean assertEquals(join("\n", expected), join("\n", lifecycle)); } { WidgetBean.lifecycle.clear(); Object object = ctx.lookup("WidgetBeanLocalBean"); assertTrue("instanceof widget", object instanceof WidgetBean); WidgetBean widget = (WidgetBean) object; // Do a business method... Stack<Lifecycle> lifecycle = widget.getLifecycle(); assertNotNull("lifecycle", lifecycle); assertSame("lifecycle", lifecycle, WidgetBean.lifecycle); // Check the lifecycle of the bean assertEquals( Lifecycle.CONSTRUCTOR + "\n" + Lifecycle.BUSINESS_METHOD + "\n", join("\n", lifecycle)); } { WidgetBean.lifecycle.clear(); Object object = ctx.lookup("WidgetBeanRemote"); assertTrue("instanceof widget", object instanceof RemoteWidget); RemoteWidget remoteWidget = (RemoteWidget) object; // Do a business method... Stack<Lifecycle> lifecycle = remoteWidget.getLifecycle(); assertNotNull("lifecycle", lifecycle); assertNotSame("lifecycle", lifecycle, WidgetBean.lifecycle); // Check the lifecycle of the bean assertEquals(Lifecycle.BUSINESS_METHOD + "\n", join("\n", lifecycle)); } }
@Override public void stopAsync() { if (lifecycle.tryToMoveTo(Lifecycle.State.STOPPING)) { stopperThread = new StopperThread( monitored, commands, Long.parseLong(props.nonNullValue(PROPERTY_TERMINATION_TIMEOUT))); stopperThread.start(); stopWatcher.stopWatching(); } }
/** Blocks until stopped in a timely fashion (see {@link org.sonar.process.StopperThread}) */ void stop() { stopAsync(); try { // stopperThread is not null for sure // join() does nothing if thread already finished stopperThread.join(); lifecycle.tryToMoveTo(Lifecycle.State.STOPPED); } catch (InterruptedException e) { // nothing to do, the process is going to be exited } exit.exit(0); }
@Override public HttpHandler start() throws ServletException { ThreadSetupAction.Handle handle = deployment.getThreadSetupAction().setup(null); try { deployment.getDeploymentInfo().getSessionManager().start(); for (Lifecycle object : deployment.getLifecycleObjects()) { object.start(); } HttpHandler root = deployment.getServletHandler(); // create the executor, if it exists if (deployment.getDeploymentInfo().getExecutorFactory() != null) { try { executor = deployment.getDeploymentInfo().getExecutorFactory().createInstance(); root = new AttachmentHandler<>( HttpServerExchange.DISPATCH_EXECUTOR, root, executor.getInstance()); } catch (InstantiationException e) { throw new RuntimeException(e); } } if (deployment.getDeploymentInfo().getExecutorFactory() != null) { if (deployment.getDeploymentInfo().getAsyncExecutorFactory() != null) { try { asyncExecutor = deployment.getDeploymentInfo().getAsyncExecutorFactory().createInstance(); root = new AttachmentHandler<>( AsyncContextImpl.ASYNC_EXECUTOR, root, asyncExecutor.getInstance()); } catch (InstantiationException e) { throw new RuntimeException(e); } } } state = State.STARTED; return root; } finally { handle.tearDown(); } }
/** * Set the Valve instance that has been distinguished as the basic Valve for this Pipeline (if * any). Prioer to setting the basic Valve, the Valve's <code>setContainer()</code> will be * called, if it implements <code>Contained</code>, with the owning Container as an argument. The * method may throw an <code>IllegalArgumentException</code> if this Valve chooses not to be * associated with this Container, or <code>IllegalStateException</code> if it is already * associated with a different Container. * * @param valve Valve to be distinguished as the basic Valve */ public void setBasic(Valve valve) { // Change components if necessary Valve oldBasic = this.basic; if (oldBasic == valve) return; // Stop the old component if necessary if (oldBasic != null) { if (started && (oldBasic instanceof Lifecycle)) { try { ((Lifecycle) oldBasic).stop(); } catch (LifecycleException e) { log("StandardPipeline.setBasic: stop", e); } } if (oldBasic instanceof Contained) { try { ((Contained) oldBasic).setContainer(null); } catch (Throwable t) {; } } } // Start the new component if necessary if (valve == null) return; if (valve instanceof Contained) { ((Contained) valve).setContainer(this.container); } if (valve instanceof Lifecycle) { try { ((Lifecycle) valve).start(); } catch (LifecycleException e) { log("StandardPipeline.setBasic: start", e); return; } } this.basic = valve; }
/** Add Tomcat-style valve. */ public synchronized void addValve(Valve valve) { /* * Check if this is a GlassFish-style valve that was compiled * against the old org.apache.catalina.Valve interface (from * GlassFish releases prior to V3), which has since been renamed * to org.glassfish.web.valve.GlassFishValve (in V3) */ if (isGlassFishValve(valve)) { try { addValve(new GlassFishValveAdapter(valve)); } catch (Exception e) { String msg = MessageFormat.format(rb.getString(ADD_TOMCAT_STYLE_VALVE_EXCEPTION), valve); log.log(Level.SEVERE, msg, e); } return; } if (valve instanceof Contained) ((Contained) valve).setContainer(this.container); // Start the new Valve if necessary if (started) { if (valve instanceof Lifecycle) { try { ((Lifecycle) valve).start(); } catch (LifecycleException e) { log.log(Level.SEVERE, ADD_VALVE_EXCEPTION, e); } } } if (firstTcValve == null) { firstTcValve = lastTcValve = valve; } else { lastTcValve.setNext(valve); lastTcValve = valve; } if (basic != null) { valve.setNext((Valve) basic); } }
/** * Gracefully shut down active use of the public methods of this Component. * * @throws LifecycleException if this component detects a fatal error that needs to be reported */ public synchronized void stop() throws LifecycleException { // Validate and update our current component state if (!started) throw new LifecycleException(sm.getString("standardPipeline.notStarted")); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null); // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(STOP_EVENT, null); started = false; // Stop the Valves in our pipeline (including the basic), if any if ((basic != null) && (basic instanceof Lifecycle)) ((Lifecycle) basic).stop(); for (int i = 0; i < valves.length; i++) { if (valves[i] instanceof Lifecycle) ((Lifecycle) valves[i]).stop(); } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null); }
/** * Add a new Valve to the end of the pipeline associated with this Container. Prior to adding the * Valve, the Valve's <code>setContainer()</code> method will be called, if it implements <code> * Contained</code>, with the owning Container as an argument. The method may throw an <code> * IllegalArgumentException</code> if this Valve chooses not to be associated with this Container, * or <code>IllegalStateException</code> if it is already associated with a different Container. * * @param valve Valve to be added * @throws IllegalArgumentException if this Container refused to accept the specified Valve * @throws IllegalArgumentException if the specifie Valve refuses to be associated with this * Container * @throws IllegalStateException if the specified Valve is already associated with a different * Container */ public void addValve(Valve valve) { // Validate that we can add this Valve if (valve instanceof Contained) ((Contained) valve).setContainer(this.container); // Start the new component if necessary if (started && (valve instanceof Lifecycle)) { try { ((Lifecycle) valve).start(); } catch (LifecycleException e) { log("StandardPipeline.addValve: start: ", e); } } // Add this Valve to the set associated with this Pipeline synchronized (valves) { Valve results[] = new Valve[valves.length + 1]; System.arraycopy(valves, 0, results, 0, valves.length); results[valves.length] = valve; valves = results; } }
/** * Remove the specified Valve from the pipeline associated with this Container, if it is found; * otherwise, do nothing. If the Valve is found and removed, the Valve's <code>setContainer(null) * </code> method will be called if it implements <code>Contained</code>. * * @param valve Valve to be removed */ public void removeValve(Valve valve) { synchronized (valves) { // Locate this Valve in our list int j = -1; for (int i = 0; i < valves.length; i++) { if (valve == valves[i]) { j = i; break; } } if (j < 0) return; // Remove this valve from our list Valve results[] = new Valve[valves.length - 1]; int n = 0; for (int i = 0; i < valves.length; i++) { if (i == j) continue; results[n++] = valves[i]; } valves = results; try { if (valve instanceof Contained) ((Contained) valve).setContainer(null); } catch (Throwable t) {; } } // Stop this valve if necessary if (started && (valve instanceof Lifecycle)) { try { ((Lifecycle) valve).stop(); } catch (LifecycleException e) { log("StandardPipeline.removeValve: stop: ", e); } } }
Lifecycle.State getState() { return lifecycle.getState(); }
boolean isStarted() { return lifecycle.getState() == Lifecycle.State.STARTED; }
public static void main(String[] args) { System.setProperty("catalina.base", System.getProperty("user.dir")); Connector connector = new HttpConnector(); Wrapper wrapper1 = new StandardWrapper(); wrapper1.setName("Primitive"); wrapper1.setServletClass("PrimitiveServlet"); Wrapper wrapper2 = new StandardWrapper(); wrapper2.setName("Modern"); wrapper2.setServletClass("ModernServlet"); Context context = new StandardContext(); // StandardContext's start method adds a default mapper context.setPath("/app1"); context.setDocBase("app1"); context.addChild(wrapper1); context.addChild(wrapper2); LifecycleListener listener = new SimpleContextConfig(); ((Lifecycle) context).addLifecycleListener(listener); Host host = new StandardHost(); host.addChild(context); host.setName("localhost"); host.setAppBase("webapps"); Loader loader = new WebappLoader(); context.setLoader(loader); // context.addServletMapping(pattern, name); context.addServletMapping("/Primitive", "Primitive"); context.addServletMapping("/Modern", "Modern"); Engine engine = new StandardEngine(); engine.addChild(host); engine.setDefaultHost("localhost"); Service service = new StandardService(); service.setName("Stand-alone Service"); Server server = new StandardServer(); server.addService(service); service.addConnector(connector); // StandardService class's setContainer will call all its connector's setContainer method service.setContainer(engine); // Start the new server if (server instanceof Lifecycle) { try { server.initialize(); ((Lifecycle) server).start(); server.await(); // the program waits until the await method returns, // i.e. until a shutdown command is received. } catch (LifecycleException e) { e.printStackTrace(System.out); } } // Shut down the server if (server instanceof Lifecycle) { try { ((Lifecycle) server).stop(); } catch (LifecycleException e) { e.printStackTrace(System.out); } } }
private void testFailover(Lifecycle lifecycle, URL baseURL1, URL baseURL2) throws Exception { HttpClient client = TestHttpClientUtils.promiscuousCookieHttpClient(); URI uri1 = SimpleServlet.createURI(baseURL1); URI uri2 = SimpleServlet.createURI(baseURL2); this.establishTopology(baseURL1, NODES); try { 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.assertEquals(NODE_1, entry.getValue()); Assert.assertEquals( entry.getKey(), response.getFirstHeader(SimpleServlet.SESSION_ID_HEADER).getValue()); } finally { HttpClientUtils.closeQuietly(response); } // Let's do this twice to have more debug info if failover is slow. 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); if (entry != null) { Assert.assertEquals(NODE_1, entry.getValue()); Assert.assertEquals( entry.getKey(), response.getFirstHeader(SimpleServlet.SESSION_ID_HEADER).getValue()); } } finally { HttpClientUtils.closeQuietly(response); } // Gracefully undeploy from/shutdown the 1st container. lifecycle.stop(NODE_1); this.establishTopology(baseURL2, NODE_2); // Now check on the 2nd server response = client.execute(new HttpGet(uri2)); try { Assert.assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertEquals( "Session failed to replicate after container 1 was shutdown.", 3, Integer.parseInt(response.getFirstHeader(SimpleServlet.VALUE_HEADER).getValue())); Map.Entry<String, String> entry = parseSessionRoute(response); Assert.assertEquals(NODE_2, entry.getValue()); Assert.assertEquals( entry.getKey(), response.getFirstHeader(SimpleServlet.SESSION_ID_HEADER).getValue()); } finally { HttpClientUtils.closeQuietly(response); } // Let's do one more check. response = client.execute(new HttpGet(uri2)); try { Assert.assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertEquals( 4, Integer.parseInt(response.getFirstHeader(SimpleServlet.VALUE_HEADER).getValue())); Map.Entry<String, String> entry = parseSessionRoute(response); if (entry != null) { Assert.assertEquals(NODE_2, entry.getValue()); Assert.assertEquals( entry.getKey(), response.getFirstHeader(SimpleServlet.SESSION_ID_HEADER).getValue()); } } finally { HttpClientUtils.closeQuietly(response); } lifecycle.start(NODE_1); this.establishTopology(baseURL2, NODES); response = client.execute(new HttpGet(uri2)); try { Assert.assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertEquals( "Session failed to replicate after container 1 was brough up.", 5, Integer.parseInt(response.getFirstHeader(SimpleServlet.VALUE_HEADER).getValue())); Map.Entry<String, String> entry = parseSessionRoute(response); if (entry != null) { Assert.assertEquals(NODE_1, entry.getValue()); Assert.assertEquals( entry.getKey(), response.getFirstHeader(SimpleServlet.SESSION_ID_HEADER).getValue()); } } finally { HttpClientUtils.closeQuietly(response); } // The previous and next requests intentially hit the non-owning node this.nonOwnerTask.run(); // Let's do this twice to have more debug info if failover is slow. response = client.execute(new HttpGet(uri2)); try { Assert.assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertEquals( 6, Integer.parseInt(response.getFirstHeader(SimpleServlet.VALUE_HEADER).getValue())); Map.Entry<String, String> entry = parseSessionRoute(response); if (entry != null) { Assert.assertEquals(NODE_1, entry.getValue()); Assert.assertEquals( entry.getKey(), response.getFirstHeader(SimpleServlet.SESSION_ID_HEADER).getValue()); } } finally { HttpClientUtils.closeQuietly(response); } // Until graceful undeploy is supported, we need to wait for replication to complete before // undeploy (WFLY-6769). if (lifecycle instanceof RedeployLifecycle) { Thread.sleep(GRACE_TIME_TO_REPLICATE); } // Gracefully undeploy from/shutdown the 1st container. lifecycle.stop(NODE_2); this.establishTopology(baseURL1, NODE_1); // Now check on the 2nd server response = client.execute(new HttpGet(uri1)); try { Assert.assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertEquals( "Session failed to replicate after container 1 was shutdown.", 7, Integer.parseInt(response.getFirstHeader(SimpleServlet.VALUE_HEADER).getValue())); Map.Entry<String, String> entry = parseSessionRoute(response); if (entry != null) { Assert.assertEquals(NODE_1, entry.getValue()); Assert.assertEquals( entry.getKey(), response.getFirstHeader(SimpleServlet.SESSION_ID_HEADER).getValue()); } } finally { HttpClientUtils.closeQuietly(response); } // Let's do one more check. response = client.execute(new HttpGet(uri1)); try { Assert.assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertEquals( 8, Integer.parseInt(response.getFirstHeader(SimpleServlet.VALUE_HEADER).getValue())); Map.Entry<String, String> entry = parseSessionRoute(response); if (entry != null) { Assert.assertEquals(NODE_1, entry.getValue()); Assert.assertEquals( entry.getKey(), response.getFirstHeader(SimpleServlet.SESSION_ID_HEADER).getValue()); } } finally { HttpClientUtils.closeQuietly(response); } lifecycle.start(NODE_2); this.establishTopology(baseURL1, NODES); response = client.execute(new HttpGet(uri1)); try { Assert.assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertEquals( "Session failed to replicate after container 1 was brought up.", 9, Integer.parseInt(response.getFirstHeader(SimpleServlet.VALUE_HEADER).getValue())); Map.Entry<String, String> entry = parseSessionRoute(response); if (entry != null) { Assert.assertEquals(NODE_2, entry.getValue()); Assert.assertEquals( entry.getKey(), response.getFirstHeader(SimpleServlet.SESSION_ID_HEADER).getValue()); } } finally { HttpClientUtils.closeQuietly(response); } // Let's do this twice to have more debug info if failover is slow. response = client.execute(new HttpGet(uri1)); try { Assert.assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode()); Assert.assertEquals( 10, Integer.parseInt(response.getFirstHeader(SimpleServlet.VALUE_HEADER).getValue())); Map.Entry<String, String> entry = parseSessionRoute(response); if (entry != null) { Assert.assertEquals(NODE_2, entry.getValue()); Assert.assertEquals( entry.getKey(), response.getFirstHeader(SimpleServlet.SESSION_ID_HEADER).getValue()); } } finally { HttpClientUtils.closeQuietly(response); } } finally { HttpClientUtils.closeQuietly(client); } }