From: Tom Pantelis Date: Wed, 24 May 2017 12:13:34 +0000 (-0400) Subject: Bug 5740: Change TimeoutNow and Shutdown to externalizable proxy X-Git-Tag: release/nitrogen~184 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=6751227ff9443018d75e3a99da5693230d23d82b Bug 5740: Change TimeoutNow and Shutdown to externalizable proxy Change-Id: I3b2289c258ffab288901b5cbf4e5032bc143dfc7 Signed-off-by: Tom Pantelis --- diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/EmptyExternalizableProxy.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/EmptyExternalizableProxy.java new file mode 100644 index 0000000000..4f1fe37667 --- /dev/null +++ b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/EmptyExternalizableProxy.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2017 Inocybe Technologies 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.base.messages; + +import com.google.common.base.Preconditions; +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; + +/** + * Abstract base that implements Externalizable with no-op methods that is intended for classes that use the + * externalizable proxy pattern but have no data to serialize and read-resolve to a static instance. + * + * @author Thomas Pantelis + */ +public abstract class EmptyExternalizableProxy implements Externalizable { + private static final long serialVersionUID = 1L; + + private final Object readResolveTo; + + protected EmptyExternalizableProxy(Object readResolveTo) { + this.readResolveTo = Preconditions.checkNotNull(readResolveTo); + } + + @Override + public void writeExternal(ObjectOutput out) throws IOException { + } + + @Override + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + } + + protected Object readResolve() { + return readResolveTo; + } +} diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/TimeoutNow.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/TimeoutNow.java index 5a753c24c9..b85d8b7008 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/TimeoutNow.java +++ b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/base/messages/TimeoutNow.java @@ -22,7 +22,18 @@ public final class TimeoutNow implements Serializable { // Hidden on purpose } - private Object readResolve() { - return INSTANCE; + private Object writeReplace() { + return new Proxy(); + } + + private static class Proxy extends EmptyExternalizableProxy { + private static final long serialVersionUID = 1L; + + // checkstyle flags the public modifier as redundant which really doesn't make sense since it clearly isn't + // redundant. It is explicitly needed for Java serialization to be able to create instances via reflection. + @SuppressWarnings("checkstyle:RedundantModifier") + public Proxy() { + super(INSTANCE); + } } } diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/client/messages/Shutdown.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/client/messages/Shutdown.java index 4261baef2f..22acc41e01 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/client/messages/Shutdown.java +++ b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/client/messages/Shutdown.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.cluster.raft.client.messages; import java.io.Serializable; +import org.opendaylight.controller.cluster.raft.base.messages.EmptyExternalizableProxy; /** * Message sent to a raft actor to shutdown gracefully. If it's the leader it will transfer leadership to a @@ -24,7 +25,18 @@ public final class Shutdown implements Serializable { // Hidden on purpose } - private Object readResolve() { - return INSTANCE; + private Object writeReplace() { + return new Proxy(); + } + + private static class Proxy extends EmptyExternalizableProxy { + private static final long serialVersionUID = 1L; + + // checkstyle flags the public modifier as redundant which really doesn't make sense since it clearly isn't + // redundant. It is explicitly needed for Java serialization to be able to create instances via reflection. + @SuppressWarnings("checkstyle:RedundantModifier") + public Proxy() { + super(INSTANCE); + } } } diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/base/messages/TimeoutNowTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/base/messages/TimeoutNowTest.java new file mode 100644 index 0000000000..26cdb22d8c --- /dev/null +++ b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/base/messages/TimeoutNowTest.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2017 Inocybe Technologies 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.base.messages; + +import static org.junit.Assert.assertSame; + +import org.apache.commons.lang.SerializationUtils; +import org.junit.Test; + +/** + * Unit tests for TimeoutNow. + * + * @author Thomas Pantelis + */ +public class TimeoutNowTest { + + @Test + public void test() { + TimeoutNow cloned = (TimeoutNow) SerializationUtils.clone(TimeoutNow.INSTANCE); + assertSame("Cloned instance", TimeoutNow.INSTANCE, cloned); + } +} diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/client/messages/ShutdownTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/client/messages/ShutdownTest.java new file mode 100644 index 0000000000..81b9fbbb86 --- /dev/null +++ b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/client/messages/ShutdownTest.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2017 Inocybe Technologies 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.client.messages; + +import static org.junit.Assert.assertSame; + +import org.apache.commons.lang.SerializationUtils; +import org.junit.Test; + +/** + * Unit tests for Shutdown. + * + * @author Thomas Pantelis + */ +public class ShutdownTest { + + @Test + public void test() { + Shutdown cloned = (Shutdown) SerializationUtils.clone(Shutdown.INSTANCE); + assertSame("Cloned instance", Shutdown.INSTANCE, cloned); + } +}