/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt 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.test.cluster.test;

import java.util.Set;

import javax.management.ObjectName;

import junit.framework.Test;

import org.apache.commons.httpclient.HttpClient;
import org.jboss.cache.Fqn;
import org.jboss.jmx.adaptor.rmi.RMIAdaptor;
import org.jboss.test.JBossClusteredTestCase;

/**
 * Tests the use of the TreeCache.activateRegion()/inactivateRegion().
 * 
 * TODO add a concurrency test.
 * 
 * @author <a href="mailto://brian.stansberry@jboss.com">Brian Stansberry</a>
 * @version $Revision$
 */
public class StateTransferTestCase extends BaseTest
{

   private static final Object[] NULL_ARGS = new Object[] {};
   private static final String[] NULL_TYPES = new String[] {};
   
   protected String setUrl_;
   protected String getUrl_;
   protected String setUrlBase_;
   protected String getUrlBase_;
   
   private ObjectName warObjectName;
   private ObjectName cacheObjectName;
   private RMIAdaptor adaptor0_;
   private RMIAdaptor adaptor1_;
   private String warFqn_;
   
   /**
    * Create a new StateTransferTestCase.
    * 
    * @param name
    */
   public StateTransferTestCase(String name)
   {
      super(name);
      setUrlBase_ = "setSession.jsp";
      getUrlBase_ = "getAttribute.jsp";
      concatenate();
   }

   protected void concatenate()
   {
      String contextPath = "/" + getWarName() + "/";
      setUrl_ = contextPath +setUrlBase_;
      getUrl_ = contextPath +getUrlBase_;
   }

   public static Test suite() throws Exception
   {
      Test t1 = JBossClusteredTestCase.getDeploySetup(StateTransferTestCase.class,
            "http-scoped.war");
      return t1;
   }
   
   protected void setUp() throws Exception
   {
      super.setUp();
      
      if (warObjectName == null)
      {
         String oname = "jboss.web:J2EEApplication=none,J2EEServer=none," +
                        "j2eeType=WebModule,name=//localhost/" + getWarName();
         warObjectName = new ObjectName(oname);
         
         cacheObjectName = new ObjectName("jboss.cache:service=TomcatClusteringCache");
         
         RMIAdaptor[] adaptors = getAdaptors();
         adaptor0_ = adaptors[0];
         adaptor1_ = adaptors[1];
         
         Object[] names = {"JSESSION", "localhost", getWarName() };
         Fqn fqn = new Fqn(names);
         warFqn_ = fqn.toString();
      }
   }
   
   protected String getWarName()
   {
      return "http-scoped";
   }
   
   public void testActivationInactivation() throws Exception
   {
      getLog().debug("Enter testActivationInactivation");

      getLog().debug(setUrl_ + ":::::::" + getUrl_);
      
      // Stop the war on server1
      adaptor1_.invoke(warObjectName, "stop" , NULL_ARGS, NULL_TYPES);

      // Confirm the war isn't available on server1
      HttpClient client0 = new HttpClient();
      makeGetFailed(client0, baseURL1_ +setUrl_);
      
      // Create 3 sessions on server0
      HttpClient[] clients = new HttpClient[3];
      String[] attrs = new String[clients.length];
      for (int i = 0; i < clients.length; i++)
      {
         clients[i] = new HttpClient();
         makeGet(clients[i], baseURL0_ +setUrl_);
         attrs[i] = makeGet(clients[i], baseURL0_ + getUrl_);
         // Set cookie domain to server1
         this.setCookieDomainToThisServer(clients[i], servers_[1]);
      }
      
      getLog().debug("Sessions created");
      
      // Confirm there are no sessions in the server1 cache
      Set sessions = (Set) adaptor1_.invoke(cacheObjectName, 
                                            "getChildrenNames",
                                            new Object[] { warFqn_ },
                                            new String[] { String.class.getName() });      
      if (sessions != null)
      {
         assertTrue("server1 has no cached sessions", sessions.size() == 0);
      }
      
      getLog().debug("Server1 has no cached sessions");
      
      // Start the war on server1
      adaptor1_.invoke(warObjectName, "start" , NULL_ARGS, NULL_TYPES);
      
      getLog().debug("Server1 started");
      
      // Confirm the sessions are in the server1 cache
      sessions = (Set) adaptor1_.invoke(cacheObjectName, 
            "getChildrenNames",
            new Object[] { warFqn_ },
            new String[] { String.class.getName() });
      assertNotNull("server1 has cached sessions", sessions);
      assertEquals("server1 has cached sessions", clients.length, sessions.size());
      
      getLog().debug("Server1 has cached sessions");
      
      for (int i = 0; i < clients.length; i++)
      {
         String attr = makeGet(clients[i], baseURL1_ + getUrl_);
         assertEquals("attribute matches for client " + i, attrs[i], attr);
      }
      
      getLog().debug("Attributes match");
      
      // Sleep a bit in case the above get triggers replication that takes
      // a while -- don't want a repl to arrive after the cache is cleared
      sleep(500);
      
      // Stop the war on server0
      adaptor0_.invoke(warObjectName, "stop" , NULL_ARGS, NULL_TYPES);
      
      // Confirm there are no sessions in the server0 cache
      sessions = (Set) adaptor0_.invoke(cacheObjectName, 
                                        "getChildrenNames",
                                        new Object[] { warFqn_ },
                                        new String[] { String.class.getName() });      
      if (sessions != null)
      {
         assertTrue("server0 has no cached sessions", sessions.size() == 0);
      }
      
      getLog().debug("Server0 has no cached sessions");
   }

}
