HHH-10023 Make hibernate-infinispan compiled with Infinispan 7.x but runnable with Infinispan 8.x

This commit is contained in:
Radim Vansa 2015-08-06 13:38:05 +02:00 committed by Galder Zamarreño
parent 6fdc4cab8d
commit c952a843fa
10 changed files with 142 additions and 46 deletions

View File

@ -7,7 +7,6 @@
package org.hibernate.cache.infinispan.timestamp;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.transaction.Transaction;
@ -17,6 +16,8 @@ import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.engine.spi.SessionImplementor;
import org.infinispan.AdvancedCache;
import org.infinispan.commons.util.CloseableIterable;
import org.infinispan.container.entries.CacheEntry;
import org.infinispan.context.Flag;
import org.infinispan.notifications.Listener;
import org.infinispan.notifications.cachelistener.annotation.CacheEntryModified;
@ -121,9 +122,14 @@ public class ClusteredTimestampsRegionImpl extends TimestampsRegionImpl {
* Brings all data from the distributed cache into our local cache.
*/
private void populateLocalCache() {
final Set children = cache.keySet();
for ( Object key : children ) {
get( null, key );
CloseableIterable<CacheEntry<Object, Void>> iterable = Caches.keys(cache);
try {
for (CacheEntry<Object, Void> entry : iterable) {
get(null, entry.getKey());
}
}
finally {
iterable.close();
}
}

View File

@ -6,13 +6,21 @@
*/
package org.hibernate.cache.infinispan.util;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.Callable;
import javax.transaction.Status;
import javax.transaction.TransactionManager;
import org.infinispan.AdvancedCache;
import org.infinispan.commons.util.CloseableIterable;
import org.infinispan.commons.util.CloseableIterator;
import org.infinispan.container.entries.CacheEntry;
import org.infinispan.context.Flag;
import org.infinispan.filter.AcceptAllKeyValueFilter;
import org.infinispan.filter.NullValueConverter;
import org.infinispan.remoting.rpc.RpcManager;
import org.infinispan.remoting.rpc.RpcOptions;
@ -263,12 +271,11 @@ public class Caches {
}
public static void removeAll(AdvancedCache cache) {
CloseableIterator it = cache.keySet().iterator();
CloseableIterator it = keys(cache).iterator();
try {
while (it.hasNext()) {
// Necessary to get next element
it.next();
it.remove();
// Cannot use it.next(); it.remove() due to ISPN-5653
cache.remove(it.next());
}
}
finally {
@ -276,4 +283,83 @@ public class Caches {
}
}
/**
* This interface is provided for convenient fluent use of CloseableIterable
*/
public interface CollectableCloseableIterable extends CloseableIterable {
Set toSet();
}
public static CollectableCloseableIterable keys(AdvancedCache cache) {
// HHH-10023: we can't use keySet()
final CloseableIterable<CacheEntry<Object, Void>> entryIterable = cache
.filterEntries( AcceptAllKeyValueFilter.getInstance() )
.converter( NullValueConverter.getInstance() );
return new CollectableCloseableIterable() {
@Override
public void close() {
entryIterable.close();
}
@Override
public CloseableIterator iterator() {
final CloseableIterator<CacheEntry<Object, Void>> entryIterator = entryIterable.iterator();
return new CloseableIterator() {
@Override
public void close() {
entryIterator.close();
}
@Override
public boolean hasNext() {
return entryIterator.hasNext();
}
@Override
public Object next() {
return entryIterator.next().getKey();
}
};
}
@Override
public String toString() {
CloseableIterator<CacheEntry<Object, Void>> it = entryIterable.iterator();
try {
if (!it.hasNext()) {
return "[]";
}
StringBuilder sb = new StringBuilder();
sb.append('[');
for (; ; ) {
CacheEntry<Object, Void> entry = it.next();
sb.append(entry.getKey());
if (!it.hasNext()) {
return sb.append(']').toString();
}
sb.append(',').append(' ');
}
}
finally {
it.close();
}
}
@Override
public Set toSet() {
HashSet set = new HashSet();
CloseableIterator it = iterator();
try {
while (it.hasNext()) {
set.add(it.next());
}
}
finally {
it.close();
}
return set;
}
};
}
}

View File

@ -22,6 +22,7 @@ import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cache.infinispan.InfinispanRegionFactory;
import org.hibernate.cache.infinispan.impl.BaseGeneralDataRegion;
import org.hibernate.cache.infinispan.util.Caches;
import org.hibernate.cache.spi.GeneralDataRegion;
import org.hibernate.cache.spi.QueryResultsRegion;
import org.hibernate.cache.spi.Region;
@ -33,6 +34,7 @@ import org.hibernate.test.cache.infinispan.functional.SingleNodeTestCase;
import org.hibernate.test.cache.infinispan.util.BatchModeJtaPlatform;
import org.hibernate.test.cache.infinispan.util.CacheTestUtil;
import org.infinispan.AdvancedCache;
import org.infinispan.commons.util.CloseableIterable;
import org.infinispan.transaction.tm.BatchModeTransactionManager;
import org.jboss.logging.Logger;
import org.junit.Test;
@ -188,11 +190,11 @@ public abstract class AbstractGeneralDataRegionTestCase extends AbstractRegionIm
SessionImplementor remoteSession = (SessionImplementor) sessionFactories.get(1).openSession();
try {
Set keys = localCache.keySet();
assertEquals( "No valid children in " + keys, 0, getValidKeyCount( keys ) );
Set localKeys = Caches.keys(localCache).toSet();
assertEquals( "No valid children in " + localKeys, 0, localKeys.size() );
keys = remoteCache.keySet();
assertEquals( "No valid children in " + keys, 0, getValidKeyCount( keys ) );
Set remoteKeys = Caches.keys(remoteCache).toSet();
assertEquals( "No valid children in " + remoteKeys, 0, remoteKeys.size() );
assertNull( "local is clean", localRegion.get(null, KEY ) );
assertNull( "remote is clean", remoteRegion.get(null, KEY ) );
@ -215,13 +217,15 @@ public abstract class AbstractGeneralDataRegionTestCase extends AbstractRegionIm
sleep( 250 );
// This should re-establish the region root node in the optimistic case
assertNull( localRegion.get(null, KEY ) );
assertEquals( "No valid children in " + keys, 0, getValidKeyCount( localCache.keySet() ) );
localKeys = Caches.keys(localCache).toSet();
assertEquals( "No valid children in " + localKeys, 0, localKeys.size() );
// Re-establishing the region root on the local node doesn't
// propagate it to other nodes. Do a get on the remote node to re-establish
// This only adds a node in the case of optimistic locking
assertEquals( null, remoteRegion.get(null, KEY ) );
assertEquals( "No valid children in " + keys, 0, getValidKeyCount( remoteCache.keySet() ) );
remoteKeys = Caches.keys(remoteCache).toSet();
assertEquals( "No valid children in " + remoteKeys, 0, remoteKeys.size() );
assertEquals( "local is clean", null, localRegion.get(null, KEY ) );
assertEquals( "remote is clean", null, remoteRegion.get(null, KEY ) );

View File

@ -96,9 +96,4 @@ public abstract class AbstractNonFunctionalTestCase extends org.hibernate.testin
protected void avoidConcurrentFlush() {
testSupport.avoidConcurrentFlush();
}
protected int getValidKeyCount(Set keys) {
return keys.size();
}
}

View File

@ -418,9 +418,9 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
final Object KEY = TestingKeyFactory.generateCollectionCacheKey( KEY_BASE + testCount++ );
assertEquals( 0, getValidKeyCount( localCollectionRegion.getCache().keySet() ) );
assertEquals( 0, localCollectionRegion.getCache().size() );
assertEquals( 0, getValidKeyCount( remoteCollectionRegion.getCache().keySet() ) );
assertEquals( 0, remoteCollectionRegion.getCache().size() );
assertNull( "local is clean", localAccessStrategy.get(null, KEY, System.currentTimeMillis() ) );
assertNull( "remote is clean", remoteAccessStrategy.get(null, KEY, System.currentTimeMillis() ) );
@ -447,19 +447,19 @@ public abstract class AbstractCollectionRegionAccessStrategyTestCase extends Abs
// This should re-establish the region root node
assertNull( localAccessStrategy.get(null, KEY, System.currentTimeMillis() ) );
assertEquals( 0, getValidKeyCount( localCollectionRegion.getCache().keySet() ) );
assertEquals( 0, localCollectionRegion.getCache().size() );
// Re-establishing the region root on the local node doesn't
// propagate it to other nodes. Do a get on the remote node to re-establish
assertEquals( null, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis() ) );
assertEquals( 0, getValidKeyCount( remoteCollectionRegion.getCache().keySet() ) );
assertEquals( 0, remoteCollectionRegion.getCache().size() );
// Test whether the get above messes up the optimistic version
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer( 1 ) );
assertEquals( VALUE1, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis() ) );
assertEquals( 1, getValidKeyCount( remoteCollectionRegion.getCache().keySet() ) );
assertEquals( 1, remoteCollectionRegion.getCache().size() );
// Wait for async propagation of the putFromLoad
sleep( 250 );

View File

@ -506,8 +506,8 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
private void evictOrRemoveTest(final boolean evict) throws Exception {
final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ );
assertEquals(0, getValidKeyCount(localEntityRegion.getCache().keySet()));
assertEquals(0, getValidKeyCount(remoteEntityRegion.getCache().keySet()));
assertEquals(0, localEntityRegion.getCache().size());
assertEquals(0, remoteEntityRegion.getCache().size());
assertNull("local is clean", localAccessStrategy.get(null, KEY, System.currentTimeMillis()));
assertNull("remote is clean", remoteAccessStrategy.get(null, KEY, System.currentTimeMillis()));
@ -528,15 +528,15 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
}
});
assertEquals(null, localAccessStrategy.get(null, KEY, System.currentTimeMillis()));
assertEquals(0, getValidKeyCount(localEntityRegion.getCache().keySet()));
assertEquals(0, localEntityRegion.getCache().size());
assertEquals(null, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis()));
assertEquals(0, getValidKeyCount(remoteEntityRegion.getCache().keySet()));
assertEquals(0, remoteEntityRegion.getCache().size());
}
private void evictOrRemoveAllTest(final boolean evict) throws Exception {
final Object KEY = TestingKeyFactory.generateEntityCacheKey( KEY_BASE + testCount++ );
assertEquals(0, getValidKeyCount(localEntityRegion.getCache().keySet()));
assertEquals(0, getValidKeyCount(remoteEntityRegion.getCache().keySet()));
assertEquals(0, localEntityRegion.getCache().size());
assertEquals(0, remoteEntityRegion.getCache().size());
assertNull("local is clean", localAccessStrategy.get(null, KEY, System.currentTimeMillis()));
assertNull("remote is clean", remoteAccessStrategy.get(null, KEY, System.currentTimeMillis()));
@ -567,17 +567,17 @@ public abstract class AbstractEntityRegionAccessStrategyTestCase extends Abstrac
// This should re-establish the region root node in the optimistic case
assertNull(localAccessStrategy.get(null, KEY, System.currentTimeMillis()));
assertEquals(0, getValidKeyCount(localEntityRegion.getCache().keySet()));
assertEquals(0, localEntityRegion.getCache().size());
// Re-establishing the region root on the local node doesn't
// propagate it to other nodes. Do a get on the remote node to re-establish
assertEquals(null, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis()));
assertEquals(0, getValidKeyCount(remoteEntityRegion.getCache().keySet()));
assertEquals(0, remoteEntityRegion.getCache().size());
// Test whether the get above messes up the optimistic version
remoteAccessStrategy.putFromLoad(null, KEY, VALUE1, System.currentTimeMillis(), new Integer(1));
assertEquals(VALUE1, remoteAccessStrategy.get(null, KEY, System.currentTimeMillis()));
assertEquals(1, getValidKeyCount(remoteEntityRegion.getCache().keySet()));
assertEquals(1, remoteEntityRegion.getCache().size());
// Wait for async propagation
sleep(250);

View File

@ -7,11 +7,14 @@ import org.hibernate.Session;
import org.hibernate.boot.SessionFactoryBuilder;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cache.infinispan.entity.EntityRegionImpl;
import org.hibernate.cache.infinispan.util.Caches;
import org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
import org.hibernate.test.cache.infinispan.tm.XaConnectionProvider;
import org.hibernate.testing.env.ConnectionProviderBuilder;
import org.infinispan.AdvancedCache;
import org.infinispan.commons.util.CloseableIterable;
import org.infinispan.commons.util.CloseableIteratorSet;
import org.infinispan.context.Flag;
import org.junit.Test;
@ -110,9 +113,10 @@ public class MultiTenancyTestCase extends SingleNodeTestCase {
// });
// }
EntityRegionImpl region = (EntityRegionImpl) sessionFactory().getSecondLevelCacheRegion(Item.class.getName());
CloseableIteratorSet keySet = region.getCache().withFlags(Flag.CACHE_MODE_LOCAL).keySet();
assertEquals(1, keySet.size());
assertEquals("OldCacheKeyImplementation", keySet.iterator().next().getClass().getSimpleName());
AdvancedCache localCache = region.getCache().withFlags(Flag.CACHE_MODE_LOCAL);
CloseableIterable keys = Caches.keys(localCache);
assertEquals(1, localCache.size());
assertEquals("OldCacheKeyImplementation", keys.iterator().next().getClass().getSimpleName());
}
}

View File

@ -4,6 +4,9 @@ import java.util.concurrent.Callable;
import org.hibernate.Session;
import org.hibernate.cache.infinispan.entity.EntityRegionImpl;
import org.hibernate.cache.infinispan.util.Caches;
import org.infinispan.AdvancedCache;
import org.infinispan.commons.util.CloseableIterable;
import org.infinispan.commons.util.CloseableIteratorSet;
import org.infinispan.context.Flag;
import org.junit.Test;
@ -48,9 +51,10 @@ public class NoTenancyTestCase extends SingleNodeTestCase {
}
EntityRegionImpl region = (EntityRegionImpl) sessionFactory().getSecondLevelCacheRegion(Item.class.getName());
CloseableIteratorSet keySet = region.getCache().withFlags(Flag.CACHE_MODE_LOCAL).keySet();
assertEquals(1, keySet.size());
assertEquals(sessionFactory().getClassMetadata(Item.class).getIdentifierType().getReturnedClass(), keySet.iterator().next().getClass());
AdvancedCache localCache = region.getCache().withFlags(Flag.CACHE_MODE_LOCAL);
CloseableIterable keys = Caches.keys(localCache);
assertEquals(1, localCache.size());
assertEquals(sessionFactory().getClassMetadata(Item.class).getIdentifierType().getReturnedClass(), keys.iterator().next().getClass());
}
}

View File

@ -124,8 +124,8 @@ public class EntityCollectionInvalidationTestCase extends DualNodeTestCase {
assertLoadedFromCache( remoteListener, ids.customerId, ids.contactIds );
// After modification, local cache should have been invalidated and hence should be empty
assertEquals( 0, getValidKeyCount( localCollectionCache.keySet() ) );
assertEquals( 0, getValidKeyCount( localCustomerCache.keySet() ) );
assertEquals( 0, localCollectionCache.size() );
assertEquals( 0, localCustomerCache.size() );
}
finally {
// cleanup the db
@ -313,10 +313,6 @@ public class EntityCollectionInvalidationTestCase extends DualNodeTestCase {
);
}
protected int getValidKeyCount(Set keys) {
return keys.size();
}
@Listener
public static class MyListener {
private static final Log log = LogFactory.getLog( MyListener.class );

View File

@ -14,6 +14,7 @@ import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cache.infinispan.util.Caches;
import org.hibernate.criterion.Restrictions;
import org.hibernate.test.cache.infinispan.functional.Citizen;
import org.hibernate.test.cache.infinispan.functional.NaturalIdOnManyToOne;
@ -124,7 +125,7 @@ public class NaturalIdInvalidationTestCase extends DualNodeTestCase {
deleteCitizenWithCriteria(remoteTM, remoteFactory);
sleep(250);
Set localKeys = localNaturalIdCache.keySet();
Set localKeys = Caches.keys(localNaturalIdCache.getAdvancedCache()).toSet();
assertEquals(1, localKeys.size());
// Only key left is the one for the citizen *not* in France
localKeys.toString().contains("000");