X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-remoterpc-connector%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fremote%2Frpc%2Fregistry%2FRoutingTable.java;h=5159b96876d9e78bb4f2b85e08477b3ce842fb6a;hb=a2b838f96589b502578fa4e15cef2769f886a378;hp=90b069e58785aa95c50b36734aee9d5eaadffab4;hpb=00634259fd13ebc57f16ad63340e6472a2b6c6f2;p=controller.git diff --git a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/RoutingTable.java b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/RoutingTable.java index 90b069e587..5159b96876 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/RoutingTable.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/remote/rpc/registry/RoutingTable.java @@ -8,71 +8,129 @@ package org.opendaylight.controller.remote.rpc.registry; import akka.actor.ActorRef; +import akka.serialization.JavaSerializer; +import akka.serialization.Serialization; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableSet; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; import java.util.Optional; import java.util.Set; +import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeDataInput; +import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeDataOutput; +import org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeInputOutput; import org.opendaylight.controller.remote.rpc.registry.gossip.BucketData; -import org.opendaylight.controller.sal.connector.api.RpcRouter; -import org.opendaylight.controller.sal.connector.api.RpcRouter.RouteIdentifier; +import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier; -public class RoutingTable implements BucketData, Serializable { - private static final long serialVersionUID = 5592610415175278760L; +public final class RoutingTable implements BucketData, Serializable { + private static final class Proxy implements Externalizable { + private static final long serialVersionUID = 1L; - private final Map, Long> table; - private final ActorRef router; + @SuppressFBWarnings(value = "SE_BAD_FIELD", justification = "We deal with the field in serialization methods.") + private Collection rpcs; + private ActorRef rpcInvoker; - private RoutingTable(final ActorRef router, final Map, Long> table) { - this.router = Preconditions.checkNotNull(router); - this.table = Preconditions.checkNotNull(table); - } + // checkstyle flags the public modifier as redundant however it is explicitly needed for Java serialization to + // be able to create instances via reflection. + @SuppressWarnings("checkstyle:RedundantModifier") + public Proxy() { + // For Externalizable + } + + Proxy(final RoutingTable table) { + rpcs = table.getRoutes(); + rpcInvoker = table.getRpcInvoker(); + } + + @Override + public void writeExternal(final ObjectOutput out) throws IOException { + out.writeObject(Serialization.serializedActorPath(rpcInvoker)); + + final NormalizedNodeDataOutput nnout = NormalizedNodeInputOutput.newDataOutput(out); + nnout.writeInt(rpcs.size()); + for (DOMRpcIdentifier id : rpcs) { + nnout.writeSchemaPath(id.getType()); + nnout.writeYangInstanceIdentifier(id.getContextReference()); + } + } + + @Override + public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { + rpcInvoker = JavaSerializer.currentSystem().value().provider().resolveActorRef((String) in.readObject()); - RoutingTable(final ActorRef router) { - this(router, new HashMap<>()); + final NormalizedNodeDataInput nnin = NormalizedNodeInputOutput.newDataInput(in); + final int size = nnin.readInt(); + rpcs = new ArrayList<>(size); + for (int i = 0; i < size; ++i) { + rpcs.add(DOMRpcIdentifier.create(nnin.readSchemaPath(), nnin.readYangInstanceIdentifier())); + } + } + + private Object readResolve() { + return new RoutingTable(rpcInvoker, rpcs); + } } - @Override - public RoutingTable copy() { - return new RoutingTable(router, new HashMap<>(table)); + private static final long serialVersionUID = 1L; + + @SuppressFBWarnings(value = "SE_BAD_FIELD", justification = "We deal with the field in serialization methods.") + private final Set rpcs; + private final ActorRef rpcInvoker; + + RoutingTable(final ActorRef rpcInvoker, final Collection table) { + this.rpcInvoker = Preconditions.checkNotNull(rpcInvoker); + this.rpcs = ImmutableSet.copyOf(table); } @Override public Optional getWatchActor() { - return Optional.of(router); + return Optional.of(rpcInvoker); } - public Set> getRoutes() { - return table.keySet(); + public Set getRoutes() { + return rpcs; } - public void addRoute(final RpcRouter.RouteIdentifier routeId) { - table.put(routeId, System.currentTimeMillis()); + ActorRef getRpcInvoker() { + return rpcInvoker; } - public void removeRoute(final RpcRouter.RouteIdentifier routeId) { - table.remove(routeId); + RoutingTable addRpcs(final Collection toAdd) { + final Set newRpcs = new HashSet<>(rpcs); + newRpcs.addAll(toAdd); + return new RoutingTable(rpcInvoker, newRpcs); } - public boolean contains(final RpcRouter.RouteIdentifier routeId) { - return table.containsKey(routeId); + RoutingTable removeRpcs(final Collection toRemove) { + final Set newRpcs = new HashSet<>(rpcs); + newRpcs.removeAll(toRemove); + return new RoutingTable(rpcInvoker, newRpcs); } - public boolean isEmpty() { - return table.isEmpty(); + private Object writeReplace() { + return new Proxy(this); } - public int size() { - return table.size(); + @VisibleForTesting + boolean contains(final DOMRpcIdentifier routeId) { + return rpcs.contains(routeId); } - public ActorRef getRouter() { - return router; + @VisibleForTesting + int size() { + return rpcs.size(); } @Override public String toString() { - return "RoutingTable{" + "table=" + table + ", router=" + router + '}'; + return "RoutingTable{" + "rpcs=" + rpcs + ", rpcInvoker=" + rpcInvoker + '}'; } }