Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Grotzke committed May 26, 2010
2 parents 5bc72d8 + 0586541 commit 4722eb8
Show file tree
Hide file tree
Showing 16 changed files with 713 additions and 54 deletions.
16 changes: 10 additions & 6 deletions buildfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ JAVOLUTION = artifact('javolution:javolution:jar:5.4.3.1').from(file('lib/javolu
XSTREAM = transitive( 'com.thoughtworks.xstream:xstream:jar:1.3.1' )

# Kryo
KRYO_SERIALIZERS = artifact( 'de.javakaffee:kryoserializers:jar:0.4' ).from(file('lib/kryo-serializers-0.4.jar'))
KRYO = artifact( 'com.esotericsoftware:kryo:jar:1.01' ).from( file( 'lib/kryo-1.01.jar' ) )
KRYO_SERIALIZERS = artifact( 'de.javakaffee:kryoserializers:jar:0.6' ).from(file('lib/kryo-serializers-0.6.jar'))
KRYO = artifact( 'com.esotericsoftware:kryo:jar:1.02' ).from( file( 'lib/kryo-1.02.jar' ) )
REFLECTASM = artifact('com.esotericsoftware:reflectasm:jar:0.8').from(file('lib/reflectasm-0.8.jar'))
MINLOG = artifact('com.esotericsoftware:minlog:jar:1.2').from(file('lib/minlog-1.2.jar'))
ASM = 'asm:asm:jar:3.2'
Expand All @@ -27,6 +27,10 @@ ASM = 'asm:asm:jar:3.2'
JODA_TIME = 'joda-time:joda-time:jar:1.6'
CGLIB = transitive( 'cglib:cglib:jar:2.2' )
WICKET = transitive( 'org.apache.wicket:wicket:jar:1.4.7' )
HIBERNATE = transitive( 'org.hibernate:hibernate-core:jar:3.3.2.GA' )
HIBERNATE_ANNOTATIONS = transitive( 'org.hibernate:hibernate-annotations:jar:3.4.0.GA' )
HSQLDB = transitive( 'hsqldb:hsqldb:jar:1.8.0.10' )
JAVASSIST = transitive( 'javassist:javassist:jar:3.11.0.GA' )

# Testing
JMEMCACHED = transitive( 'com.thimbleware.jmemcached:jmemcached-core:jar:0.9.1' ).reject { |a| a.group == 'org.slf4j' }
Expand All @@ -51,7 +55,7 @@ end
desc 'memcached-session-manager (msm for short): memcached based session failover for Apache Tomcat'
define 'msm' do
project.group = 'de.javakaffee.web.msm'
project.version = '1.3.2'
project.version = '1.3.3'

compile.using :source=>'1.6', :target=>'1.6'
test.using :testng
Expand All @@ -63,14 +67,14 @@ define 'msm' do
desc 'The core module of memcached-session-manager'
define 'core' do |project|
compile.with( SERVLET_API, CATALINA, CATALINA_HA, TC_COYOTE, MEMCACHED )
test.with( JMEMCACHED, HTTP_CLIENT, SLF4J, JMOCK_CGLIB, MOCKITO )
test.with( JMEMCACHED, HTTP_CLIENT, SLF4J, JMOCK_CGLIB, MOCKITO, HIBERNATE, HIBERNATE_ANNOTATIONS, JAVASSIST, HSQLDB )
package :jar, :id => 'memcached-session-manager'
package(:jar, :classifier => 'sources', :id => 'memcached-session-manager').include :from => compile.sources
end

desc 'Javolution/xml based serialization strategy'
define 'javolution-serializer' do |project|
compile.with( projects('core'), project('core').compile.dependencies, JAVOLUTION )
compile.with( projects('core'), project('core').compile.dependencies, JAVOLUTION, HIBERNATE )
test.with( compile.dependencies, project('core').test.dependencies, CLANG )
package :jar, :id => 'msm-javolution-serializer'
package(:jar, :classifier => 'sources', :id => 'msm-javolution-serializer').include :from => compile.sources
Expand Down Expand Up @@ -102,7 +106,7 @@ define 'msm' do

desc 'Kryo/binary serialization strategy'
define 'kryo-serializer' do |project|
compile.with( projects('core'), project('core').compile.dependencies, KRYO_SERIALIZERS, KRYO, REFLECTASM, ASM, MINLOG, JODA_TIME, WICKET )
compile.with( projects('core'), project('core').compile.dependencies, KRYO_SERIALIZERS, KRYO, REFLECTASM, ASM, MINLOG, JODA_TIME, WICKET, HIBERNATE )
test.with( compile.dependencies, project('core').test.dependencies, CLANG )
package :jar, :id => 'msm-kryo-serializer'
package(:jar, :classifier => 'sources', :id => 'msm-kryo-serializer').include :from => compile.sources
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -346,9 +346,8 @@ private ConnectionFactory createConnectionFactory(
}

private TranscoderFactory createTranscoderFactory() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
log.info( "Starting with transcoder factory " + _transcoderFactoryClassName );
final ClassLoader classLoader = getContainer().getLoader().getClassLoader();
final Class<? extends TranscoderFactory> transcoderFactoryClass = Class.forName( _transcoderFactoryClassName, false, classLoader ).asSubclass( TranscoderFactory.class );
_log.info( "Creating transcoder factory " + _transcoderFactoryClassName );
final Class<? extends TranscoderFactory> transcoderFactoryClass = loadTranscoderFactoryClass();
final TranscoderFactory transcoderFactory = transcoderFactoryClass.newInstance();
transcoderFactory.setCopyCollectionsForSerialization( _copyCollectionsForSerialization );
if ( _customConverterClassNames != null ) {
Expand All @@ -358,6 +357,19 @@ private TranscoderFactory createTranscoderFactory() throws InstantiationExceptio
return transcoderFactory;
}

private Class<? extends TranscoderFactory> loadTranscoderFactoryClass() throws ClassNotFoundException {
Class<? extends TranscoderFactory> transcoderFactoryClass;
final ClassLoader classLoader = getContainer().getLoader().getClassLoader();
try {
_log.debug( "Loading transcoder factory class " + _transcoderFactoryClassName + " using classloader " + classLoader );
transcoderFactoryClass = Class.forName( _transcoderFactoryClassName, false, classLoader ).asSubclass( TranscoderFactory.class );
} catch ( final ClassNotFoundException e ) {
_log.info( "Could not load transcoderfactory class with classloader "+ classLoader +", trying " + getClass().getClassLoader() );
transcoderFactoryClass = Class.forName( _transcoderFactoryClassName, false, getClass().getClassLoader() ).asSubclass( TranscoderFactory.class );
}
return transcoderFactoryClass;
}

protected NodeAvailabilityCache<String> createNodeAvailabilityCache( final int size, final long ttlInMillis,
final MemcachedClient memcachedClient ) {
return new NodeAvailabilityCache<String>( size, ttlInMillis, new CacheLoader<String>() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@
import java.util.HashMap;
import java.util.Hashtable;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.naming.NamingException;
import javax.servlet.http.HttpSessionActivationListener;
Expand Down Expand Up @@ -509,6 +511,18 @@ public static void assertDeepEquals( final Object one, final Object another, fin
return;
}

if ( Set.class.isAssignableFrom( one.getClass() ) ) {
final Set<?> m1 = (Set<?>) one;
final Set<?> m2 = (Set<?>) another;
Assert.assertEquals( m1.size(), m2.size() );
final Iterator<?> iter1 = m1.iterator();
final Iterator<?> iter2 = m2.iterator();
while( iter1.hasNext() ) {
assertDeepEquals( iter1.next(), iter2.next() );
}
return;
}

if ( Number.class.isAssignableFrom( one.getClass() ) ) {
Assert.assertEquals( ( (Number) one ).longValue(), ( (Number) another ).longValue() );
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
/*
* Copyright 2010 Martin Grotzke
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package de.javakaffee.web.msm.serializer.hibernate;

import java.io.Serializable;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;

import org.apache.catalina.core.StandardContext;
import org.apache.catalina.loader.WebappLoader;
import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.annotations.AccessType;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

import de.javakaffee.web.msm.MemcachedBackupSession;
import de.javakaffee.web.msm.MemcachedBackupSessionManager;
import de.javakaffee.web.msm.SessionAttributesTranscoder;
import de.javakaffee.web.msm.TranscoderService;
import de.javakaffee.web.msm.integration.TestUtils;

/**
* Test for serialization/deserialization of hibernate collection mappings.
*
* @author <a href="mailto:martin.grotzke@javakaffee.de">Martin Grotzke</a>
*/
public abstract class AbstractHibernateCollectionsTest {

private static final Logger LOG = LoggerFactory.getLogger( AbstractHibernateCollectionsTest.class );

private SessionFactory _sessionFactory;

@BeforeTest
protected void beforeTest() {
_sessionFactory = new AnnotationConfiguration()
.addAnnotatedClass( Person.class )
.addAnnotatedClass( Animal.class )
.configure().buildSessionFactory();
}

@Test( enabled = true )
public void testDeserializeHibernateCollection() {

final MemcachedBackupSessionManager manager = createManager();

final Set<Animal> animals = new HashSet<Animal>( Arrays.asList( new Animal( "cat" ) ) );
final Person person = new Person( "foo bar", animals );

final Long personId = createPerson( person );
final Person foundPerson = findPerson( personId );
LOG.info( "person: " + person.toString() );
LOG.info( "found: " + foundPerson.toString() );
TestUtils.assertDeepEquals( person, foundPerson );

final TranscoderService transcoderService = new TranscoderService( createTranscoder( manager ) );

final MemcachedBackupSession session = createSession( manager, "123456789" );
session.setAttribute( "person", foundPerson );

final byte[] data = transcoderService.serialize( session );
final MemcachedBackupSession deserialized = transcoderService.deserialize( data, null, manager );

final Person deserializedPerson = (Person) deserialized.getAttribute( "person" );
TestUtils.assertDeepEquals( foundPerson, deserializedPerson );

}

protected abstract SessionAttributesTranscoder createTranscoder( MemcachedBackupSessionManager manager );

private Person findPerson( final Long personId ) {
final Person foundPerson = withSession( new Callback<Person>() {

@Override
public Person execute( final Session session ) {

final Criteria crit = session.createCriteria( Person.class ).add( Restrictions.idEq( personId ) );
@SuppressWarnings( "unchecked" )
final List<Person> list = crit.list();
Assert.assertEquals( list.size(), 1 );
final Person result = list.get( 0 );
Hibernate.initialize( result.animals );
return result;
}

});
return foundPerson;
}

private Long createPerson( final Person person ) {
final Long personId = withSession( new Callback<Long>() {

@Override
public Long execute( final Session session ) {
return (Long) session.save( person );
}

});
return personId;
}

@Entity
@AccessType( "field" )
@SuppressWarnings( "serial" )
static class Person implements Serializable {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public Long id;
public String name;

@OneToMany( cascade = CascadeType.ALL )
public Set<Animal> animals;

public Person() {
}
public Person( final String name, final Set<Animal> animals ) {
this.name = name;
this.animals = animals;
}

@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", animals=" + animals + "]";
}

}

@Entity
@AccessType( "field" )
@SuppressWarnings( "serial" )
static class Animal implements Serializable {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public Long id;
public String name;

public Animal() {
}
public Animal( final String name ) {
this.name = name;
}

@Override
public String toString() {
return "Animal [id=" + id + ", name=" + name + "]";
}

}

static interface Callback<T> {

T execute(Session session);

}

<T> T withSession( final Callback<T> callback ) {
final Session session = _sessionFactory.openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
final T result = callback.execute( session );
transaction.commit();
return result;
} catch ( final HibernateException e ) {
transaction.rollback();
throw new RuntimeException( e );
} finally {
session.close();
}
}

private static MemcachedBackupSessionManager createManager() {
final MemcachedBackupSessionManager manager = new MemcachedBackupSessionManager();

final StandardContext container = new StandardContext();
manager.setContainer( container );

final WebappLoader webappLoader = new WebappLoader() {
@Override
public ClassLoader getClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
};
manager.getContainer().setLoader( webappLoader );

return manager;
}

private static MemcachedBackupSession createSession( final MemcachedBackupSessionManager manager, final String id ) {
final MemcachedBackupSession session = manager.createEmptySession();
session.setId( id );
session.setValid( true );
return session;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2010 Martin Grotzke
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package de.javakaffee.web.msm.serializer.hibernate;

import org.testng.annotations.Test;

import de.javakaffee.web.msm.JavaSerializationTranscoder;
import de.javakaffee.web.msm.MemcachedBackupSessionManager;
import de.javakaffee.web.msm.SessionAttributesTranscoder;

/**
* Test for serialization/deserialization of hibernate collection mappings with
* {@link JavaSerializationTranscoder}.
*
* @author <a href="mailto:martin.grotzke@javakaffee.de">Martin Grotzke</a>
*/
@Test
public class JavaSerializationHibernateCollectionsTest extends AbstractHibernateCollectionsTest {

@Override
protected SessionAttributesTranscoder createTranscoder( final MemcachedBackupSessionManager manager ) {
return new JavaSerializationTranscoder( manager );
}


}
Loading

0 comments on commit 4722eb8

Please sign in to comment.