/** * Ensure that a value can be serialized and deserialized using Kryo. * * <p>When a Stellar function is used in a Storm topology there are cases when the result * needs to be serializable, like when using the Profiler. Storm can use either Kryo or * basic Java serialization. It is highly recommended that all Stellar functions return a * result that is Kryo serializable to allow for the broadest possible use of the function. * * @param value The value to validate. */ private static void ensureKryoSerializable(Object value, String expression) { String msg = String.format("Expression result is not Kryo serializable. It is highly recommended for all " + "functions to return a result that is Kryo serializable to allow for their broadest possible use. " + "expr=%s, value=%s", expression, value); byte[] raw = SerDeUtils.toBytes(value); Object actual = SerDeUtils.fromBytes(raw, Object.class); Assert.assertEquals(msg, value, actual); }
/** * Serializes the given Object into bytes. * */ @Override public byte[] apply(Object o) { return toBytes(o); } }
/** * Deserializes the given bytes. * * @param bytes the function argument * @return the function result */ @Override public T apply(byte[] bytes) { return fromBytes(bytes, clazz); } }
@Override public byte[] apply(T t) { return SerDeUtils.toBytes(t); } }
@Override public void read(Kryo kryo, Input input) { int numVariableMappings = input.readShort(); variableMappings = new ArrayList<>(numVariableMappings); for(int i = 0;i < numVariableMappings;++i) { int size = input.readInt(); if(size > 0) { byte[] bytes = input.readBytes(size); Map m = SerDeUtils.fromBytes(bytes, Map.class); variableMappings.add(m); } } } }
@Override public void write(Kryo kryo, Output output) { int numVariableMappings = variableMappings.isEmpty()?0:variableMappings.size(); output.writeShort(numVariableMappings); for(Map m : variableMappings) { byte[] b = m == null?new byte[]{}:SerDeUtils.toBytes(m); output.writeInt(b.length); if(b.length > 0) { output.writeBytes(b); } } }
data = (byte[])o; } else { data = SerDeUtils.toBytes(o);
@Test public void testFloat() { final Float expected = 2.2F; byte[] raw = SerDeUtils.toBytes(expected); { float actual = SerDeUtils.fromBytes(raw, Float.class); assertEquals(expected, actual, 0.01); } { float actual = (float) SerDeUtils.fromBytes(raw, Object.class); assertEquals(expected, actual, 0.01); } }
@Test public void testDouble() { final double expected = 2.0; byte[] raw = SerDeUtils.toBytes(expected); { double actual = SerDeUtils.fromBytes(raw, Double.class); assertEquals(expected, actual, 0.01); } { double actual = (double) SerDeUtils.fromBytes(raw, Object.class); assertEquals(expected, actual, 0.01); } }
@Test @SuppressWarnings("unchecked") public void testBloomFilter() { final BloomFilter<Object> expected = new BloomFilter<>(new BloomFilter.DefaultSerializer<>(), 10000, 0.01); expected.add("foo"); expected.add("bar"); byte[] raw = SerDeUtils.toBytes(expected); BloomFilter<Object> actual = (BloomFilter) SerDeUtils.fromBytes(raw, Object.class); Assert.assertTrue(actual.mightContain("foo")); Assert.assertFalse(actual.mightContain("timothy")); assertEquals(expected, actual); }