You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2016/12/06 08:40:21 UTC
[24/50] ignite git commit: IGNITE-4026: Fixed
BinaryObjectBuilder.build() can fail if one of the fields is Externalizable,
enum from binary object. This closes #1281. This closes #1289.
IGNITE-4026: Fixed BinaryObjectBuilder.build() can fail if one of the fields is Externalizable, enum from binary object. This closes #1281. This closes #1289.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/0b7c62d2
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/0b7c62d2
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/0b7c62d2
Branch: refs/heads/ignite-comm-balance-master
Commit: 0b7c62d2939854223653d832a616ddb61211bf22
Parents: d1cc292
Author: dkarachentsev <dk...@gridgain.com>
Authored: Mon Nov 28 11:30:14 2016 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Mon Nov 28 11:30:14 2016 +0300
----------------------------------------------------------------------
.../internal/binary/GridBinaryMarshaller.java | 2 +-
.../binary/builder/BinaryBuilderReader.java | 11 ++
.../binary/builder/BinaryBuilderSerializer.java | 4 +
.../binary/builder/BinaryObjectBuilderImpl.java | 10 ++
.../BinaryObjectBuilderAdditionalSelfTest.java | 157 ++++++++++++++++++-
5 files changed, 181 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/0b7c62d2/modules/core/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java
index ad63521..624fa33 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/GridBinaryMarshaller.java
@@ -43,7 +43,7 @@ public class GridBinaryMarshaller {
private static final ThreadLocal<BinaryContext> BINARY_CTX = new ThreadLocal<>();
/** */
- static final byte OPTM_MARSH = -2;
+ public static final byte OPTM_MARSH = -2;
/** */
public static final byte BYTE = 1;
http://git-wip-us.apache.org/repos/asf/ignite/blob/0b7c62d2/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java
index 347fb2b..baaabd6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderReader.java
@@ -33,6 +33,7 @@ import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
+import org.apache.ignite.internal.util.typedef.internal.U;
import static java.nio.charset.StandardCharsets.UTF_8;
@@ -757,6 +758,16 @@ public class BinaryBuilderReader implements BinaryPositionReadable {
return new BinaryPlainBinaryObject(binaryObj);
}
+ case GridBinaryMarshaller.OPTM_MARSH: {
+ final BinaryHeapInputStream bin = BinaryHeapInputStream.create(arr, pos);
+
+ final Object obj = BinaryUtils.doReadOptimized(bin, ctx, U.resolveClassLoader(ctx.configuration()));
+
+ pos = bin.position();
+
+ return obj;
+ }
+
default:
throw new BinaryObjectException("Invalid flag value: " + type);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/0b7c62d2/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java
index b296437..6974176 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryBuilderSerializer.java
@@ -116,8 +116,12 @@ class BinaryBuilderSerializer {
String typeName = writer.context().userTypeName(clsName);
BinaryMetadata meta = new BinaryMetadata(typeId, typeName, null, null, null, true);
+
writer.context().updateMetadata(typeId, meta);
+ // Need register class for marshaller to be able to deserialize enum value.
+ writer.context().descriptorForClass(val.getClass(), false);
+
writer.writeByte(GridBinaryMarshaller.ENUM);
writer.writeInt(typeId);
writer.writeInt(((Enum)val).ordinal());
http://git-wip-us.apache.org/repos/asf/ignite/blob/0b7c62d2/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java
index ddd2423..a847d04 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/binary/builder/BinaryObjectBuilderImpl.java
@@ -22,6 +22,7 @@ import org.apache.ignite.binary.BinaryObject;
import org.apache.ignite.binary.BinaryObjectBuilder;
import org.apache.ignite.binary.BinaryObjectException;
import org.apache.ignite.binary.BinaryType;
+import org.apache.ignite.internal.binary.BinaryEnumObjectImpl;
import org.apache.ignite.internal.binary.BinaryMetadata;
import org.apache.ignite.internal.binary.BinaryObjectImpl;
import org.apache.ignite.internal.binary.BinaryWriterExImpl;
@@ -391,6 +392,15 @@ public class BinaryObjectBuilderImpl implements BinaryObjectBuilder {
if (((BinaryValueWithType)newVal).value() == null)
nullFieldVal = true;
}
+ // Detect Enum and Enum array type.
+ else if (newVal instanceof BinaryEnumObjectImpl)
+ newFldTypeId = GridBinaryMarshaller.ENUM;
+ else if (newVal.getClass().isArray() && newVal.getClass().getComponentType() == BinaryObject.class) {
+ BinaryObject[] arr = (BinaryObject[])newVal;
+
+ newFldTypeId = arr.length > 0 && arr[0] instanceof BinaryEnumObjectImpl ?
+ GridBinaryMarshaller.ENUM_ARR : GridBinaryMarshaller.OBJ_ARR;
+ }
else
newFldTypeId = BinaryUtils.typeByClass(newVal.getClass());
http://git-wip-us.apache.org/repos/asf/ignite/blob/0b7c62d2/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryObjectBuilderAdditionalSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryObjectBuilderAdditionalSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryObjectBuilderAdditionalSelfTest.java
index 24806cb..507aa6b 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryObjectBuilderAdditionalSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/binary/BinaryObjectBuilderAdditionalSelfTest.java
@@ -21,6 +21,10 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
@@ -1423,11 +1427,19 @@ public class BinaryObjectBuilderAdditionalSelfTest extends GridCommonAbstractTes
* @return Wrapper.
*/
private BinaryObjectBuilderImpl newWrapper(Class<?> aCls) {
+ return newWrapper(aCls.getName());
+ }
+
+ /**
+ * @param typeName Type name.
+ * @return Wrapper.
+ */
+ private BinaryObjectBuilderImpl newWrapper(String typeName) {
CacheObjectBinaryProcessorImpl processor = (CacheObjectBinaryProcessorImpl)(
(IgniteBinaryImpl)binaries()).processor();
- return new BinaryObjectBuilderImpl(processor.binaryContext(), processor.typeId(aCls.getName()),
- processor.binaryContext().userTypeName(aCls.getName()));
+ return new BinaryObjectBuilderImpl(processor.binaryContext(), processor.typeId(typeName),
+ processor.binaryContext().userTypeName(typeName));
}
/**
@@ -1508,4 +1520,145 @@ public class BinaryObjectBuilderAdditionalSelfTest extends GridCommonAbstractTes
assert OBJ.equals(binaryObj.type().fieldTypeName("asSetHint"));
assert OBJ.equals(binaryObj.type().fieldTypeName("asMapHint"));
}
+
+ /**
+ * Checks that externalizable value is correctly serialized/deserialized.
+ *
+ * @throws Exception If failed.
+ */
+ public void testBuilderExternalizable() throws Exception {
+ BinaryObjectBuilder builder = newWrapper("TestType");
+
+ final TestObjectExternalizable exp = new TestObjectExternalizable("test");
+ final TestObjectExternalizable[] expArr = new TestObjectExternalizable[]{
+ new TestObjectExternalizable("test1"), new TestObjectExternalizable("test2")};
+
+ BinaryObject extObj = builder.setField("extVal", exp).setField("extArr", expArr).build();
+
+ assertEquals(exp, extObj.field("extVal"));
+ Assert.assertArrayEquals(expArr, (Object[])extObj.field("extArr"));
+
+ builder = extObj.toBuilder();
+
+ extObj = builder.setField("intVal", 10).build();
+
+ assertEquals(exp, extObj.field("extVal"));
+ Assert.assertArrayEquals(expArr, (Object[])extObj.field("extArr"));
+ assertEquals(Integer.valueOf(10), extObj.field("intVal"));
+
+ builder = extObj.toBuilder();
+
+ extObj = builder.setField("strVal", "some string").build();
+
+ assertEquals(exp, extObj.field("extVal"));
+ Assert.assertArrayEquals(expArr, (Object[])extObj.field("extArr"));
+ assertEquals(Integer.valueOf(10), extObj.field("intVal"));
+ assertEquals("some string", extObj.field("strVal"));
+ }
+
+ /**
+ * Checks correct serialization/deserialization of enums in builder.
+ *
+ * @throws Exception If failed.
+ */
+ public void testEnum() throws Exception {
+ BinaryObjectBuilder builder = newWrapper("TestType");
+
+ final TestEnum exp = TestEnum.A;
+ final TestEnum[] expArr = {TestEnum.A, TestEnum.B};
+
+ BinaryObject enumObj = builder.setField("testEnum", exp).setField("testEnumArr", expArr).build();
+
+ assertEquals(exp, ((BinaryObject)enumObj.field("testEnum")).deserialize());
+ Assert.assertArrayEquals(expArr, (Object[])deserializeEnumBinaryArray(enumObj.field("testEnumArr")));
+
+ builder = newWrapper(enumObj.type().typeName());
+
+ enumObj = builder.setField("testEnum", (Object)enumObj.field("testEnum"))
+ .setField("testEnumArr", (Object)enumObj.field("testEnumArr")).build();
+
+ assertEquals(exp, ((BinaryObject)enumObj.field("testEnum")).deserialize());
+ Assert.assertArrayEquals(expArr, (Object[])deserializeEnumBinaryArray(enumObj.field("testEnumArr")));
+ }
+
+ /**
+ * @param obj BinaryObject array.
+ * @return Deserialized enums.
+ */
+ private TestEnum[] deserializeEnumBinaryArray(Object obj) {
+ Object[] arr = (Object[])obj;
+
+ final TestEnum[] res = new TestEnum[arr.length];
+
+ for (int i = 0; i < arr.length; i++)
+ res[i] = ((BinaryObject)arr[i]).deserialize();
+
+ return res;
+ }
+
+ /**
+ *
+ */
+ private static class TestObjectExternalizable implements Externalizable {
+ /** */
+ private String val;
+
+ /**
+ *
+ */
+ public TestObjectExternalizable() {
+ }
+
+ /**
+ * @param val Value.
+ */
+ public TestObjectExternalizable(final String val) {
+ this.val = val;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void writeExternal(final ObjectOutput out) throws IOException {
+ out.writeUTF(val);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
+ val = in.readUTF();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(final Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ final TestObjectExternalizable that = (TestObjectExternalizable)o;
+
+ return val != null ? val.equals(that.val) : that.val == null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ return val != null ? val.hashCode() : 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return "TestObjectExternalizable{" +
+ "val='" + val + '\'' +
+ '}';
+ }
+ }
+
+ /**
+ *
+ */
+ private enum TestEnum {
+ /** */
+ A,
+
+ /** */
+ B
+ }
}