Package org.jboss.test.cluster.testutil

Source Code of org.jboss.test.cluster.testutil.SessionTestUtil

/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, 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.test.cluster.testutil;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;

import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletException;

import org.apache.catalina.Context;
import org.apache.catalina.Manager;
import org.apache.catalina.Pipeline;
import org.apache.catalina.Valve;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.core.StandardContext;
import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpState;
import org.infinispan.Cache;
import org.infinispan.config.CacheLoaderManagerConfig;
import org.infinispan.config.Configuration;
import org.infinispan.config.Configuration.CacheMode;
import org.infinispan.config.GlobalConfiguration;
import org.infinispan.lifecycle.ComponentStatus;
import org.infinispan.loaders.CacheLoaderConfig;
import org.infinispan.loaders.file.FileCacheStoreConfig;
import org.infinispan.manager.CacheContainer;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.remoting.transport.Address;
import org.infinispan.util.concurrent.IsolationLevel;
import org.jboss.logging.Logger;
import org.jboss.metadata.javaee.spec.EmptyMetaData;
import org.jboss.metadata.web.jboss.JBossWebMetaData;
import org.jboss.metadata.web.jboss.PassivationConfig;
import org.jboss.metadata.web.jboss.ReplicationConfig;
import org.jboss.metadata.web.jboss.ReplicationGranularity;
import org.jboss.metadata.web.jboss.ReplicationTrigger;
import org.jboss.metadata.web.jboss.SnapshotMode;
import org.jboss.test.cluster.web.mocks.BasicRequestHandler;
import org.jboss.test.cluster.web.mocks.MockEngine;
import org.jboss.test.cluster.web.mocks.MockHost;
import org.jboss.test.cluster.web.mocks.MockRequest;
import org.jboss.test.cluster.web.mocks.MockValve;
import org.jboss.test.cluster.web.mocks.RequestHandler;
import org.jboss.test.cluster.web.mocks.RequestHandlerValve;
import org.jboss.web.tomcat.service.session.JBossCacheManager;
import org.jboss.web.tomcat.service.session.distributedcache.ispn.CacheSource;
import org.jboss.web.tomcat.service.session.distributedcache.ispn.DistributedCacheManagerFactory;
import org.jboss.web.tomcat.service.session.distributedcache.spi.LocalDistributableSessionManager;
import org.jboss.web.tomcat.service.session.distributedcache.spi.OutgoingDistributableSessionData;
import org.jboss.web.tomcat.service.session.distributedcache.spi.TestDistributedCacheManagerFactory;

/**
* Utilities for session testing.
*
* @author <a href="mailto://brian.stansberry@jboss.com">Brian Stansberry</a>
* @version $Revision: 109938 $
*/
public class SessionTestUtil
{
   public static final String CACHE_CONFIG_PROP = "jbosstest.cluster.web.cache.config";
  
   private static final Logger log = Logger.getLogger(SessionTestUtil.class);

   public static JBossCacheManager<?> createManager(String warName,
                                                 int maxInactiveInterval,
                                                 final CacheContainer cacheContainer,
                                                 String jvmRoute)
   {
      if (cacheContainer == null)
      {
         throw new IllegalStateException("Failed to initialize distributedManagerFactory");
      }
     
      DistributedCacheManagerFactory factory = new DistributedCacheManagerFactory();
      CacheSource sessionCacheSource = new CacheSource()
      {
         @Override
         public <K, V> Cache<K, V> getCache(LocalDistributableSessionManager manager)
         {
            return cacheContainer.getCache(manager.getName());
         }
      };
      CacheSource jvmRouteCacheSource = new CacheSource()
      {
         @Override
         public <K, V> Cache<K, V> getCache(LocalDistributableSessionManager manager)
         {
            return cacheContainer.getCache(manager.getEngineName());
         }
      };
     
      factory.setSessionCacheSource(sessionCacheSource);
      factory.setJvmRouteCacheSource(jvmRouteCacheSource);
     
      JBossCacheManager<OutgoingDistributableSessionData> manager = new JBossCacheManager<OutgoingDistributableSessionData>(factory);
      manager.setSnapshotMode(SnapshotMode.INSTANT);
     
      setupContainer(warName, jvmRoute, manager);
     
      // Do this after assigning the manager to the container, or else
      // the container's setting will override ours
      // Can't just set the container as their config is per minute not per second
      manager.setMaxInactiveInterval(maxInactiveInterval);

      return manager;
   }

   private static volatile int containerIndex = 1;
  
   public static EmbeddedCacheManager createCacheContainer(boolean local, String passivationDir, boolean totalReplication, boolean purgeCacheLoader) throws Exception
   {
      GlobalConfiguration global = local ? GlobalConfiguration.getNonClusteredDefault() : GlobalConfiguration.getClusteredDefault();
      global.setClusterName("testing");
      global.setCacheManagerName("container" + containerIndex++);
      global.setStrictPeerToPeer(false);

      Configuration config = new Configuration();
      config.setInvocationBatchingEnabled(true);
      config.setIsolationLevel(IsolationLevel.REPEATABLE_READ);
      config.setSyncReplTimeout(20000);
      config.setLockAcquisitionTimeout(15000);
      config.setCacheMode(local ? CacheMode.LOCAL : (totalReplication ? CacheMode.REPL_SYNC : CacheMode.DIST_SYNC));
     
      CacheMode mode = config.getCacheMode();

      config.setFetchInMemoryState(mode.isReplicated());
     
      // Block for commits -- no races between test driver and replication
      config.setSyncCommitPhase(true);
      config.setSyncRollbackPhase(true);
     
      if (passivationDir != null)
      {
         CacheLoaderManagerConfig managerConfig = new CacheLoaderManagerConfig();
         managerConfig.setPassivation(true);
         managerConfig.setPreload(!purgeCacheLoader);
        
         FileCacheStoreConfig fileConfig = new FileCacheStoreConfig();
         fileConfig.setLocation(passivationDir);
         fileConfig.setFetchPersistentState(mode.isReplicated());
         fileConfig.setPurgeOnStartup(purgeCacheLoader);
        
         managerConfig.setCacheLoaderConfigs(Collections.<CacheLoaderConfig>singletonList(fileConfig));
        
         config.setCacheLoaderManagerConfig(managerConfig);
      }
     
      final EmbeddedCacheManager sessionContainer = new DefaultCacheManager(global, config, false);
     
      global = local ? GlobalConfiguration.getNonClusteredDefault() : GlobalConfiguration.getClusteredDefault();
      global.setClusterName("testing-jvmroute");
      global.setCacheManagerName("container" + containerIndex++);
      global.setStrictPeerToPeer(false);
     
      config = new Configuration();
      config.setInvocationBatchingEnabled(true);
      config.setIsolationLevel(IsolationLevel.REPEATABLE_READ);
      config.setSyncReplTimeout(20000);
      config.setLockAcquisitionTimeout(15000);
      config.setCacheMode(CacheMode.REPL_SYNC);
      config.setFetchInMemoryState(true);
      config.setSyncCommitPhase(true);
      config.setSyncRollbackPhase(true);
     
      final EmbeddedCacheManager jvmRouteContainer = new DefaultCacheManager(global, config, false);
     
      return new EmbeddedCacheManager()
      {
         @Override
         public <K, V> Cache<K, V> getCache()
         {
            return sessionContainer.getCache();
         }

         @Override
         public <K, V> Cache<K, V> getCache(String cacheName)
         {
            return cacheName.equals("jboss.web") ? jvmRouteContainer.<K, V>getCache() : sessionContainer.<K, V>getCache(cacheName);
         }

         @Override
         public void start()
         {
            jvmRouteContainer.start();
            sessionContainer.start();
         }

         @Override
         public void stop()
         {
            sessionContainer.stop();
            jvmRouteContainer.stop();
         }

         @Override
         public void addListener(Object listener)
         {
            sessionContainer.addListener(listener);
         }

         @Override
         public void removeListener(Object listener)
         {
            sessionContainer.removeListener(listener);
         }

         @Override
         public Set<Object> getListeners()
         {
            return sessionContainer.getListeners();
         }

         @Override
         public Configuration defineConfiguration(String cacheName, Configuration configurationOverride)
         {
            return sessionContainer.defineConfiguration(cacheName, configurationOverride);
         }

         @Override
         public Configuration defineConfiguration(String cacheName, String templateCacheName, Configuration configurationOverride)
         {
            return sessionContainer.defineConfiguration(cacheName, templateCacheName, configurationOverride);
         }

         @Override
         public String getClusterName()
         {
            return sessionContainer.getClusterName();
         }

         @Override
         public List<Address> getMembers()
         {
            return sessionContainer.getMembers();
         }

         @Override
         public Address getAddress()
         {
            return sessionContainer.getAddress();
         }

         @Override
         public boolean isCoordinator()
         {
            return sessionContainer.isCoordinator();
         }

         @Override
         public ComponentStatus getStatus()
         {
            return sessionContainer.getStatus();
         }

         @Override
         public GlobalConfiguration getGlobalConfiguration()
         {
            return sessionContainer.getGlobalConfiguration();
         }

         @Override
         public Configuration getDefaultConfiguration()
         {
            return sessionContainer.getDefaultConfiguration();
         }

         @Override
         public Set<String> getCacheNames()
         {
            return sessionContainer.getCacheNames();
         }

         @Override
         public Address getCoordinator()
         {
            return sessionContainer.getCoordinator();
         }

         @Override
         public boolean isRunning(String cacheName)
         {
            return cacheName.equals("jboss.web") ? jvmRouteContainer.isDefaultRunning() : sessionContainer.isRunning(cacheName);
         }

         @Override
         public boolean isDefaultRunning()
         {
            return sessionContainer.isDefaultRunning();
         }
      };
   }
  
   public static void setupContainer(String warName, String jvmRoute, Manager mgr)
   {
      MockEngine engine = new MockEngine();
      engine.setName("jboss.web");
      engine.setJvmRoute(jvmRoute);
      MockHost host = new MockHost();
      host.setName("localhost");
      engine.addChild(host);
      StandardContext container = new StandardContext();
      container.setName(warName);
      host.addChild(container);
      container.setManager(mgr);
   }
  
   public static JBossWebMetaData createWebMetaData(int maxSessions)
   {
      return createWebMetaData(ReplicationGranularity.SESSION,
                               ReplicationTrigger.SET_AND_NON_PRIMITIVE_GET,
                               maxSessions, false, -1, -1, false, 0);
   }
  
   public static JBossWebMetaData createWebMetaData(int maxSessions, boolean passivation,
         int maxIdle, int minIdle)
   {
      return createWebMetaData(ReplicationGranularity.SESSION,
                               ReplicationTrigger.SET_AND_NON_PRIMITIVE_GET,
                               maxSessions, passivation, maxIdle, minIdle, false, 60);
   }
  
   public static JBossWebMetaData createWebMetaData(ReplicationGranularity granularity,
                                                    ReplicationTrigger trigger,boolean batchMode,
                                                    int maxUnreplicated)
   {
      return createWebMetaData(granularity, trigger, -1, false,
                               -1, -1, batchMode, maxUnreplicated);
   }
  
   public static JBossWebMetaData createWebMetaData(ReplicationGranularity granularity,
                                              ReplicationTrigger trigger,
                                              int maxSessions, boolean passivation,
                                              int maxIdle, int minIdle,
                                              boolean batchMode,
                                              int maxUnreplicated)
   {
      JBossWebMetaData webMetaData = new JBossWebMetaData();
      webMetaData.setDistributable(new EmptyMetaData());
      webMetaData.setMaxActiveSessions(new Integer(maxSessions));
      PassivationConfig pcfg = new PassivationConfig();
      pcfg.setUseSessionPassivation(Boolean.valueOf(passivation));
      pcfg.setPassivationMaxIdleTime(new Integer(maxIdle));
      pcfg.setPassivationMinIdleTime(new Integer(minIdle));
      webMetaData.setPassivationConfig(pcfg);
      ReplicationConfig repCfg = new ReplicationConfig();
      repCfg.setReplicationGranularity(granularity);
      repCfg.setReplicationTrigger(trigger);
      repCfg.setReplicationFieldBatchMode(Boolean.valueOf(batchMode));
      repCfg.setMaxUnreplicatedInterval(Integer.valueOf(maxUnreplicated));
      repCfg.setSnapshotMode(SnapshotMode.INSTANT);
      webMetaData.setReplicationConfig(repCfg);
     
      return webMetaData;
   }
  
   public static void invokeRequest(Manager manager, RequestHandler handler, String sessionId)
      throws ServletException, IOException
   {
      Valve valve = setupPipeline(manager, handler);
      Request request = setupRequest(manager, sessionId);
      invokeRequest(valve, request);
   }
  
   public static void invokeRequest(Valve pipelineHead, Request request)
      throws ServletException, IOException
   {
      pipelineHead.invoke(request, request.getResponse());
      // StandardHostValve calls request.getSession(false) on way out, so we will too
      request.getSession(false);
      request.recycle();
   }
  
   public static Valve setupPipeline(Manager manager, RequestHandler requestHandler)
   {
      Pipeline pipeline = manager.getContainer().getPipeline();
     
      // Clean out any existing request handler
      Valve[] valves = pipeline.getValves();
      RequestHandlerValve mockValve = null;
      for (Valve valve: valves)
      {
         if (valve instanceof RequestHandlerValve)        
         {
            mockValve = (RequestHandlerValve) valve;
            break;
         }
      }
     
      if (mockValve == null)
      {
         mockValve = new RequestHandlerValve(requestHandler);
         pipeline.addValve(mockValve);
      }
      else
      {
         mockValve.setRequestHandler(requestHandler);
      }
     
      return pipeline.getFirst();
   }
  
   public static Request setupRequest(Manager manager, String sessionId)
   {
      MockRequest request = new MockRequest();
      request.setRequestedSessionId(sessionId);
      request.setContext((Context) manager.getContainer());
      Response response = new Response();
      request.setResponse(response);
      return request;
     
   }
  
   public static void cleanupPipeline(Manager manager)
   {
      Pipeline pipeline = manager.getContainer().getPipeline();
     
      Valve[] valves = pipeline.getValves();
      for (Valve valve: valves)
      {
         if (valve instanceof MockValve)        
         {
            ((MockValve) valve).clear();
         }
      }
   }

   /**
    * Loops, continually calling {@link #areCacheViewsComplete(TestDistributedCacheManagerFactory[])}
    * until it either returns true or <code>timeout</code> ms have elapsed.
    *
    * @param dcmFactories  caches which must all have consistent views
    * @param timeout max number of ms to loop
    * @throws RuntimeException if <code>timeout</code> ms have elapse without
    *                          all caches having the same number of members.
    */
   public static void blockUntilViewsReceived(EmbeddedCacheManager[] cacheContainers, long timeout)
   {
      long failTime = System.currentTimeMillis() + timeout;

      while (System.currentTimeMillis() < failTime)
      {
         sleepThread(100);
         if (areCacheViewsComplete(cacheContainers))
         {
            return;
         }
      }

      throw new RuntimeException("timed out before caches had complete views");
   }

   /**
    * Checks each cache to see if the number of elements in the array
    * returned by {@link TestDistributedCacheFactory#getMembers()} matches the size of
    * the <code>dcmFactories</code> parameter.
    *
    * @param dcmFactories factory whose caches should form a View
    * @return <code>true</code> if all caches have
    *         <code>factories.length</code> members; false otherwise
    * @throws IllegalStateException if any of the caches have MORE view
    *                               members than factories.length
    */
   public static boolean areCacheViewsComplete(EmbeddedCacheManager[] cacheContainers)
   {
      return areCacheViewsComplete(cacheContainers, true);
   }

   public static boolean areCacheViewsComplete(EmbeddedCacheManager[] cacheContainers, boolean barfIfTooManyMembers)
   {
      for (EmbeddedCacheManager cacheContainer: cacheContainers)
      {
         log.info("Cache container " + cacheContainer.getClusterName() + " members: " + cacheContainer.getMembers());
         if (!isCacheViewComplete(cacheContainer, cacheContainers.length, barfIfTooManyMembers))
         {
            return false;
         }
      }

      return true;
   }

   public static boolean isCacheViewComplete(EmbeddedCacheManager cacheContainer, int memberCount, boolean barfIfTooManyMembers)
   {
      List<Address> members = cacheContainer.getMembers();
      if (members == null || memberCount > members.size())
      {
         return false;
      }
      else if (memberCount < members.size())
      {
         if (barfIfTooManyMembers)
         {
            // This is an exceptional condition
            StringBuffer sb = new StringBuffer("Cache at address ");
            sb.append(cacheContainer.getAddress());
            sb.append(" had ");
            sb.append(members.size());
            sb.append(" members; expecting ");
            sb.append(memberCount);
            sb.append(". Members were (");
            for (int j = 0; j < members.size(); j++)
            {
               if (j > 0)
               {
                  sb.append(", ");
               }
               sb.append(members.get(j));
            }
            sb.append(')');

            throw new IllegalStateException(sb.toString());
         }
        
         return false;
      }

      return true;
   }
  
   public static Cookie getSessionCookie(HttpClient client)
   {
      // Get the state for the JSESSIONID
      HttpState state = client.getState();
      // Get the JSESSIONID so we can reset the host
      Cookie[] cookies = state.getCookies();
      Cookie sessionID = null;
      for(int c = 0; c < cookies.length; c ++)
      {
         Cookie k = cookies[c];
         if(k.getName().equalsIgnoreCase("JSESSIONID"))
         {
            sessionID = k;
         }
      }
      return sessionID;
   }

   public static void setCookieDomainToThisServer(HttpClient client, String server)
   {
      // Get the session cookie
      Cookie sessionID = getSessionCookie(client);
      if (sessionID == null)
      {
         throw new IllegalStateException("No session cookie found on " + client);
      }
      // Reset the domain so that the cookie will be sent to server1
      sessionID.setDomain(server);
      client.getState().addCookie(sessionID);
   }
  
   public static void validateExpectedAttributes(Map<String, Object> expected, BasicRequestHandler handler)
   {
      assertFalse(handler.isNewSession());
     
      if (handler.isCheckAttributeNames())
      {
         assertEquals(expected.size(), handler.getAttributeNames().size());
      }
      Map<String, Object> checked = handler.getCheckedAttributes();
      assertEquals(expected.size(), checked.size());
      for (Map.Entry<String, Object> entry : checked.entrySet())
      {
         assertEquals(entry.getKey(), expected.get(entry.getKey()), entry.getValue());
      }
   }
  
   public static void validateNewSession(BasicRequestHandler handler)
   {
      assertTrue(handler.isNewSession());
      assertEquals(handler.getCreationTime(), handler.getLastAccessedTime());
      if (handler.isCheckAttributeNames())
      {
         assertEquals(0, handler.getAttributeNames().size());
      }
      Map<String, Object> checked = handler.getCheckedAttributes();
      for (Map.Entry<String, Object> entry : checked.entrySet())
      {
         assertNull(entry.getKey(), entry.getValue());
      }
   }
  
   public static String getPassivationDir(String rootDir, long testCount, int cacheCount)
   {
      File dir = new File(rootDir);
      dir = new File(dir, String.valueOf(testCount));
      dir.mkdirs();
      dir.deleteOnExit();
      dir = new File(dir, String.valueOf(cacheCount));
      dir.mkdirs();
      dir.deleteOnExit();
      return dir.getAbsolutePath();
   }
  
   public static void cleanFilesystem(String path)
   {
      if (path != null)
      {
         File f = new File(path);
         if (f.exists())
         {
            if (f.isDirectory())
            {
               File[] children = f.listFiles();
               for (File child : children)
               {
                  try
                  {
                     cleanFilesystem(child.getCanonicalPath());
                  }
                  catch (IOException e)
                  {
                     log.warn("Can't clean any possible children of " + f);
                  }
               }
            }
           
            if (!f.delete())
            {
               f.delete();
            }
         }
      }
   }


   /**
    * Puts the current thread to sleep for the desired number of ms, suppressing
    * any exceptions.
    *
    * @param sleeptime number of ms to sleep
    */
   public static void sleepThread(long sleeptime)
   {
      try
      {
         Thread.sleep(sleeptime);
      }
      catch (InterruptedException ie)
      {
         Thread.currentThread().interrupt();
      }
   }
  
   public static Object getAttributeValue(int value)
   {
      return Integer.valueOf(value);
   }

   private SessionTestUtil() {}
}
TOP

Related Classes of org.jboss.test.cluster.testutil.SessionTestUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.