blob: 26a9c9c64f9850d72db517d9e4fa7292581bc0e9 [file] [log] [blame]
package com.gemstone.gemfire.internal;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import java.io.File;
import java.util.Collection;
import java.util.Properties;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import com.gemstone.gemfire.cache.Cache;
import com.gemstone.gemfire.cache.CacheFactory;
import com.gemstone.gemfire.cache.DiskStoreFactory;
import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.cache.RegionFactory;
import com.gemstone.gemfire.cache.RegionShortcut;
import com.gemstone.gemfire.cache.query.internal.DefaultQuery;
import com.gemstone.gemfire.internal.cache.DiskStoreImpl;
import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
import com.gemstone.gemfire.internal.util.BlobHelper;
import com.gemstone.gemfire.pdx.PdxInstance;
import com.gemstone.gemfire.pdx.PdxInstanceFactory;
import com.gemstone.gemfire.pdx.PdxReader;
import com.gemstone.gemfire.pdx.PdxSerializable;
import com.gemstone.gemfire.pdx.PdxWriter;
import com.gemstone.gemfire.pdx.internal.PdxField;
import com.gemstone.gemfire.pdx.internal.PdxInstanceImpl;
import com.gemstone.gemfire.pdx.internal.PdxType;
import com.gemstone.gemfire.pdx.internal.PdxUnreadData;
import com.gemstone.gemfire.pdx.internal.TypeRegistry;
import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
@Category(IntegrationTest.class)
public class PdxDeleteFieldJUnitTest {
@Test
public void testPdxDeleteField() throws Exception {
String DS_NAME = "PdxDeleteFieldJUnitTestDiskStore";
Properties props = new Properties();
props.setProperty("mcast-port", "0");
props.setProperty("locators", "");
File f = new File(DS_NAME);
f.mkdir();
try {
Cache cache = (new CacheFactory(props)).setPdxPersistent(true).setPdxDiskStore(DS_NAME).create();
try {
{
DiskStoreFactory dsf = cache.createDiskStoreFactory();
dsf.setDiskDirs(new File[]{f});
dsf.create(DS_NAME);
}
RegionFactory<String, PdxValue> rf1 = cache.createRegionFactory(RegionShortcut.LOCAL_PERSISTENT);
rf1.setDiskStoreName(DS_NAME);
Region<String, PdxValue> region1 = rf1.create("region1");
PdxValue pdxValue = new PdxValue(1, 2L);
region1.put("key1", pdxValue);
byte[] pdxValueBytes = BlobHelper.serializeToBlob(pdxValue);
{
PdxValue deserializedPdxValue = (PdxValue) BlobHelper.deserializeBlob(pdxValueBytes);
assertEquals(1, deserializedPdxValue.value);
assertEquals(2L, deserializedPdxValue.fieldToDelete);
}
cache.close();
Collection<PdxType> types = DiskStoreImpl.pdxDeleteField(DS_NAME, new File[]{f}, PdxValue.class.getName(), "fieldToDelete");
assertEquals(1, types.size());
PdxType pt = types.iterator().next();
assertEquals(PdxValue.class.getName(), pt.getClassName());
assertEquals(null, pt.getPdxField("fieldToDelete"));
types = DiskStoreImpl.getPdxTypes(DS_NAME, new File[]{f});
assertEquals(1, types.size());
pt = types.iterator().next();
assertEquals(PdxValue.class.getName(), pt.getClassName());
assertEquals(true, pt.getHasDeletedField());
assertEquals(null, pt.getPdxField("fieldToDelete"));
cache = (new CacheFactory(props)).setPdxPersistent(true).setPdxDiskStore(DS_NAME).create();
{
DiskStoreFactory dsf = cache.createDiskStoreFactory();
dsf.setDiskDirs(new File[]{f});
dsf.create(DS_NAME);
PdxValue deserializedPdxValue = (PdxValue) BlobHelper.deserializeBlob(pdxValueBytes);
assertEquals(1, deserializedPdxValue.value);
assertEquals(0L, deserializedPdxValue.fieldToDelete);
}
} finally {
if (!cache.isClosed()) {
cache.close();
}
}
} finally {
FileUtil.delete(f);
}
}
@Test
public void testPdxFieldDelete() throws Exception {
Properties props = new Properties();
props.setProperty("mcast-port", "0");
props.setProperty("locators", "");
try {
Cache cache = (new CacheFactory(props)).create();
try {
PdxValue pdxValue = new PdxValue(1, 2L);
byte[] pdxValueBytes = BlobHelper.serializeToBlob(pdxValue);
{
PdxValue deserializedPdxValue = (PdxValue) BlobHelper.deserializeBlob(pdxValueBytes);
assertEquals(1, deserializedPdxValue.value);
assertEquals(2L, deserializedPdxValue.fieldToDelete);
}
PdxType pt;
DefaultQuery.setPdxReadSerialized(true); // force PdxInstance on deserialization
try {
PdxInstanceImpl pi = (PdxInstanceImpl) BlobHelper.deserializeBlob(pdxValueBytes);
pt = pi.getPdxType();
assertEquals(1, pi.getField("value"));
assertEquals(2L, pi.getField("fieldToDelete"));
} finally {
DefaultQuery.setPdxReadSerialized(false);
}
assertEquals(PdxValue.class.getName(), pt.getClassName());
PdxField field = pt.getPdxField("fieldToDelete");
pt.setHasDeletedField(true);
field.setDeleted(true);
assertEquals(null, pt.getPdxField("fieldToDelete"));
assertEquals(2, pt.getFieldCount());
{
PdxValue deserializedPdxValue = (PdxValue) BlobHelper.deserializeBlob(pdxValueBytes);
assertEquals(1, deserializedPdxValue.value);
// fieldToDelete should now be 0 (the default) instead of 2.
assertEquals(0L, deserializedPdxValue.fieldToDelete);
}
DefaultQuery.setPdxReadSerialized(true); // force PdxInstance on deserialization
try {
PdxInstance pi = (PdxInstance) BlobHelper.deserializeBlob(pdxValueBytes);
assertEquals(1, pi.getField("value"));
assertEquals(false, pi.hasField("fieldToDelete"));
assertEquals(null, pi.getField("fieldToDelete"));
assertSame(pt, ((PdxInstanceImpl)pi).getPdxType());
PdxValue deserializedPdxValue = (PdxValue) pi.getObject();
assertEquals(1, deserializedPdxValue.value);
assertEquals(0L, deserializedPdxValue.fieldToDelete);
} finally {
DefaultQuery.setPdxReadSerialized(false);
}
TypeRegistry tr = ((GemFireCacheImpl)cache).getPdxRegistry();
// Clear the local registry so we will regenerate a type for the same class
tr.testClearLocalTypeRegistry();
{
PdxInstanceFactory piFactory = cache.createPdxInstanceFactory(PdxValue.class.getName());
piFactory.writeInt("value", 1);
PdxInstance pi = piFactory.create();
assertEquals(1, pi.getField("value"));
assertEquals(null, pi.getField("fieldToDelete"));
PdxType pt2 = ((PdxInstanceImpl)pi).getPdxType();
assertEquals(null, pt2.getPdxField("fieldToDelete"));
assertEquals(1, pt2.getFieldCount());
}
} finally {
if (!cache.isClosed()) {
cache.close();
}
}
} finally {
}
}
public static class PdxValue implements PdxSerializable {
public int value;
public long fieldToDelete = -1L;
public PdxValue() {} // for deserialization
public PdxValue(int v, long lv) {
this.value = v;
this.fieldToDelete = lv;
}
@Override
public void toData(PdxWriter writer) {
writer.writeInt("value", this.value);
writer.writeLong("fieldToDelete", this.fieldToDelete);
}
@Override
public void fromData(PdxReader reader) {
this.value = reader.readInt("value");
if (reader.hasField("fieldToDelete")) {
this.fieldToDelete = reader.readLong("fieldToDelete");
} else {
this.fieldToDelete = 0L;
PdxUnreadData unread = (PdxUnreadData) reader.readUnreadFields();
assertEquals(true, unread.isEmpty());
}
}
}
}