You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by bs...@apache.org on 2015/08/14 22:39:57 UTC

[08/50] [abbrv] incubator-geode git commit: GEODE-86: add a way to get the deserialized value to KeyValueOperationContext

GEODE-86: add a way to get the deserialized value to KeyValueOperationContext

KeyValueOperationContext now has a getDeserializedValue method that can be used
to get the operation value as a deserialized object.
The javadocs on getValue now explain that the result may be a serialized blob.
Unit test coverage has been added for PutOperationContext and GetOperationContextImpl
which are subclasses of KeyValueOperationContext.


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/298ff791
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/298ff791
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/298ff791

Branch: refs/heads/feature/GEODE-77
Commit: 298ff7911ffcc7b5f7b026de340b95804b7fab5a
Parents: 405daf5
Author: Darrel Schneider <ds...@pivotal.io>
Authored: Fri Jul 10 09:20:47 2015 -0700
Committer: Darrel Schneider <ds...@pivotal.io>
Committed: Wed Jul 29 10:42:58 2015 -0700

----------------------------------------------------------------------
 .../cache/operations/GetOperationContext.java   |   7 +-
 .../operations/KeyValueOperationContext.java    |  70 +++--
 .../internal/GetOperationContextImpl.java       |  16 +-
 .../PutOperationContextJUnitTest.java           | 248 +++++++++++++++++
 .../GetOperationContextImplJUnitTest.java       | 275 +++++++++++++++++++
 5 files changed, 586 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/298ff791/gemfire-core/src/main/java/com/gemstone/gemfire/cache/operations/GetOperationContext.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/operations/GetOperationContext.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/operations/GetOperationContext.java
index 700ae00..ceb95b6 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/operations/GetOperationContext.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/operations/GetOperationContext.java
@@ -55,9 +55,14 @@ public class GetOperationContext extends KeyValueOperationContext {
    * 
    * @return the result of get operation; null when the result is a serialized
    *         value in which case user should invoke {@link #getSerializedValue()}
+   *         or {@link #getDeserializedValue()}.
    */
   public Object getObject() {
-    return this.value;
+    if (super.getSerializedValue() != null) {
+      return null;
+    } else {
+      return super.getValue();
+    }
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/298ff791/gemfire-core/src/main/java/com/gemstone/gemfire/cache/operations/KeyValueOperationContext.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/operations/KeyValueOperationContext.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/operations/KeyValueOperationContext.java
index e0fefb9..4b1af3f 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/operations/KeyValueOperationContext.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/operations/KeyValueOperationContext.java
@@ -8,6 +8,10 @@
 
 package com.gemstone.gemfire.cache.operations;
 
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.SerializationException;
+import com.gemstone.gemfire.internal.cache.EntryEventImpl;
+
 
 /**
  * Encapsulates a region operation that requires both key and serialized value
@@ -22,14 +26,9 @@ public abstract class KeyValueOperationContext extends KeyOperationContext {
    * The value of the create/update operation.
    * @since 6.5
    */
-  protected Object value;
+  private Object value;
   
   /**
-   * The serialized value of the create/update operation.
-   */
-  private byte[] serializedValue;
-
-  /**
    * True when the serialized object is a normal object; false when it is a raw
    * byte array.
    */
@@ -80,26 +79,51 @@ public abstract class KeyValueOperationContext extends KeyOperationContext {
   /**
    * Get the serialized value for this operation.
    * 
-   * @return the serialized value for this operation.
+   * @return the serialized value for this operation or null if the value is not serialized
    */
   public byte[] getSerializedValue() {
-    return this.serializedValue;
+    if (isObject()) {
+      Object tmp = this.value;
+      if (tmp instanceof byte[]) {
+        return (byte[])tmp;
+      }
+    }
+    return null;
+  }
+  
+  /**
+   * Get the deserialized value for this operation.
+   * Note that if the value is serialized this method will attempt to deserialize it.
+   * If PDX read-serialized is set to true and the value was serialized with PDX
+   * then this method will return a PdxInstance.
+   * 
+   * @return the deserialized value for this operation
+   * @throws SerializationException if deserialization of the value fails
+   * @since Geode 1.0
+   */
+  public Object getDeserializedValue() throws SerializationException {
+    byte[] blob = getSerializedValue();
+    if (blob != null) {
+      return EntryEventImpl.deserialize(blob);
+    }
+    return this.value;
   }
 
   /**
    * Get the value for this operation.
+   * Note that if the value is serialized then a byte array
+   * will be returned that contains the serialized bytes.
+   * To figure out if the returned byte array contains serialized bytes
+   * or is the deserialized value call {@link #isObject()}.
+   * If you need to deserialize the serialized bytes use 
+   * {@link DataSerializer#readObject(java.io.DataInput)}
+   * or you can just call {@link #getDeserializedValue()}.
    * 
-   * @return the value for this operation.
+   * @return the value for this operation
    * @since 6.5
    */
   public Object getValue() {
-    
-    if (serializedValue != null) {
-      return serializedValue;
-    }
-    else {
-      return value;
-    }
+    return this.value;
   }
   
   /**
@@ -121,9 +145,7 @@ public abstract class KeyValueOperationContext extends KeyOperationContext {
    *                byte array
    */
   public void setSerializedValue(byte[] serializedValue, boolean isObject) {
-    this.serializedValue = serializedValue;
-    this.value = null;
-    this.isObject = isObject;
+    setValue(serializedValue, isObject);
   }
   
 
@@ -139,14 +161,8 @@ public abstract class KeyValueOperationContext extends KeyOperationContext {
    * @since 6.5
    */
   public void setValue(Object value, boolean isObject) {
-    if (value instanceof byte[]) {
-      setSerializedValue((byte[])value, isObject);
-    }
-    else {
-      this.serializedValue = null;
-      this.value = value;
-      this.isObject = isObject;
-    }
+    this.value = value;
+    this.isObject = isObject;
   }
   
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/298ff791/gemfire-core/src/main/java/com/gemstone/gemfire/cache/operations/internal/GetOperationContextImpl.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/operations/internal/GetOperationContextImpl.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/operations/internal/GetOperationContextImpl.java
index b8e13c6..7772c84 100644
--- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/operations/internal/GetOperationContextImpl.java
+++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/operations/internal/GetOperationContextImpl.java
@@ -1,5 +1,6 @@
 package com.gemstone.gemfire.cache.operations.internal;
 
+import com.gemstone.gemfire.SerializationException;
 import com.gemstone.gemfire.cache.operations.GetOperationContext;
 import com.gemstone.gemfire.internal.offheap.Releasable;
 import com.gemstone.gemfire.internal.offheap.SimpleMemoryAllocatorImpl.Chunk;
@@ -62,7 +63,7 @@ public class GetOperationContextImpl extends GetOperationContext implements Rele
   public byte[] getSerializedValue() {
     byte[] result = super.getSerializedValue();
     if (result == null) {
-      Object v = this.value;
+      Object v = super.getValue();
       if (v instanceof StoredObject) {
         checkForReleasedOffHeapValue(v);
         result = ((StoredObject) v).getValueAsHeapByteArray();
@@ -72,10 +73,21 @@ public class GetOperationContextImpl extends GetOperationContext implements Rele
   }
 
   @Override
+  public Object getDeserializedValue() throws SerializationException {
+    Object result = super.getDeserializedValue();
+    if (result instanceof StoredObject) {
+      checkForReleasedOffHeapValue(result);
+      result = ((StoredObject) result).getValueAsDeserializedHeapObject();
+    }
+    return result;
+  }
+
+  @Override
   public Object getValue() {
     Object result = super.getValue();
     if (result instanceof StoredObject) {
       checkForReleasedOffHeapValue(result);
+      // since they called getValue they don't care if it is serialized or deserialized so return it as serialized
       result = ((StoredObject) result).getValueAsHeapByteArray();
     }
     return result;
@@ -88,7 +100,7 @@ public class GetOperationContextImpl extends GetOperationContext implements Rele
     // our value (since this context did not retain it)
     // but we do make sure that any future attempt to access
     // the off-heap value fails.
-    if (this.value instanceof Chunk) {
+    if (super.getValue() instanceof Chunk) {
       this.released = true;
     }
   }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/298ff791/gemfire-core/src/test/java/com/gemstone/gemfire/cache/operations/PutOperationContextJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/cache/operations/PutOperationContextJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/cache/operations/PutOperationContextJUnitTest.java
new file mode 100644
index 0000000..32db7bd
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/cache/operations/PutOperationContextJUnitTest.java
@@ -0,0 +1,248 @@
+package com.gemstone.gemfire.cache.operations;
+
+import static org.junit.Assert.*;
+import static org.junit.matchers.JUnitMatchers.*;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.matchers.JUnitMatchers;
+import org.junit.rules.ExpectedException;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.pdx.PdxInstance;
+import com.gemstone.gemfire.pdx.PdxReader;
+import com.gemstone.gemfire.pdx.PdxSerializable;
+import com.gemstone.gemfire.pdx.PdxWriter;
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+
+@Category(UnitTest.class)
+public class PutOperationContextJUnitTest {
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+  
+  @BeforeClass
+  public static void setUpBeforeClass() throws Exception {
+  }
+
+  @AfterClass
+  public static void tearDownAfterClass() throws Exception {
+  }
+
+  @Before
+  public void setUp() throws Exception {
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  @Test
+  public void testGetSerializedValue() throws IOException {
+    {
+      byte[] byteArrayValue = new byte[]{1,2,3,4};
+      PutOperationContext poc = new PutOperationContext("key", byteArrayValue, false, PutOperationContext.CREATE, false);
+      Assert.assertFalse(poc.isObject());
+      Assert.assertNull("value is an actual byte array which is not a serialized blob", poc.getSerializedValue());
+    }
+
+    {
+      PutOperationContext poc = new PutOperationContext("key", null, true, PutOperationContext.CREATE, false);
+      Assert.assertTrue(poc.isObject());
+      Assert.assertNull("value is null which is not a serialized blob", poc.getSerializedValue());
+    }
+
+    {
+      PutOperationContext  poc = new PutOperationContext("key", "value", true, PutOperationContext.CREATE, false);
+      Assert.assertTrue(poc.isObject());
+      Assert.assertNull("value is a String which is not a serialized blob", poc.getSerializedValue());
+    }
+
+    {
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      DataOutputStream dos = new DataOutputStream(baos);
+      DataSerializer.writeObject("value", dos);
+      dos.close();
+      byte[] blob = baos.toByteArray();
+      PutOperationContext poc = new PutOperationContext("key", blob, true, PutOperationContext.CREATE, false);
+      Assert.assertTrue(poc.isObject());
+      Assert.assertArrayEquals(blob, poc.getSerializedValue());
+    }
+
+    {
+      // create a loner cache so that pdx serialization will work
+      Cache c = (new CacheFactory()).set("locators", "").set("mcast-port", "0").setPdxReadSerialized(true).create();
+      try {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        DataOutputStream dos = new DataOutputStream(baos);
+        DataSerializer.writeObject(new PdxValue("value"), dos);
+        dos.close();
+        byte[] blob = baos.toByteArray();
+        PutOperationContext poc = new PutOperationContext("key", blob, true, PutOperationContext.CREATE, false);
+        Assert.assertTrue(poc.isObject());
+        Assert.assertArrayEquals(blob, poc.getSerializedValue());
+      } finally {
+        c.close();
+      }
+    }
+  }
+
+  @Test
+  public void testGetDeserializedValue() throws IOException {
+    {
+      byte[] byteArrayValue = new byte[]{1,2,3,4};
+      PutOperationContext poc = new PutOperationContext("key", byteArrayValue, false, PutOperationContext.CREATE, false);
+      Assert.assertFalse(poc.isObject());
+      Assert.assertArrayEquals(byteArrayValue, (byte[]) poc.getDeserializedValue());
+    }
+
+    {
+      PutOperationContext poc = new PutOperationContext("key", null, true, PutOperationContext.CREATE, false);
+      Assert.assertTrue(poc.isObject());
+      Assert.assertEquals(null, poc.getDeserializedValue());
+    }
+
+    {
+      PutOperationContext  poc = new PutOperationContext("key", "value", true, PutOperationContext.CREATE, false);
+      Assert.assertTrue(poc.isObject());
+      Assert.assertEquals("value", poc.getDeserializedValue());
+    }
+
+    {
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      DataOutputStream dos = new DataOutputStream(baos);
+      DataSerializer.writeObject("value", dos);
+      dos.close();
+      byte[] blob = baos.toByteArray();
+      PutOperationContext poc = new PutOperationContext("key", blob, true, PutOperationContext.CREATE, false);
+      Assert.assertTrue(poc.isObject());
+      Assert.assertEquals("value", poc.getDeserializedValue());
+    }
+
+    {
+      // create a loner cache so that pdx serialization will work
+      Cache c = (new CacheFactory()).set("locators", "").set("mcast-port", "0").setPdxReadSerialized(true).create();
+      try {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        DataOutputStream dos = new DataOutputStream(baos);
+        DataSerializer.writeObject(new PdxValue("value"), dos);
+        dos.close();
+        byte[] blob = baos.toByteArray();
+        PutOperationContext poc = new PutOperationContext("key", blob, true, PutOperationContext.CREATE, false);
+        Assert.assertTrue(poc.isObject());
+        PdxInstance pi = (PdxInstance) poc.getDeserializedValue();
+        Assert.assertEquals("value", pi.getField("v"));
+      } finally {
+        c.close();
+      }
+    }
+  }
+
+  @Test
+  public void testGetValue() throws IOException {
+    {
+      byte[] byteArrayValue = new byte[]{1,2,3,4};
+      PutOperationContext poc = new PutOperationContext("key", byteArrayValue, false, PutOperationContext.CREATE, false);
+      Assert.assertFalse(poc.isObject());
+      Assert.assertArrayEquals(byteArrayValue, (byte[]) poc.getValue());
+    }
+
+    {
+      PutOperationContext poc = new PutOperationContext("key", null, true, PutOperationContext.CREATE, false);
+      Assert.assertTrue(poc.isObject());
+      Assert.assertEquals(null, poc.getValue());
+    }
+
+    {
+      PutOperationContext  poc = new PutOperationContext("key", "value", true, PutOperationContext.CREATE, false);
+      Assert.assertTrue(poc.isObject());
+      Assert.assertEquals("value", poc.getValue());
+    }
+
+    {
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      DataOutputStream dos = new DataOutputStream(baos);
+      DataSerializer.writeObject("value", dos);
+      dos.close();
+      byte[] blob = baos.toByteArray();
+      PutOperationContext poc = new PutOperationContext("key", blob, true, PutOperationContext.CREATE, false);
+      Assert.assertTrue(poc.isObject());
+      Assert.assertArrayEquals(blob, (byte[]) poc.getValue());
+    }
+
+    {
+      // create a loner cache so that pdx serialization will work
+      Cache c = (new CacheFactory()).set("locators", "").set("mcast-port", "0").setPdxReadSerialized(true).create();
+      try {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        DataOutputStream dos = new DataOutputStream(baos);
+        DataSerializer.writeObject(new PdxValue("value"), dos);
+        dos.close();
+        byte[] blob = baos.toByteArray();
+        PutOperationContext poc = new PutOperationContext("key", blob, true, PutOperationContext.CREATE, false);
+        Assert.assertTrue(poc.isObject());
+        Assert.assertArrayEquals(blob, (byte[]) poc.getValue());
+      } finally {
+        c.close();
+      }
+    }
+  }
+
+  public static class PdxValue implements PdxSerializable {
+    @Override
+    public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((v == null) ? 0 : v.hashCode());
+      return result;
+    }
+    @Override
+    public boolean equals(Object obj) {
+      if (this == obj)
+        return true;
+      if (obj == null)
+        return false;
+      if (getClass() != obj.getClass())
+        return false;
+      PdxValue other = (PdxValue) obj;
+      if (v == null) {
+        if (other.v != null)
+          return false;
+      } else if (!v.equals(other.v))
+        return false;
+      return true;
+    }
+
+    private String v;
+    
+    public PdxValue() {
+    }
+    
+    public PdxValue(String v) {
+      this.v = v;
+    }
+    @Override
+    public void toData(PdxWriter writer) {
+      writer.writeString("v", this.v);
+    }
+
+    @Override
+    public void fromData(PdxReader reader) {
+      this.v = reader.readString("v");
+    }
+    
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/298ff791/gemfire-core/src/test/java/com/gemstone/gemfire/cache/operations/internal/GetOperationContextImplJUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/cache/operations/internal/GetOperationContextImplJUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/cache/operations/internal/GetOperationContextImplJUnitTest.java
new file mode 100644
index 0000000..8607468
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/cache/operations/internal/GetOperationContextImplJUnitTest.java
@@ -0,0 +1,275 @@
+package com.gemstone.gemfire.cache.operations.internal;
+
+import static org.junit.Assert.*;
+import static org.junit.matchers.JUnitMatchers.*;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.matchers.JUnitMatchers;
+import org.junit.rules.ExpectedException;
+
+import com.gemstone.gemfire.DataSerializer;
+import com.gemstone.gemfire.cache.Cache;
+import com.gemstone.gemfire.cache.CacheFactory;
+import com.gemstone.gemfire.cache.operations.PutOperationContextJUnitTest;
+import com.gemstone.gemfire.pdx.PdxInstance;
+import com.gemstone.gemfire.pdx.PdxReader;
+import com.gemstone.gemfire.pdx.PdxSerializable;
+import com.gemstone.gemfire.pdx.PdxWriter;
+import com.gemstone.gemfire.test.junit.categories.UnitTest;
+
+@Category(UnitTest.class)
+public class GetOperationContextImplJUnitTest {
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+  
+  @BeforeClass
+  public static void setUpBeforeClass() throws Exception {
+  }
+
+  @AfterClass
+  public static void tearDownAfterClass() throws Exception {
+  }
+
+  @Before
+  public void setUp() throws Exception {
+  }
+
+  @After
+  public void tearDown() throws Exception {
+  }
+
+  @Test
+  public void testGetSerializedValue() throws IOException {
+    {
+      byte[] byteArrayValue = new byte[]{1,2,3,4};
+      GetOperationContextImpl poc = new GetOperationContextImpl("key", true);
+      poc.setObject(byteArrayValue, false);
+      Assert.assertFalse(poc.isObject());
+      Assert.assertNull("value is an actual byte array which is not a serialized blob", poc.getSerializedValue());
+    }
+
+    {
+      GetOperationContextImpl poc = new GetOperationContextImpl("key", true);
+      poc.setObject(null, true);
+      Assert.assertTrue(poc.isObject());
+      Assert.assertNull("value is null which is not a serialized blob", poc.getSerializedValue());
+    }
+
+    {
+      GetOperationContextImpl poc = new GetOperationContextImpl("key", true);
+      poc.setObject("value", true);
+      Assert.assertTrue(poc.isObject());
+      Assert.assertNull("value is a String which is not a serialized blob", poc.getSerializedValue());
+    }
+
+    {
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      DataOutputStream dos = new DataOutputStream(baos);
+      DataSerializer.writeObject("value", dos);
+      dos.close();
+      byte[] blob = baos.toByteArray();
+      GetOperationContextImpl poc = new GetOperationContextImpl("key", true);
+      poc.setObject(blob, true);
+      Assert.assertTrue(poc.isObject());
+      Assert.assertArrayEquals(blob, poc.getSerializedValue());
+    }
+
+    {
+      // create a loner cache so that pdx serialization will work
+      Cache c = (new CacheFactory()).set("locators", "").set("mcast-port", "0").setPdxReadSerialized(true).create();
+      try {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        DataOutputStream dos = new DataOutputStream(baos);
+        DataSerializer.writeObject(new PutOperationContextJUnitTest.PdxValue("value"), dos);
+        dos.close();
+        byte[] blob = baos.toByteArray();
+        GetOperationContextImpl poc = new GetOperationContextImpl("key", true);
+        poc.setObject(blob, true);
+        Assert.assertTrue(poc.isObject());
+        Assert.assertArrayEquals(blob, poc.getSerializedValue());
+      } finally {
+        c.close();
+      }
+    }
+  }
+
+  @Test
+  public void testGetDeserializedValue() throws IOException {
+    {
+      byte[] byteArrayValue = new byte[]{1,2,3,4};
+      GetOperationContextImpl poc = new GetOperationContextImpl("key", true);
+      poc.setObject(byteArrayValue, false);
+      Assert.assertFalse(poc.isObject());
+      Assert.assertArrayEquals(byteArrayValue, (byte[]) poc.getDeserializedValue());
+    }
+
+    {
+      GetOperationContextImpl poc = new GetOperationContextImpl("key", true);
+      poc.setObject(null, true);
+      Assert.assertTrue(poc.isObject());
+      Assert.assertEquals(null, poc.getDeserializedValue());
+    }
+
+    {
+      GetOperationContextImpl poc = new GetOperationContextImpl("key", true);
+      poc.setObject("value", true);
+      Assert.assertTrue(poc.isObject());
+      Assert.assertEquals("value", poc.getDeserializedValue());
+    }
+
+    {
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      DataOutputStream dos = new DataOutputStream(baos);
+      DataSerializer.writeObject("value", dos);
+      dos.close();
+      byte[] blob = baos.toByteArray();
+      GetOperationContextImpl poc = new GetOperationContextImpl("key", true);
+      poc.setObject(blob, true);
+      Assert.assertTrue(poc.isObject());
+      Assert.assertEquals("value", poc.getDeserializedValue());
+    }
+
+    {
+      // create a loner cache so that pdx serialization will work
+      Cache c = (new CacheFactory()).set("locators", "").set("mcast-port", "0").setPdxReadSerialized(true).create();
+      try {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        DataOutputStream dos = new DataOutputStream(baos);
+        DataSerializer.writeObject(new PutOperationContextJUnitTest.PdxValue("value"), dos);
+        dos.close();
+        byte[] blob = baos.toByteArray();
+        GetOperationContextImpl poc = new GetOperationContextImpl("key", true);
+        poc.setObject(blob, true);
+        Assert.assertTrue(poc.isObject());
+        PdxInstance pi = (PdxInstance) poc.getDeserializedValue();
+        Assert.assertEquals("value", pi.getField("v"));
+      } finally {
+        c.close();
+      }
+    }
+  }
+
+  @Test
+  public void testGetValue() throws IOException {
+    {
+      byte[] byteArrayValue = new byte[]{1,2,3,4};
+      GetOperationContextImpl poc = new GetOperationContextImpl("key", true);
+      poc.setObject(byteArrayValue, false);
+      Assert.assertFalse(poc.isObject());
+      Assert.assertArrayEquals(byteArrayValue, (byte[]) poc.getValue());
+    }
+
+    {
+      GetOperationContextImpl poc = new GetOperationContextImpl("key", true);
+      poc.setObject(null, true);
+      Assert.assertTrue(poc.isObject());
+      Assert.assertEquals(null, poc.getValue());
+    }
+
+    {
+      GetOperationContextImpl poc = new GetOperationContextImpl("key", true);
+      poc.setObject("value", true);
+      Assert.assertTrue(poc.isObject());
+      Assert.assertEquals("value", poc.getValue());
+    }
+
+    {
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      DataOutputStream dos = new DataOutputStream(baos);
+      DataSerializer.writeObject("value", dos);
+      dos.close();
+      byte[] blob = baos.toByteArray();
+      GetOperationContextImpl poc = new GetOperationContextImpl("key", true);
+      poc.setObject(blob, true);
+      Assert.assertTrue(poc.isObject());
+      Assert.assertArrayEquals(blob, (byte[]) poc.getValue());
+    }
+
+    {
+      // create a loner cache so that pdx serialization will work
+      Cache c = (new CacheFactory()).set("locators", "").set("mcast-port", "0").setPdxReadSerialized(true).create();
+      try {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        DataOutputStream dos = new DataOutputStream(baos);
+        DataSerializer.writeObject(new PutOperationContextJUnitTest.PdxValue("value"), dos);
+        dos.close();
+        byte[] blob = baos.toByteArray();
+        GetOperationContextImpl poc = new GetOperationContextImpl("key", true);
+        poc.setObject(blob, true);
+        Assert.assertTrue(poc.isObject());
+        Assert.assertArrayEquals(blob, (byte[]) poc.getValue());
+      } finally {
+        c.close();
+      }
+    }
+  }
+
+  @Test
+  public void testGetObject() throws IOException {
+    {
+      byte[] byteArrayValue = new byte[]{1,2,3,4};
+      GetOperationContextImpl poc = new GetOperationContextImpl("key", true);
+      poc.setObject(byteArrayValue, false);
+      Assert.assertFalse(poc.isObject());
+      Assert.assertArrayEquals(byteArrayValue, (byte[]) poc.getObject());
+    }
+
+    {
+      GetOperationContextImpl poc = new GetOperationContextImpl("key", true);
+      poc.setObject(null, true);
+      Assert.assertTrue(poc.isObject());
+      Assert.assertEquals(null, poc.getObject());
+    }
+
+    {
+      GetOperationContextImpl poc = new GetOperationContextImpl("key", true);
+      poc.setObject("value", true);
+      Assert.assertTrue(poc.isObject());
+      Assert.assertEquals("value", poc.getObject());
+    }
+
+    {
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      DataOutputStream dos = new DataOutputStream(baos);
+      DataSerializer.writeObject("value", dos);
+      dos.close();
+      byte[] blob = baos.toByteArray();
+      GetOperationContextImpl poc = new GetOperationContextImpl("key", true);
+      poc.setObject(blob, true);
+      Assert.assertTrue(poc.isObject());
+      Assert.assertNull("value is a serialized blob which is not an Object", poc.getObject());
+    }
+
+    {
+      // create a loner cache so that pdx serialization will work
+      Cache c = (new CacheFactory()).set("locators", "").set("mcast-port", "0").setPdxReadSerialized(true).create();
+      try {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        DataOutputStream dos = new DataOutputStream(baos);
+        DataSerializer.writeObject(new PutOperationContextJUnitTest.PdxValue("value"), dos);
+        dos.close();
+        byte[] blob = baos.toByteArray();
+        GetOperationContextImpl poc = new GetOperationContextImpl("key", true);
+        poc.setObject(blob, true);
+        Assert.assertTrue(poc.isObject());
+        Assert.assertNull("value is a serialized blob which is not an Object", poc.getObject());
+      } finally {
+        c.close();
+      }
+    }
+  }
+  // @TODO OFFHEAP: add coverage of "release" and the gettors methods with StoreObject and off-heap Chunk values
+}