http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/GemFireEntityRegion.java ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/GemFireEntityRegion.java b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/GemFireEntityRegion.java new file mode 100644 index 0000000..a6dbc7a --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/GemFireEntityRegion.java @@ -0,0 +1,178 @@ +/*========================================================================= + * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved. + * This product is protected by U.S. and international copyright + * and intellectual property laws. Pivotal products are covered by + * one or more patents listed at http://www.pivotal.io/patents. + *========================================================================= + */ +package com.gemstone.gemfire.modules.hibernate.internal; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ExecutorService; + +import org.hibernate.cache.CacheDataDescription; +import org.hibernate.cache.CacheException; +import org.hibernate.cache.EntityRegion; +import org.hibernate.cache.access.AccessType; +import org.hibernate.cache.access.EntityRegionAccessStrategy; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.distributed.DistributedSystem; +import com.gemstone.gemfire.internal.cache.LocalRegion; +import com.gemstone.gemfire.modules.hibernate.GemFireRegionFactory; +import com.gemstone.gemfire.modules.util.ModuleStatistics; + +public class GemFireEntityRegion extends GemFireBaseRegion implements EntityRegion { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + private final boolean USE_JTA = Boolean.getBoolean("gemfiremodules.useJTA"); + + /** + * keys for which interest has been registered already + */ + private ConcurrentMap<Object, Boolean> registeredKeys = new ConcurrentHashMap<Object, Boolean>(); + + /** + * map to store the entries that were pre-fetched when the underlying region has no local storage + */ + protected ConcurrentMap<Object, EntityWrapper> preFetchMap = new ConcurrentHashMap<Object, EntityWrapper>(); + + public GemFireEntityRegion(Region<Object, EntityWrapper> region, + boolean isClient, CacheDataDescription metadata, GemFireRegionFactory regionFactory) { + super(region, isClient, metadata, regionFactory); + } + + @Override + public boolean isTransactionAware() { + // there are no colocation guarantees while using hibernate + // so return false for a PartitionedRegion for now + if (USE_JTA) { + return true; + } + return false; + } + + @Override + public CacheDataDescription getCacheDataDescription() { + return this.metadata; + } + + @Override + public EntityRegionAccessStrategy buildAccessStrategy(AccessType accessType) + throws CacheException { + if (AccessType.READ_ONLY.equals(accessType)) { + log.info("creating read-only access for region: " + this.getName()); + return new ReadOnlyAccess(this); + } + else if (AccessType.NONSTRICT_READ_WRITE.equals(accessType)) { + log.info("creating nonstrict-read-write access for region: " + + this.getName()); + return new NonStrictReadWriteAccess(this); + } + else if (AccessType.READ_WRITE.equals(accessType)) { + log.info("creating read-write access for region: " + + this.getName()); + return new ReadWriteAccess(this); + } + else if (AccessType.TRANSACTIONAL.equals(accessType)) { + log.info("creating transactional access for region: " + + this.getName()); + return new TransactionalAccess(this); + } + throw new UnsupportedOperationException("Unknown access type: " + + accessType); + } + + /** + * Should this region should register interest in keys. + * @return true for client regions with storage + */ + public boolean isRegisterInterestRequired() { + return this.isClientRegion && this.region.getAttributes().getDataPolicy().withStorage(); + } + + /** + * register interest in this key, if not already registered + * @param key + */ + public void registerInterest(Object key) { + if (!this.registeredKeys.containsKey(key)) { + this.region.registerInterest(key); + this.registeredKeys.put(key, Boolean.TRUE); + log.debug("registered interest in key{}", key); + } + } + + public void registerInterest(Collection<?> list) { + // build a list of keys for which interest is not + // already registered + List<Object> interestList = new ArrayList<Object>(); + for (Object o : list) { + if (!this.registeredKeys.containsKey(o)) { + interestList.add(o); + } + } + // register interest in this list + this.region.registerInterest(interestList); + log.debug("registered interest in {} keys", interestList.size()); + } + + /** + * wraps the keys in {@link KeyWrapper} and calls getAll + * on the underlying GemFire region. When the underlying region + * is a proxy region, the fetched entries are stored in a local + * map. + * @param keys + */ + public void getAll(Collection<?> keys) { + Set<KeyWrapper> wrappedKeys = new HashSet<KeyWrapper>(); + for (Object o : keys) { + wrappedKeys.add(new KeyWrapper(o)); + } + if (isRegisterInterestRequired()) { + registerInterest(wrappedKeys); + } else { + Map<Object, EntityWrapper> retVal = this.region.getAll(wrappedKeys); + putInLocalMap(retVal); + } + } + + /** + * if the underlying gemfire region does not have local storage, put + * the pre-fetched entries in {@link #preFetchMap} + * @param map map of prefetched entries + */ + private void putInLocalMap(Map<Object, EntityWrapper> map) { + if (!this.region.getAttributes().getDataPolicy().withStorage()) { + // if the value is null, do not cache in preFetchMap + for (Entry<Object, EntityWrapper> e : map.entrySet()) { + if (e.getValue() != null) { + this.preFetchMap.put(e.getKey(), e.getValue()); + log.debug("putting key: {} value: {} in local map", e.getKey(), e.getValue()); + } + } + } + } + + /** + * If this key was pre-fetched, get the entity. + * @param key + * @return the prefetched entity + */ + public EntityWrapper get(Object key) { + return this.preFetchMap.remove(key); + } +} +
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/GemFireQueryResultsRegion.java ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/GemFireQueryResultsRegion.java b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/GemFireQueryResultsRegion.java new file mode 100644 index 0000000..1a82a77 --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/GemFireQueryResultsRegion.java @@ -0,0 +1,104 @@ +/*========================================================================= + * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved. + * This product is protected by U.S. and international copyright + * and intellectual property laws. Pivotal products are covered by + * one or more patents listed at http://www.pivotal.io/patents. + *========================================================================= + */ +package com.gemstone.gemfire.modules.hibernate.internal; + +import java.util.Collections; +import java.util.Map; + +import org.hibernate.cache.CacheException; +import org.hibernate.cache.QueryResultsRegion; +import org.hibernate.cache.Timestamper; +import org.hibernate.cache.TimestampsRegion; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.gemstone.gemfire.cache.EntryNotFoundException; +import com.gemstone.gemfire.cache.Region; + +public class GemFireQueryResultsRegion implements QueryResultsRegion, TimestampsRegion { + + private final Region region; + + private Logger log = LoggerFactory.getLogger(getClass()); + + public GemFireQueryResultsRegion(Region region) { + this.region = region; + } + + @Override + public Object get(Object key) throws CacheException { + log.debug("get query results for {} ", key); + return this.region.get(key); + } + + @Override + public void put(Object key, Object value) throws CacheException { + log.debug("For key {} putting query results {} ", key, value); + this.region.put(key, value); + } + + @Override + public void evict(Object key) throws CacheException { + log.debug("removing query results for key {}", key); + this.region.remove(key); + } + + @Override + public void evictAll() throws CacheException { + log.debug("clearing the query cache"); + this.region.clear(); + } + + @Override + public String getName() { + return this.region.getName(); + } + + @Override + public void destroy() throws CacheException { + if (!this.region.isDestroyed()) { + this.region.destroyRegion(); + } + } + + @Override + public boolean contains(Object key) { + return this.region.containsKey(key); + } + + @Override + public long getSizeInMemory() { + return -1; + } + + @Override + public long getElementCountInMemory() { + return this.region.size(); + } + + @Override + public long getElementCountOnDisk() { + // TODO make this an overflow region + return -1; + } + + @Override + public Map toMap() { + return Collections.unmodifiableMap(this.region); + } + + @Override + public long nextTimestamp() { + return Timestamper.next(); + } + + @Override + public int getTimeout() { + return 60*1000; // all other cache providers have same value + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/KeyWrapper.java ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/KeyWrapper.java b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/KeyWrapper.java new file mode 100644 index 0000000..48762ab --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/KeyWrapper.java @@ -0,0 +1,84 @@ +/*========================================================================= + * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved. + * This product is protected by U.S. and international copyright + * and intellectual property laws. Pivotal products are covered by + * one or more patents listed at http://www.pivotal.io/patents. + *========================================================================= + */ +package com.gemstone.gemfire.modules.hibernate.internal; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.io.Serializable; + +import org.hibernate.cache.CacheKey; + +import com.gemstone.gemfire.DataSerializable; +import com.gemstone.gemfire.DataSerializer; + +/** + * wraps {@link CacheKey}, and implements equals and + * hashCode. This is required for register interest + * operation/prefetching + * @author sbawaska + * + */ +public class KeyWrapper implements DataSerializable { + + private Serializable key; + private String entityName; + + private static final String separator = "#"; + + public KeyWrapper() { + } + + public KeyWrapper(Object p_key) { + if (p_key instanceof String) { + String stringKey = (String)p_key; + this.key = stringKey.substring(stringKey.indexOf(separator)+1); + this.entityName = stringKey.substring(0, stringKey.indexOf(separator)); + } else { + CacheKey cacheKey = (CacheKey)p_key; + this.key = cacheKey.getKey(); + this.entityName = cacheKey.getEntityOrRoleName(); + } + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof KeyWrapper) { + KeyWrapper other = (KeyWrapper)obj; + if (this.key.toString().equals(other.key.toString()) + && this.entityName.equals(other.entityName)) { + return true; + } + } + return false; + } + + @Override + public int hashCode() { + return this.key.toString().hashCode() + this.entityName.hashCode(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(this.entityName).append(separator).append(this.key); + return sb.toString(); + } + + @Override + public void toData(DataOutput out) throws IOException { + DataSerializer.writeObject(this.key, out); + out.writeUTF(this.entityName); + } + + @Override + public void fromData(DataInput in) throws IOException, ClassNotFoundException { + this.key = DataSerializer.readObject(in); + this.entityName = in.readUTF(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/NonStrictReadWriteAccess.java ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/NonStrictReadWriteAccess.java b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/NonStrictReadWriteAccess.java new file mode 100644 index 0000000..2b45fe8 --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/NonStrictReadWriteAccess.java @@ -0,0 +1,74 @@ +/*========================================================================= + * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved. + * This product is protected by U.S. and international copyright + * and intellectual property laws. Pivotal products are covered by + * one or more patents listed at http://www.pivotal.io/patents. + *========================================================================= + */ +package com.gemstone.gemfire.modules.hibernate.internal; + +import org.hibernate.cache.CacheException; +import org.hibernate.cache.access.SoftLock; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NonStrictReadWriteAccess extends Access { + + private Logger log = LoggerFactory.getLogger(getClass()); + + public NonStrictReadWriteAccess(GemFireEntityRegion region) { + super(region); + } + + @Override + public SoftLock lockItem(Object key, Object version) throws CacheException { + log.debug("lock item called for key {}", key); + return null; + } + + @Override + public boolean afterUpdate(Object key, Object value, Object currentVersion, + Object previousVersion, SoftLock lock) throws CacheException { + log.debug("after update called for key: {} value: {}", key, value); + getGemFireRegion().put(getWrappedKey(key), new EntityWrapper(value, -1L)); + return true; + } + + @Override + public boolean update(Object key, Object value, Object currentVersion, + Object previousVersion) throws CacheException { + log.debug("updating key: {} value: {}", key, value); + getGemFireRegion().put(getWrappedKey(key), new EntityWrapper(value, -1L)); + return true; + } +// +// @Override +// public boolean insert(Object key, Object value, Object version) +// throws CacheException { +// log.debug("inserting key:{} value:{}", key, value); +// getGemFireRegion().put(key, new EntityWrapper(value, -1L)); +// return true; +// } +// +// @Override +// public boolean afterInsert(Object key, Object value, Object version) +// throws CacheException { +// log.debug("after insert called for key:{} value:{}", key, value); +// getGemFireRegion().put(key, new EntityWrapper(value, -1L)); +// return true; +// } +// + @Override + public boolean putFromLoad(Object key, Object value, long txTimestamp, + Object version) throws CacheException { + return putFromLoad(key, value, txTimestamp, version, true); + } + + @Override + public boolean putFromLoad(Object key, Object value, long txTimestamp, + Object version, boolean minimalPutOverride) throws CacheException { + log.debug("putting a new entry from load key:{} value:{}", key, value); + getGemFireRegion().put(getWrappedKey(key), new EntityWrapper(value, -1L)); + return true; + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/ReadOnlyAccess.java ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/ReadOnlyAccess.java b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/ReadOnlyAccess.java new file mode 100644 index 0000000..f966d12 --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/ReadOnlyAccess.java @@ -0,0 +1,46 @@ +/*========================================================================= + * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved. + * This product is protected by U.S. and international copyright + * and intellectual property laws. Pivotal products are covered by + * one or more patents listed at http://www.pivotal.io/patents. + *========================================================================= + */ +package com.gemstone.gemfire.modules.hibernate.internal; + +import org.hibernate.cache.CacheException; +import org.hibernate.cache.access.SoftLock; + +public class ReadOnlyAccess extends Access { + + public ReadOnlyAccess(GemFireEntityRegion region) { + super(region); + } + + @Override + public boolean insert(Object key, Object value, Object version) + throws CacheException { + throw new UnsupportedOperationException( + "insert not supported on read only access"); + } + + @Override + public boolean update(Object key, Object value, Object currentVersion, + Object previousVersion) throws CacheException { + throw new UnsupportedOperationException( + "update not supported on read only access"); + } + + @Override + public boolean afterInsert(Object key, Object value, Object version) + throws CacheException { + throw new UnsupportedOperationException( + "insert not supported on read only access"); + } + + @Override + public boolean afterUpdate(Object key, Object value, Object currentVersion, + Object previousVersion, SoftLock lock) throws CacheException { + throw new UnsupportedOperationException( + "update not supported on read only access"); + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/ReadWriteAccess.java ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/ReadWriteAccess.java b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/ReadWriteAccess.java new file mode 100644 index 0000000..813525b --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/ReadWriteAccess.java @@ -0,0 +1,27 @@ +/*========================================================================= + * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved. + * This product is protected by U.S. and international copyright + * and intellectual property laws. Pivotal products are covered by + * one or more patents listed at http://www.pivotal.io/patents. + *========================================================================= + */ +package com.gemstone.gemfire.modules.hibernate.internal; + +import org.hibernate.cache.CacheException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ReadWriteAccess extends Access { + + private Logger log = LoggerFactory.getLogger(getClass()); + + public ReadWriteAccess(GemFireEntityRegion region) { + super(region); + } + + @Override + public boolean update(Object key, Object value, Object currentVersion, + Object previousVersion) throws CacheException { + return super.update(key, value, currentVersion, previousVersion); + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/RegionFactoryDelegate.java ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/RegionFactoryDelegate.java b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/RegionFactoryDelegate.java new file mode 100644 index 0000000..90df4bc --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/RegionFactoryDelegate.java @@ -0,0 +1,144 @@ +/*========================================================================= + * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved. + * This product is protected by U.S. and international copyright + * and intellectual property laws. Pivotal products are covered by + * one or more patents listed at http://www.pivotal.io/patents. + *========================================================================= + */ +package com.gemstone.gemfire.modules.hibernate.internal; + +import java.util.Iterator; +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.gemstone.gemfire.cache.Cache; +import com.gemstone.gemfire.cache.CacheFactory; +import com.gemstone.gemfire.cache.DataPolicy; +import com.gemstone.gemfire.cache.GemFireCache; +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.RegionShortcut; +import com.gemstone.gemfire.cache.client.ClientRegionShortcut; +import com.gemstone.gemfire.cache.execute.FunctionService; +import com.gemstone.gemfire.internal.cache.GemFireCacheImpl; +import com.gemstone.gemfire.modules.hibernate.GemFireCacheProvider; +import com.gemstone.gemfire.modules.util.BootstrappingFunction; +import com.gemstone.gemfire.modules.util.CreateRegionFunction; +import com.gemstone.gemfire.modules.util.RegionConfiguration; + +public class RegionFactoryDelegate { + + private static final String LOG_FILE = "log-file"; + + private static final String CACHE_XML_FILE = "cache-xml-file"; + + private static final String DEFAULT_REGION_TYPE = RegionShortcut.REPLICATE_HEAP_LRU.name(); + + private static final String CLIENT_DEFAULT_REGION_TYPE = ClientRegionShortcut.PROXY.name(); + + protected final Properties gemfireProperties; + protected final Properties regionProperties; + + protected Logger log = LoggerFactory.getLogger(getClass()); + + private Cache cache; + + public RegionFactoryDelegate(Properties gemfireProperties, Properties regionProperties) { + this.gemfireProperties = gemfireProperties; + this.regionProperties = regionProperties; + } + + public GemFireCache startCache() { + log.info("Creating a GemFire cache"); + checkExistingCache(); + cache = new CacheFactory(gemfireProperties).create(); + log.debug("GemFire cache creation completed"); + FunctionService.onMembers(this.cache.getDistributedSystem()).execute(new BootstrappingFunction()).getResult(); + FunctionService.registerFunction(new CreateRegionFunction(cache)); + return cache; + } + + /** + * When hibernate module is running within servlet container, we should + * check if http module is being used and make sure that we use + * same cache-xml and log-file properties. + */ + protected void checkExistingCache() { + Cache existingCache = GemFireCacheImpl.getInstance(); + if (existingCache == null) { + return; + } + Properties existingProps = existingCache.getDistributedSystem().getProperties(); + String cacheXML = existingProps.getProperty(CACHE_XML_FILE); + String logFile = existingProps.getProperty(LOG_FILE, ""); + this.gemfireProperties.setProperty(CACHE_XML_FILE, cacheXML); + this.gemfireProperties.setProperty(LOG_FILE, logFile); + log.info("Existing GemFire cache detected. Using same "+CACHE_XML_FILE+":"+cacheXML+ + " and "+LOG_FILE+":"+logFile+" as existing cache"); + } + + public Region<Object, EntityWrapper> createRegion(String regionName) { + Region<Object, EntityWrapper> r = cache.getRegion(regionName); + if (r != null) { + // for the peer-to-peer case, for now we assume that + // cache.xml will be the same for all peers + // TODO validate regions without this assumption + return r; + } + String regionType = getRegionType(regionName); + boolean isLocalRegion = regionType.contains("LOCAL") ? true : false; + RegionConfiguration regionConfig = new RegionConfiguration(); + regionConfig.setRegionName(regionName); + regionConfig.setRegionAttributesId(regionType); + regionConfig.setCacheWriterName(EntityRegionWriter.class.getCanonicalName()); + com.gemstone.gemfire.cache.RegionFactory<Object, EntityWrapper> rFactory = this.cache + .createRegionFactory(RegionShortcut.valueOf(regionType)); + rFactory.setCacheWriter(new EntityRegionWriter()); + if (isLocalRegion) { + rFactory.setDataPolicy(DataPolicy.REPLICATE); + } + r = rFactory.create(regionName); + // create same region on peers + if (!isLocalRegion) { + FunctionService.onMembers(this.cache.getDistributedSystem()) + .withArgs(regionConfig).execute(CreateRegionFunction.ID).getResult(); + } + return r; + } + + /** + * returns the type of region to create by consulting the properties specified + * in hibernate.cfg.xml + * + * @see #createRegion(String) + * @param regionName + * @return string representation of {@link RegionShortcut} + * @see GemFireCacheProvider + */ + protected String getRegionType(String regionName) { + String rType = getOverridenRegionType(regionName); + if (rType != null) { + return rType.toUpperCase(); + } + rType = regionProperties + .getProperty("gemfire.default-region-attributes-id"); + if (rType == null) { + rType = DEFAULT_REGION_TYPE; + } + return rType.toUpperCase(); + } + + private String getOverridenRegionType(String regionName) { + String rType = null; + Iterator<Object> it = regionProperties.keySet().iterator(); + while (it.hasNext()) { + String current = (String)it.next(); + if (current.contains(regionName)) { + rType = regionProperties.getProperty(current); + break; + } + } + return rType; + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/TransactionalAccess.java ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/TransactionalAccess.java b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/TransactionalAccess.java new file mode 100644 index 0000000..3c20717 --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/main/java/com/gemstone/gemfire/modules/hibernate/internal/TransactionalAccess.java @@ -0,0 +1,10 @@ +package com.gemstone.gemfire.modules.hibernate.internal; + +public class TransactionalAccess extends Access { + + public TransactionalAccess(GemFireEntityRegion region) { + super(region); + // TODO Auto-generated constructor stub + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/Event.hbm.xml ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/Event.hbm.xml b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/Event.hbm.xml new file mode 100644 index 0000000..9e9fbd7 --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/Event.hbm.xml @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<!DOCTYPE hibernate-mapping PUBLIC + "-//Hibernate/Hibernate Mapping DTD 3.0//EN" + "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> + +<hibernate-mapping package="hibe"> + <class name="Event" table="EVENTS"> + <cache usage="read-write"/> + <id name="id" column="EVENT_ID"> + <generator class="native"/> + </id> + <version name="version"/> + <property name="date" type="timestamp" column="EVENT_DATE"/> + <property name="title"/> + </class> +</hibernate-mapping> http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/Event.java ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/Event.java b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/Event.java new file mode 100644 index 0000000..dfc8748 --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/Event.java @@ -0,0 +1,58 @@ +/*========================================================================= + * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved. + * This product is protected by U.S. and international copyright + * and intellectual property laws. Pivotal products are covered by + * one or more patents listed at http://www.pivotal.io/patents. + *========================================================================= + */ +package hibe; + +import java.util.Date; + +public class Event { + private Long id; + + private String title; + private Date date; + private int i; + + public Event() {} + + public Long getId() { + return id; + } + + private void setId(Long id) { + this.id = id; + } + + public Date getDate() { + return date; + } + + public Integer getVersion() { + return i; + } + + public void setVersion(int i) { + this.i = i; + } + + public void setDate(Date date) { + this.date = date; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + @Override + public String toString() { + StringBuilder b = new StringBuilder(); + b.append("Event:id:"+id+" title:"+title+" date:"+date); + return b.toString(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/HibernateBB.java ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/HibernateBB.java b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/HibernateBB.java new file mode 100644 index 0000000..9c9a624 --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/HibernateBB.java @@ -0,0 +1,63 @@ +/*========================================================================= + * Copyright (c) 2002-2014, Pivotal Software, Inc. All Rights Reserved. + * This product is protected by U.S. and international copyright + * and intellectual property laws. Pivotal products are covered by + * more patents listed at http://www.pivotal.io/patents. + *========================================================================= + */ +package hibe; + +import hydra.*; +import hydra.blackboard.Blackboard; + +/** + * A Hydra blackboard that keeps track of what the various task + * threads in an {@link HibernateTest} do. + * + * @author lhughes + * @since 6.5 + */ +public class HibernateBB extends Blackboard { + +// Blackboard creation variables +static String HIBERNATE_BB_NAME = "Hibernate_Blackboard"; +static String HIBERNATE_BB_TYPE = "RMI"; + +// number of invocations for each task type +// just to show counters definition + use +public static int STARTTASK; +public static int INITTASK; +public static int TASK; +public static int CLOSETASK; +public static int ENDTASK; + +// singleton instance of this Blackboard +public static HibernateBB bbInstance = null; + + /** + * Get the HibernateBB + */ + public static HibernateBB getBB() { + if (bbInstance == null) { + synchronized ( HibernateBB.class ) { + if (bbInstance == null) + bbInstance = new HibernateBB(HIBERNATE_BB_NAME, HIBERNATE_BB_TYPE); + } + } + return bbInstance; + } + + /** + * Zero-arg constructor for remote method invocations. + */ + public HibernateBB() { + } + + /** + * Creates a sample blackboard using the specified name and transport type. + */ + public HibernateBB(String name, String type) { + super(name, type, HibernateBB.class); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/HibernatePrms.java ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/HibernatePrms.java b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/HibernatePrms.java new file mode 100644 index 0000000..0e4c26f --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/HibernatePrms.java @@ -0,0 +1,44 @@ +/*========================================================================= + * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved. + * This product is protected by U.S. and international copyright + * and intellectual property laws. Pivotal products are covered by + * one or more patents listed at http://www.pivotal.io/patents. + *========================================================================= + */ +package hibe; + +import hydra.*; + +public class HibernatePrms extends BasePrms { + +/** (boolean) True if the test execute operations within a single transaction + * Defaults to false + */ +public static Long useTransactions; +public static boolean useTransactions() { + Long key = useTransactions; + return tasktab().booleanAt( key, tab().booleanAt( key, false )); +} + + +public static Long persistenceXml; +public static String getPersistenceXml() { + Long key = persistenceXml; + return tasktab().stringAt( key, tab().stringAt( key, null )); +} + + + +public static Long cachingStrategy; +public static String getCachingStrategy() { + Long key = cachingStrategy; + return tasktab().stringAt( key, tab().stringAt( key, null )); +} + + +// ================================================================================ +static { + BasePrms.setValues(HibernatePrms.class); +} + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/HibernateTest.java ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/HibernateTest.java b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/HibernateTest.java new file mode 100644 index 0000000..5c00063 --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/HibernateTest.java @@ -0,0 +1,418 @@ +/*========================================================================= + * Copyright (c) 2002-2014, Pivotal Software, Inc. All Rights Reserved. + * This product is protected by U.S. and international copyright + * and intellectual property laws. Pivotal products are covered by + * more patents listed at http://www.pivotal.io/patents. + *========================================================================= + */ +package hibe; + +import hydra.*; + +import java.util.*; +import java.sql.*; +import java.io.*; +import com.gemstone.gemfire.*; +import com.gemstone.gemfire.cache.*; +import com.gemstone.gemfire.internal.OSProcess; +import com.gemstone.gemfire.internal.cache.*; + +import org.hibernate.FlushMode; +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.cfg.Configuration; + +/** + * A Hydra test interacts with Hiberate APIs. + * + * @see HibernatePrms + * + * @author lhughes + * @since 6.5 + */ +public class HibernateTest { + + /* The singleton instance of EventTest in this VM */ + static protected HibernateTest testInstance; + + protected boolean useTransactions; + // cache whether this instance should perform all operations in one invocation + // as a single transaction. + protected boolean isSerialExecution; + + /** + * STARTTASK for Hibernate (one time execution) + */ + public synchronized static void HydraTask_startTask() { + long counter = HibernateBB.getBB().getSharedCounters().incrementAndRead(HibernateBB.STARTTASK); + Log.getLogWriter().info("invoked HydraTask_startTask(), STARTTASK counter = " + counter); + } + + /** + * Creates and {@linkplain #initialize initializes} the singleton + * instance of <code>HibernateTest</code> in this VM. + */ + public synchronized static void HydraTask_initialize() throws Exception { + if (testInstance == null) { + testInstance = new HibernateTest(); + testInstance.initialize(); + } + } + + /** + * @see #HydraTask_initialize + */ + protected void initialize() throws Exception{ + String clientName = System.getProperty( "clientName" ); + useTransactions = HibernatePrms.useTransactions(); + isSerialExecution = TestConfig.tab().booleanAt(Prms.serialExecution, false); + long counter = HibernateBB.getBB().getSharedCounters().incrementAndRead(HibernateBB.INITTASK); + + + StringBuffer aStr = new StringBuffer(); + aStr.append("invoked initialize() in " + clientName + "\n"); + aStr.append("useTransactions = " + useTransactions + "\n"); + aStr.append("isSerialExecution = " + isSerialExecution + "\n"); + aStr.append("INITTASK counter = " + counter); + Log.getLogWriter().info(aStr.toString()); + Log.getLogWriter().info("Creating DB"); + createDatabase(); + Log.getLogWriter().info("Created DB"); + } + + /** + * Initializes the test region in the peer VMs + */ + public static void createPeerCache() { + Cache c = CacheHelper.createCache(ConfigPrms.getCacheConfig()); + DiskStoreFactory dsf = c.createDiskStoreFactory(); + File f = new File("member"+RemoteTestModule.getMyVmid()); + f.mkdir(); + dsf.setDiskDirs(new File[] { f}); + dsf.create(DiskStoreFactory.DEFAULT_DISK_STORE_NAME); + } + + /** + * TASK for hibernate test ... MasterController will continually + * assign until totalTaskTimeSec. + */ + public static synchronized void HydraTask_doOps() { + testInstance.doOps(); + } + + +static LogWriter log = null; + + public static void doNothing() throws Exception { } + + public static void testBasic() throws Exception { + log = Log.getLogWriter(); + log.info("SWAP:creating session factory In hibernateTestCase"); + Session session = getSessionFactory().openSession(); + log.info("SWAP:session opened"); + // session.setFlushMode(FlushMode.COMMIT); + session.beginTransaction(); + Event theEvent = new Event(); + theEvent.setTitle("title"); + theEvent.setDate(new java.util.Date()); + session.save(theEvent); + Long id = theEvent.getId(); + session.getTransaction().commit(); + log.info("commit complete...doing load"); + session.beginTransaction(); + Event ev = (Event)session.load(Event.class, id); + log.info("load complete: " + ev); + log.info("SWAP"); + ev.setTitle("newTitle"); + session.save(ev); + log.info("commit"); + session.getTransaction().commit(); + log.info("save complete " + ev); + + session.beginTransaction(); + ev = (Event)session.load(Event.class, id); + log.info("load complete: " + ev); + ev.setTitle("newTitle2"); + session.save(ev); + log.info("commit"); + session.getTransaction().commit(); + log.info("save complete " + ev); + + ev = (Event)session.load(Event.class, id); + log.info("second load " + ev); + session.flush(); + session.disconnect(); + log.info("flush complete session:" + session); + + session = getSessionFactory().openSession(); + // ev = (Event) session.load(Event.class, id); + ev = (Event)session.get(Event.class, id); + log.info("third load " + ev); + //printExistingDB(); + // System.in.read(); + // try direct data + + } + private void doOps() { + long counter = HibernateBB.getBB().getSharedCounters().incrementAndRead(HibernateBB.TASK); + Log.getLogWriter().info("invoked doOps(), TASK counter = " + counter); + } + + /** + * CLOSETASK for hibernate test ... + */ + public static synchronized void HydraTask_closeTask() { + if(testInstance!=null) { + testInstance.closeTask(); + } + } + + private void closeTask() { + long counter = HibernateBB.getBB().getSharedCounters().incrementAndRead(HibernateBB.CLOSETASK); + Log.getLogWriter().info("invoked closeTask(), CLOSETASK counter = " + counter); + } + + /** + * ENDTASK for hibernate test ... time to check BB counters! + */ + public static synchronized void HydraTask_endTask() throws Exception { + testInstance = new HibernateTest(); + testInstance.initialize(); + testInstance.endTask(); + } + + private void endTask() { + HibernateBB.getBB().printSharedCounters(); + } + + private static SessionFactory getSessionFactory() throws Exception { + Configuration cfg = new Configuration(); + cfg.setProperty("hibernate.dialect", "org.hibernate.dialect.DerbyDialect"); + cfg.setProperty("hibernate.connection.driver_class", + "org.apache.derby.jdbc.EmbeddedDriver"); + cfg.setProperty("hibernate.connection.url", "jdbc:derby:sup;create=true"); + cfg.setProperty("hibernate.connection.pool_size", "1"); + cfg.setProperty("hibernate.connection.autocommit", "true"); + cfg.setProperty("hibernate.hbm2ddl.auto", "update"); + cfg.setProperty("hibernate.cache.region.factory_class", + "com.gemstone.gemfire.modules.hibernate.GemFireRegionFactory"); + cfg.setProperty("hibernate.show_sql", "true"); + cfg.setProperty("hibernate.cache.use_query_cache", "true"); + cfg.setProperty("gemfire.locators", getLocatorString()); + cfg.setProperty("gemfire.mcast-port", "0"); + String strategy = HibernatePrms.getCachingStrategy(); + if(strategy!=null) { + cfg.setProperty("gemfire.default-region-attributes-id",strategy); + } + //cfg.setProperty("gemfire.log-level", "fine"); + // cfg.setProperty("", ""); + cfg.addClass(Person.class); + cfg.addClass(Event.class); + return cfg.buildSessionFactory(); + } + + public static void validateQueryCacheRegion() throws Exception { + Cache c = CacheHelper.getCache(); + Set regions = c.rootRegions(); + Region r = c.getRegion("/gemfire.hibernateQueryResults"); + if(r==null) { + throw new Exception("query cache region not found!"); + } + } + + public static void validateEventPersonRegions() throws Exception { + validateEventPersonRegions(true); + } + public static void validateEventPersonRegionsOnPeers() throws Exception { + validateEventPersonRegions(false); + } + private static void validateEventPersonRegions(boolean expectLocal) throws Exception { + Cache c = CacheHelper.getCache(); + Set regions = c.rootRegions(); + for (Object object : regions) { + System.out.println("REGION BURGER:"+((Region)object).getFullPath()); + } + + + Region r = c.getRegion("/__regionConfigurationMetadata"); + if(r==null) { + throw new Exception ("Metadata region is null"); + } + validateRegion("/hibe.Event", expectLocal); + validateRegion("/hibe.Person", expectLocal); + validateRegion("/hibe.Person.events", expectLocal); + + } + + private static void validateRegion(String regionName, boolean expectLocal) throws Exception { + /* + * REPLICATE, + * REPLICATE_PERSISTENT, + * REPLICATE_PROXY, + * PARTITION, + * PARTITION_PERSISTENT, + * PARTITION_REDUNDANT, + * PARTITION_REDUNDANT_PERSISTENT, + * PARTITION_PROXY_REDUNDANT, + * PARTITION_PROXY, + * LOCAL, + * LOCAL_PERSISTENT + * + * HEAP_LRU + * + */ + String strategy = HibernatePrms.getCachingStrategy(); + boolean isLocal = strategy.contains("LOCAL"); + Cache c = CacheHelper.getCache(); + Region r = c.getRegion(regionName); + if(!isLocal && r == null) { + throw new Exception(regionName+" region not found!"); + } else if (isLocal) { + if (expectLocal && r == null) { + throw new Exception("expected region:"+ regionName+" to be null"); + } else { + return; + } + } + boolean partition = false; + boolean persistent = false; + boolean overflow = false; + boolean heapLru = false; + boolean local = false; + boolean redundant = false; + + + System.out.println("VALIDATIN STRAT:"+strategy+" Regger:"+r.getClass()); + if(strategy.indexOf("PARTITION")>-1) { + partition = true; + } + if(strategy.indexOf("PERSISTENT")>-1) { + persistent = true; + } + + + if(strategy.indexOf("OVERFLOW")>-1) { + overflow = true; + } + + + if(strategy.indexOf("HEAP")>-1) { + heapLru = true; + } + + if(strategy.indexOf("LOCAL")>-1) { + local = true; + } + + if(strategy.indexOf("REDUNDANT")>-1) { + redundant = true; + } + + + + RegionAttributes ra = r.getAttributes(); + if(ra.getPartitionAttributes()==null && partition) { + throw new Exception("Supposed to be partition, but no partition attributes"); + } else if(!partition && ra.getPartitionAttributes()!=null) { + throw new Exception("Supposed to be !partition but partition attributes exist"); + } else if(!partition) { + if(local) { + if(ra.getScope()!=Scope.LOCAL) { + throw new Exception("Scope should have been LOCAL, but it is:"+ra.getScope()); + } + } else if(ra.getScope()!=Scope.DISTRIBUTED_ACK) { + throw new Exception("Scope should have been D_ACK, but it is:"+ra.getScope()); + } + } else if(partition && redundant) { + //ok we are chill and partitioned + if(ra.getPartitionAttributes().getRedundantCopies()==0) { + throw new Exception("Redundant copies should have been greater than 0"); + } + } + + if(ra.getPersistBackup() && !persistent) { + throw new Exception("Was supposed to be !persistent, but it is!"); + } else if(!ra.getPersistBackup() && persistent) { + throw new Exception("Was supposed to be persistent, but it isn't!"); + } + + if(overflow) { + EvictionAttributes ea = ra.getEvictionAttributes(); + if(ea.getAlgorithm()==EvictionAlgorithm.NONE || ea.getAction()!=EvictionAction.OVERFLOW_TO_DISK) { + throw new Exception("Overflow should have been on, but wasn't"); + } + } else if(!heapLru) { + EvictionAttributes ea = ra.getEvictionAttributes(); + if(ea.getAlgorithm()!=EvictionAlgorithm.NONE) { + throw new Exception("EvictionAttributes should have been null"); + } + } + + if(heapLru) { + EvictionAttributes ea = ra.getEvictionAttributes(); + if(ea.getAlgorithm()==EvictionAlgorithm.NONE) { + throw new Exception("Eviction should have been on, but wasn't"); + } + EvictionAlgorithm eaa = ea.getAlgorithm(); + + if(eaa==null || eaa!=EvictionAlgorithm.LRU_HEAP) { + throw new Exception("heap lru should have been on, but wasn't"); + } + } else if(!overflow) { + EvictionAttributes ea = ra.getEvictionAttributes(); + if(ea.getAlgorithm()!=EvictionAlgorithm.NONE) { + throw new Exception("EvictionAttributes should have been null"); + } + } + + + + + } + + /** + * Finds the locator endpoint for this VM from the shared {@link + * DistributedSystemBlackboard} map, if it exists. Caches the result. + */ + private static synchronized String getLocatorString() { + Integer vmid = new Integer(5); + DistributedSystemHelper.Endpoint TheLocatorEndpoint = (DistributedSystemHelper.Endpoint)DistributedSystemBlackboard.getInstance() + .getSharedMap().get(vmid); + return TheLocatorEndpoint.getAddress()+"["+TheLocatorEndpoint.getPort()+"]"; + } + + private static void createDatabase() throws Exception { + // Extract all the persistence unit properties: + final Properties properties = new Properties(); + properties.put("javax.persistence.jdbc.driver","org.apache.derby.jdbc.EmbeddedDriver"); + properties.put("javax.persistence.jdbc.url","jdbc:derby:/export/monaco1/users/lhughes/jpa/jpab/temp/work/derby/jpab1379523664;create=true"); + // Load the JDBC driver: + String driver = properties.getProperty("javax.persistence.jdbc.driver"); + if (driver == null) { + return; // cannot connect to the server + } + Class.forName(driver).newInstance(); + + // Build the connection url: + String url = properties.getProperty("javax.persistence.jdbc.url"); + int dbNamePos = url.lastIndexOf('/') + 1; + int dbNameEndPos = url.lastIndexOf(';'); + String dbName = (dbNameEndPos < 0) ? + url.substring(dbNamePos) : url.substring(dbNamePos, dbNameEndPos); + url = url.substring(0, dbNamePos - 1); + url += "?user=" + properties.getProperty("javax.persistence.jdbc.user"); + url += "&password=" + properties.getProperty( + "javax.persistence.jdbc.password"); + + // Try to create the database: + try { + Connection con = DriverManager.getConnection(url); + Statement s = con.createStatement(); + s.executeUpdate("CREATE DATABASE " + dbName); + } + catch (Exception e) { + // silently ignored - database may be created automatically + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/HibernateTest2.java ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/HibernateTest2.java b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/HibernateTest2.java new file mode 100644 index 0000000..686730c --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/HibernateTest2.java @@ -0,0 +1,155 @@ +/*========================================================================= + * Copyright (c) 2002-2014, Pivotal Software, Inc. All Rights Reserved. + * This product is protected by U.S. and international copyright + * and intellectual property laws. Pivotal products are covered by + * more patents listed at http://www.pivotal.io/patents. + *========================================================================= + */ +package hibe; + +import hydra.*; + +import java.util.*; +import com.gemstone.gemfire.cache.*; + +/** + * A Hydra test interacts with Hiberate APIs. + * + * @see HibernatePrms + * + * @author lhughes + * @since 6.5 + */ +public class HibernateTest2 { + + /* The singleton instance of EventTest in this VM */ + static protected HibernateTest2 testInstance; + + protected boolean useTransactions; + // cache whether this instance should perform all operations in one invocation + // as a single transaction. + protected boolean isSerialExecution; + + /** + * STARTTASK for Hibernate (one time execution) + */ + public synchronized static void HydraTask_startTask() { + long counter = HibernateBB.getBB().getSharedCounters().incrementAndRead(HibernateBB.STARTTASK); + Log.getLogWriter().info("invoked HydraTask_startTask(), STARTTASK counter = " + counter); + } + + /** + * Creates and {@linkplain #initialize initializes} the singleton + * instance of <code>HibernateTest2</code> in this VM. + */ + public synchronized static void HydraTask_initialize() { + if (testInstance == null) { + testInstance = new HibernateTest2(); + testInstance.initialize(); + } + } + + /** + * @see #HydraTask_initialize + */ + protected void initialize() { + String clientName = System.getProperty( "clientName" ); + useTransactions = HibernatePrms.useTransactions(); + isSerialExecution = TestConfig.tab().booleanAt(Prms.serialExecution, false); + long counter = HibernateBB.getBB().getSharedCounters().incrementAndRead(HibernateBB.INITTASK); + + + StringBuffer aStr = new StringBuffer(); + aStr.append("invoked initialize() in " + clientName + "\n"); + aStr.append("useTransactions = " + useTransactions + "\n"); + aStr.append("isSerialExecution = " + isSerialExecution + "\n"); + aStr.append("INITTASK counter = " + counter); + + Log.getLogWriter().info(aStr.toString()); + } + + /** + * Initializes the test region in the peer VMs + */ + public static void createPeerCache() { + CacheHelper.createCache(ConfigPrms.getCacheConfig()); + } + + /** + * Initializes the test region in the bridge server VM + */ + public static void initBridgeServer() { + // create cache from xml + String cacheXmlFile = "$JTESTS/gemfirePlugins/server.xml"; + CacheHelper.createCacheFromXml(cacheXmlFile); + //BridgeHelper.startBridgeServer(ConfigPrms.getBridgeConfig()); + } + + /** + * TASK for hibernate test ... MasterController will continually + * assign until totalTaskTimeSec. + */ + public static synchronized void HydraTask_doOps() { + testInstance.doOps(); + } + + private void doOps() { + long counter = HibernateBB.getBB().getSharedCounters().incrementAndRead(HibernateBB.TASK); + Log.getLogWriter().info("invoked doOps(), TASK counter = " + counter); + } + + /** + * TASK for jpab (benchmark) test. Simply wait for client + * to publish data. + */ + public static synchronized void HydraTask_waitForJPAB() { + MasterController.sleepForMs(10000); + testInstance.displayRegions(); + } + + /** + * CLOSETASK for validate regions/region sizes + */ + public static synchronized void HydraTask_displayRegions() { + testInstance.displayRegions(); + } + + private void displayRegions() { + long counter = HibernateBB.getBB().getSharedCounters().incrementAndRead(HibernateBB.CLOSETASK); + + StringBuffer aStr = new StringBuffer(); + Set<Region<?,?>> rootRegions = CacheHelper.getCache().rootRegions(); + aStr.append("There are " + rootRegions.size() + " rootRegions:\n"); + + for (Iterator i = rootRegions.iterator(); i.hasNext(); ) { + Region r = (Region)i.next(); + aStr.append(r.getName() + " has " + r.entrySet().size() + " entries\n"); + } + Log.getLogWriter().info(aStr.toString()); + } + + /** + * CLOSETASK for hibernate test ... + */ + public static synchronized void HydraTask_closeTask() { + testInstance.closeTask(); + } + + private void closeTask() { + long counter = HibernateBB.getBB().getSharedCounters().incrementAndRead(HibernateBB.CLOSETASK); + Log.getLogWriter().info("invoked closeTask(), CLOSETASK counter = " + counter); + } + + /** + * ENDTASK for hibernate test ... time to check BB counters! + */ + public static synchronized void HydraTask_endTask() { + testInstance = new HibernateTest2(); + testInstance.initialize(); + testInstance.endTask(); + } + + private void endTask() { + HibernateBB.getBB().printSharedCounters(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/Person.hbm.xml ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/Person.hbm.xml b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/Person.hbm.xml new file mode 100644 index 0000000..b3ac67b --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/Person.hbm.xml @@ -0,0 +1,21 @@ +<?xml version="1.0"?> +<!DOCTYPE hibernate-mapping PUBLIC + "-//Hibernate/Hibernate Mapping DTD 3.0//EN" + "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> + +<hibernate-mapping package="hibe"> + <class name="Person" table="PERSON"> + <cache usage="read-write"/> + <id name="id" column="PERSON_ID"> + <generator class="native"/> + </id> + <property name="age"/> + <property name="firstname"/> + <property name="lastname"/> + <set name="events" table="PERSON_EVENT"> + <cache usage="read-write"/> + <key column="PERSON_ID"/> + <many-to-many column="EVENT_ID" class="Event"/> + </set> + </class> +</hibernate-mapping> http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/Person.java ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/Person.java b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/Person.java new file mode 100644 index 0000000..ad6e6a0 --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/Person.java @@ -0,0 +1,63 @@ +/*========================================================================= + * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved. + * This product is protected by U.S. and international copyright + * and intellectual property laws. Pivotal products are covered by + * one or more patents listed at http://www.pivotal.io/patents. + *========================================================================= + */ +package hibe; + +import java.util.HashSet; +import java.util.Set; + +public class Person { + private Long id; + private int age; + private String firstname; + private String lastname; + + private Set<Event> events = new HashSet<Event>(); + + public Person() {} + + private void setId(Long id) { + this.id = id; + } + + public Long getId() { + return id; + } + + public void setAge(int age) { + this.age = age; + } + + public int getAge() { + return age; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public String getFirstname() { + return firstname; + } + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + public String getLastname() { + return lastname; + } + + public void setEvents(Set<Event> events) { + this.events = events; + } + + public Set<Event> getEvents() { + return events; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/hibe.bt ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/hibe.bt b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/hibe.bt new file mode 100644 index 0000000..a6408d4 --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/hibe.bt @@ -0,0 +1,33 @@ + /** +Test each RegionShortcut config possibility. + +These ones won't work, so they are left out: + + PARTITION_PROXY, + PARTITION_PROXY_REDUNDANT, + REPLICATE_PROXY + +*/ + +hibe/hibe1.conf locatorHosts=1 locatorVMsPerHost=1 locatorThreadsPerVM=1 A=client clientHosts=1 clientVMsPerHost=4 clientThreadsPerVM=1 B=hibernate hibernateHosts=1 hibernateVMsPerHost=1 hibernateThreadsPerVM=1 + region= + PARTITION, + PARTITION_REDUNDANT, + PARTITION_PERSISTENT, + PARTITION_REDUNDANT_PERSISTENT, + PARTITION_OVERFLOW, + PARTITION_REDUNDANT_OVERFLOW, + PARTITION_PERSISTENT_OVERFLOW, + PARTITION_REDUNDANT_PERSISTENT_OVERFLOW, + PARTITION_HEAP_LRU, + PARTITION_REDUNDANT_HEAP_LRU, + REPLICATE, + REPLICATE_PERSISTENT, + REPLICATE_OVERFLOW, + REPLICATE_PERSISTENT_OVERFLOW, + REPLICATE_HEAP_LRU, + LOCAL, + LOCAL_PERSISTENT, + LOCAL_HEAP_LRU, + LOCAL_OVERFLOW, + LOCAL_PERSISTENT_OVERFLOW http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/hibe.inc ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/hibe.inc b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/hibe.inc new file mode 100644 index 0000000..e724405 --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/hibe.inc @@ -0,0 +1,128 @@ +hydra.Prms-testRequirement = "Starts a locator and p2p clients in a single DS"; +hydra.Prms-testDescription = " TBD "; + +INCLUDE $JTESTS/hydraconfig/hydraparams1.inc; +INCLUDE $JTESTS/hydraconfig/topology_p2p_2_locator.inc; + +/** + * Start the locators and connect them to distributed system. + */ +INITTASK taskClass = hydra.DistributedSystemHelper taskMethod = createLocator + threadGroups = locator; + +INITTASK taskClass = hydra.DistributedSystemHelper taskMethod = startLocatorAndDS + threadGroups = locator; + +INITTASK taskClass = hibe.HibernateTest taskMethod = HydraTask_initialize + threadGroups = hibernate + ; + +INITTASK taskClass = hibe.HibernateTest taskMethod = createPeerCache + threadGroups = locator,clients + ; + +TASK taskClass = hibe.HibernateTest taskMethod = doNothing + threadGroups = clients,locator + maxTimesToRun = 1 + ; + + +CLOSETASK taskClass = hibe.HibernateTest taskMethod = validateEventPersonRegions + threadGroups = hibernate + ; + +CLOSETASK taskClass = hibe.HibernateTest taskMethod = validateEventPersonRegionsOnPeers + threadGroups = clients + ; + +CLOSETASK taskClass = hibe.HibernateTest taskMethod = validateQueryCacheRegion + threadGroups = hibernate + ; + + + +CLOSETASK taskClass = hibe.HibernateTest taskMethod = HydraTask_closeTask + threadGroups = clients + ; + +CLOSETASK taskClass = hydra.DistributedSystemHelper taskMethod = stopLocator + threadGroups = locator; + ; + + +hydra.Prms-totalTaskTimeSec = 600; +hydra.Prms-maxResultWaitSec = 180; + +// test controls the locator (create/start/stop) +hydra.Prms-manageLocatorAgents = false; // turn off master-managed locators + +// define a cache (no regions) +hydra.ConfigPrms-cacheConfig = gemfireCache; +hydra.CachePrms-names = gemfireCache; + +// all are peers in a single DS +hydra.GemFirePrms-distributedSystem = ds; + +THREADGROUP locator + totalThreads = fcn ${locatorHosts} * ${locatorVMsPerHost} + * ${locatorThreadsPerVM} + ncf + clientNames = fcn "hydra.TestConfigFcns.generateNames + (\"locator\", ${locatorHosts}, true)" + ncf; +THREADGROUP clients + totalThreads = fcn ${clientHosts} * ${clientVMsPerHost} + * ${clientThreadsPerVM} + ncf + clientNames = fcn "hydra.TestConfigFcns.generateNames + (\"client\", ${clientHosts}, true)" + ncf; + +THREADGROUP hibernate + totalThreads = fcn ${hibernateHosts} * ${hibernateVMsPerHost} + * ${hibernateThreadsPerVM} + ncf + clientNames = fcn "hydra.TestConfigFcns.generateNames + (\"hibernate\", ${hibernateHosts}, true)" + ncf; + + + + +// Control logging in hydra controlled portion of test +//hydra.log.LogPrms-file_logLevel = fine; +hydra.GemFirePrms-logLevel = fine; +//hydra.VmPrms-extraVMArgs += "-DDistributionManager.VERBOSE=true"; +//hydra.VmPrms-extraVMArgs += "-DDistributionManager.DEBUG_JAVAGROUPS=true"; + + +// need same jars as the jpab (jpa benchmark) +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/lib/antlr-2.7.6.jar; +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/lib/c3p0-0.9.1.jar; +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/lib/cglib-2.2.jar; +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/lib/commons-collections-3.1.jar; +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/lib/dom4j-1.6.1.jar; +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/lib/ehcache-core-2.2.0.jar; +hydra.VmPrms-extraClassPaths += /export/mclaren1/users/sbawaska/gemfireModules/gemfire-modules/target/gemfire-modules-2.1.jar; +hydra.VmPrms-extraClassPaths += /home/sbawaska/.m2/repository/org/hibernate/hibernate-core/3.5.0-Final/hibernate-core-3.5.0-Final.jar; +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/lib/hibernate-index-annotation.jar; +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/lib/hibernate-jpa-2.0-api-1.0.0.Final.jar; +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/lib/infinispan-core-4.0.0.FINAL.jar; +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/lib/javassist-3.9.0.GA.jar; +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/lib/jbosscache-core-3.2.1.GA.jar; +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/lib/jdo2-index.jar; +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/lib/jpa2.jar; +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/lib/jta-1.1.jar; +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/lib/openjpa-index-annotation.jar; +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/lib/oscache-2.1.jar; +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/lib/proxool-0.8.3.jar; +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/lib/slf4j-api-1.5.8.jar; +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/lib/slf4j-jdk14-1.5.8.jar; +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/lib/swarmcache-1.0RC2.jar; + +// jpa test classes +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/jpab.jar; + +// hibernate jar from jpa/Hibernate/lib +hydra.VmPrms-extraClassPaths += /export/java/users/java_share/jpa/jpab/jpa/Hibernate/lib/hibernate3.jar; +hydra.VmPrms-extraClassPaths += /export/gcm/where/java/derby/derby-10.4.2.0/jars/insane/derby.jar; http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/hibe1.conf ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/hibe1.conf b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/hibe1.conf new file mode 100644 index 0000000..5467a4e --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/hibe1.conf @@ -0,0 +1,12 @@ +hydra.Prms-testRequirement = "Basic setup for a concurrent hibernate test"; +hydra.Prms-testDescription = " TBD "; + +INCLUDE $JTESTS/hibe/hibe.inc; + +hibe.HibernatePrms-cachingStrategy = ${region}; + +INITTASK taskClass = hibe.HibernateTest taskMethod = testBasic + threadGroups = hibernate + ; + + \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/hibernate.bt ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/hibernate.bt b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/hibernate.bt new file mode 100644 index 0000000..11c510e --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/test/hydra/hibe/hibernate.bt @@ -0,0 +1,8 @@ +gemfirePlugins/p2pJPAB.conf + locatorHosts=1 locatorVMsPerHost=1 locatorThreadsPerVM=1 + +gemfirePlugins/hctJPAB.conf + locatorHosts=1 locatorVMsPerHost=1 locatorThreadsPerVM=1 + A=client clientHosts=1 clientVMsPerHost=4 clientThreadsPerVM=1 + B=hibernate hibernateHosts=1 hibernateVMsPerHost=1 hibernateThreadsPerVM=1 + http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/test/hydra/readme.txt ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/test/hydra/readme.txt b/extensions/gemfire-modules-hibernate/src/test/hydra/readme.txt new file mode 100644 index 0000000..7a12e6b --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/test/hydra/readme.txt @@ -0,0 +1,48 @@ +To run and compile these tests, you need a gemfire checkout 6.5+ +In that gemfire checkout, cd to the tests directory, and create a symbolic link to the "hibe" directory in here. eg: ln -s /Users/gregp/plugins/gemfire-plugins/src/test/hydra/hibe + +Then apply the following patch to build.xml: +Index: build.xml +=================================================================== +--- build.xml (revision 34744) ++++ build.xml (working copy) +@@ -866,6 +866,7 @@ + <pathelement location="${jetty.dir}/jsp-2.1.jar"/> + <pathelement location="${bcel.dir}/bcel.jar"/> + <pathelement location="${osgi.core.jar}"/> ++ <pathelement +location="/home/sbawaska/.m2/repository/org/hibernate/hibernate-core/3.5.0-Final/hibernate-core-3.5.0-Final.jar"/> + </classpath> + </javac> + +@@ -936,6 +937,7 @@ + <pathelement location="${ant.home}/lib/ant.jar"/> + <pathelement location="${jetty.dir}/core-3.1.1.jar"/> + <pathelement location="${jetty.dir}/jsp-2.1.jar"/> ++ <pathelement +location="/home/sbawaska/.m2/repository/org/hibernate/hibernate-core/3.5.0-Final/hibernate-core-3.5.0-Final.jar"/> + </classpath> + </javac> + +@@ -996,6 +998,7 @@ + <include name="hyperictest/lib/*.jar"/> + <include name="hyperictest/config/*.properties"/> + <include name="jta/*.xml"/> ++ <include name="hibe/*.xml"/> + <include name="junit/runner/excluded.properties"/> + <include name="**/*.bt"/> + <include name="**/*.conf"/> +@@ -2901,6 +2904,7 @@ + <pathelement location="${jetty.dir}/core-3.1.1.jar"/> + <pathelement location="${jetty.dir}/jsp-2.1.jar"/> + <pathelement location="cobertura.jar"/> ++ <pathelement +location="/home/sbawaska/.m2/repository/org/hibernate/hibernate-core/3.5.0-Final/hibernate-core-3.5.0-Final.jar"/> + </classpath> + + <env key="GEMFIRE" value="${product.dir}"/> + + + +In hibe/hibe.inc , there are references to the modules jar in /Users/gregp that need to be changed, also, there are also references to /export/monaco1 , so those need to be reachable. +In gemfire checkout main dir, run ./build.sh compile-tests execute-battery -Dbt.file=`pwd`/tests/hibe/hibe.bt http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/0c89797b/extensions/gemfire-modules-hibernate/src/test/java/com/gemstone/gemfire/modules/Event.java ---------------------------------------------------------------------- diff --git a/extensions/gemfire-modules-hibernate/src/test/java/com/gemstone/gemfire/modules/Event.java b/extensions/gemfire-modules-hibernate/src/test/java/com/gemstone/gemfire/modules/Event.java new file mode 100644 index 0000000..ed80f08 --- /dev/null +++ b/extensions/gemfire-modules-hibernate/src/test/java/com/gemstone/gemfire/modules/Event.java @@ -0,0 +1,58 @@ +/*========================================================================= + * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved. + * This product is protected by U.S. and international copyright + * and intellectual property laws. Pivotal products are covered by + * one or more patents listed at http://www.pivotal.io/patents. + *========================================================================= + */ +package com.gemstone.gemfire.modules; + +import java.util.Date; + +public class Event { + private Long id; + + private String title; + private Date date; + private int i; + + public Event() {} + + public Long getId() { + return id; + } + + private void setId(Long id) { + this.id = id; + } + + public Date getDate() { + return date; + } + + public Integer getVersion() { + return i; + } + + public void setVersion(int i) { + this.i = i; + } + + public void setDate(Date date) { + this.date = date; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + @Override + public String toString() { + StringBuilder b = new StringBuilder(); + b.append("Event:id:"+id+" title:"+title+" date:"+date); + return b.toString(); + } +} \ No newline at end of file
