Add specific serializer for SimpleReplicatedLogEntry
[controller.git] / opendaylight / md-sal / sal-akka-raft / src / main / java / org / opendaylight / controller / cluster / raft / persisted / SimpleReplicatedLogEntrySerializer.java
diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/persisted/SimpleReplicatedLogEntrySerializer.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/persisted/SimpleReplicatedLogEntrySerializer.java
new file mode 100644 (file)
index 0000000..ca6e6df
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2018 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.cluster.raft.persisted;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Objects.requireNonNull;
+
+import akka.actor.ExtendedActorSystem;
+import akka.serialization.JSerializer;
+import akka.util.ClassLoaderObjectInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import org.apache.commons.lang3.SerializationUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Specialized serializer for {@link SimpleReplicatedLogEntry} that optimizes serialization.
+ *
+ * @author Thomas Pantelis
+ */
+public class SimpleReplicatedLogEntrySerializer extends JSerializer {
+    private static final Logger LOG = LoggerFactory.getLogger(SimpleReplicatedLogEntrySerializer.class);
+
+    private final ExtendedActorSystem system;
+
+    public SimpleReplicatedLogEntrySerializer(final ExtendedActorSystem system) {
+        this.system = requireNonNull(system);
+    }
+
+    @Override
+    public int identifier() {
+        return 97439500;
+    }
+
+    @Override
+    public boolean includeManifest() {
+        return false;
+    }
+
+    @Override
+    public byte[] toBinary(Object obj) {
+        checkArgument(obj instanceof SimpleReplicatedLogEntry, "Unsupported object type %s", obj.getClass());
+
+        SimpleReplicatedLogEntry replicatedLogEntry = (SimpleReplicatedLogEntry)obj;
+        final int estimatedSerializedSize = replicatedLogEntry.estimatedSerializedSize();
+
+        final ByteArrayOutputStream bos = new ByteArrayOutputStream(estimatedSerializedSize);
+        SerializationUtils.serialize(replicatedLogEntry, bos);
+        final byte[] bytes = bos.toByteArray();
+
+        LOG.debug("Estimated serialized size {}, data size {} for payload: {}. Actual serialized size: {}",
+            estimatedSerializedSize, replicatedLogEntry.getData().size(), replicatedLogEntry.getData(), bytes.length);
+
+        return bytes;
+    }
+
+    @Override
+    public Object fromBinaryJava(byte[] bytes, Class<?> manifest) {
+        try (ClassLoaderObjectInputStream is = new ClassLoaderObjectInputStream(system.dynamicAccess().classLoader(),
+                new ByteArrayInputStream(bytes))) {
+            return is.readObject();
+        } catch (IOException | ClassNotFoundException e) {
+            throw new IllegalStateException("Failed to deserialize object", e);
+        }
+    }
+}