org.opendaylight.controller.remote.rpc.registry.RoutingTable Maven / Gradle / Ivy
/*
* Copyright (c) 2014 Cisco Systems, 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.remote.rpc.registry;
import akka.actor.ActorRef;
import akka.serialization.JavaSerializer;
import akka.serialization.Serialization;
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.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
import org.opendaylight.yangtools.yang.data.codec.binfmt.NormalizedNodeDataInput;
import org.opendaylight.yangtools.yang.data.codec.binfmt.NormalizedNodeDataOutput;
import org.opendaylight.yangtools.yang.data.codec.binfmt.NormalizedNodeStreamVersion;
import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
public final class RoutingTable extends AbstractRoutingTable {
private static final class Proxy implements Externalizable {
private static final long serialVersionUID = 1L;
@SuppressFBWarnings(value = "SE_BAD_FIELD", justification = "We deal with the field in serialization methods.")
private Collection rpcs;
private ActorRef opsInvoker;
// 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.getItems();
opsInvoker = table.getInvoker();
}
@Override
public void writeExternal(final ObjectOutput out) throws IOException {
out.writeObject(Serialization.serializedActorPath(opsInvoker));
try (NormalizedNodeDataOutput nnout = NormalizedNodeStreamVersion.current().newDataOutput(out)) {
nnout.writeInt(rpcs.size());
for (DOMRpcIdentifier id : rpcs) {
// TODO: we should be able to get by with just a QName
nnout.writeSchemaNodeIdentifier(Absolute.of(id.getType()));
nnout.writeYangInstanceIdentifier(id.getContextReference());
}
}
}
@Override
public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
opsInvoker = JavaSerializer.currentSystem().value().provider().resolveActorRef((String) in.readObject());
final NormalizedNodeDataInput nnin = NormalizedNodeDataInput.newDataInput(in);
final int size = nnin.readInt();
rpcs = new ArrayList<>(size);
for (int i = 0; i < size; ++i) {
// TODO: we should be able to get by with just a QName
rpcs.add(DOMRpcIdentifier.create(nnin.readSchemaNodeIdentifier().firstNodeIdentifier(),
nnin.readYangInstanceIdentifier()));
}
}
private Object readResolve() {
return new RoutingTable(opsInvoker, rpcs);
}
}
private static final long serialVersionUID = 1L;
RoutingTable(final ActorRef invoker, final Collection table) {
super(invoker, table);
}
RoutingTable addRpcs(final Collection toAdd) {
final Set newRpcs = new HashSet<>(getItems());
newRpcs.addAll(toAdd);
return new RoutingTable(getInvoker(), newRpcs);
}
RoutingTable removeRpcs(final Collection toRemove) {
final Set newRpcs = new HashSet<>(getItems());
newRpcs.removeAll(toRemove);
return new RoutingTable(getInvoker(), newRpcs);
}
@Override
Object writeReplace() {
return new Proxy(this);
}
}