--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. 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.datastore.persisted;
+
+import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.io.ByteStreams;
+import java.io.IOException;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+import org.opendaylight.controller.cluster.datastore.persisted.AbstractIdentifiablePayload.SerialForm;
+
+/**
+ * Serialization proxy for {@link AbortTransactionPayload}.
+ */
+final class AT implements SerialForm {
+ private static final long serialVersionUID = 1L;
+
+ private TransactionIdentifier identifier;
+ private byte[] bytes;
+
+ @SuppressWarnings("checkstyle:RedundantModifier")
+ public AT() {
+ // For Externalizable
+ }
+
+ AT(final byte[] bytes) {
+ this.bytes = requireNonNull(bytes);
+ }
+
+ @Override
+ public byte[] bytes() {
+ return bytes;
+ }
+
+ @Override
+ public void readExternal(final byte[] newBytes) throws IOException {
+ bytes = requireNonNull(newBytes);
+ identifier = verifyNotNull(TransactionIdentifier.readFrom(ByteStreams.newDataInput(newBytes)));
+ }
+
+ @Override
+ public Object readResolve() {
+ return new AbortTransactionPayload(identifier, bytes);
+ }
+}
*/
public abstract class AbstractIdentifiablePayload<T extends Identifier> extends IdentifiablePayload<T>
implements Serializable {
- protected abstract static class AbstractProxy<T extends Identifier> implements Externalizable {
+ /**
+ * An {@link Externalizable} with default implementations we expect our implementations to comply with. On-wire
+ * serialization format is defined by {@link #bytes()}.
+ */
+ protected interface SerialForm extends Externalizable {
+ /**
+ * Return the serial form of this object contents, corresponding to
+ * {@link AbstractIdentifiablePayload#serialized}.
+ *
+ * @return Serialized form
+ */
+ byte[] bytes();
+
+ /**
+ * Resolve this proxy to an actual {@link AbstractIdentifiablePayload}.
+ *
+ * @return A payload.
+ */
+ Object readResolve();
+
+ /**
+ * Restore state from specified serialized form.
+ *
+ * @param newBytes Serialized form, as returned by {@link #bytes()}
+ * @throws IOException when a deserialization problem occurs
+ */
+ void readExternal(byte[] newBytes) throws IOException;
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>
+ * The default implementation is canonical and should never be overridden.
+ */
+ @Override
+ default void readExternal(final ObjectInput in) throws IOException {
+ final var bytes = new byte[in.readInt()];
+ in.readFully(bytes);
+ readExternal(bytes);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>
+ * The default implementation is canonical and should never be overridden.
+ */
+ @Override
+ default void writeExternal(final ObjectOutput out) throws IOException {
+ final var bytes = bytes();
+ out.writeInt(bytes.length);
+ out.write(bytes);
+ }
+ }
+
+ protected abstract static class AbstractProxy<T extends Identifier> implements SerialForm {
private static final long serialVersionUID = 1L;
private byte[] serialized;
}
@Override
- public final void writeExternal(final ObjectOutput out) throws IOException {
- out.writeInt(serialized.length);
- out.write(serialized);
+ public final byte[] bytes() {
+ return serialized;
}
@Override
- public final void readExternal(final ObjectInput in) throws IOException {
- final int length = in.readInt();
- serialized = new byte[length];
- in.readFully(serialized);
+ public final void readExternal(final byte[] bytes) throws IOException {
+ serialized = requireNonNull(bytes);
identifier = verifyNotNull(readIdentifier(ByteStreams.newDataInput(serialized)));
}
- protected final Object readResolve() {
+ @Override
+ public final Object readResolve() {
return verifyNotNull(createObject(identifier, serialized));
}
return serialized.length;
}
+ protected final byte @NonNull [] serialized() {
+ return serialized;
+ }
+
@Override
public final int serializedSize() {
// TODO: this is not entirely accurate, as the serialization stream has additional overheads:
return verifyNotNull(externalizableProxy(serialized));
}
- @SuppressWarnings("checkstyle:hiddenField")
protected abstract @NonNull AbstractProxy<T> externalizableProxy(byte @NonNull[] serialized);
protected abstract int externalizableProxySize();
--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. 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.datastore.persisted;
+
+import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.io.ByteStreams;
+import java.io.IOException;
+import org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifier;
+import org.opendaylight.controller.cluster.datastore.persisted.AbstractIdentifiablePayload.SerialForm;
+
+/**
+ * Serialization proxy for {@link CreateLocalHistoryPayload}.
+ */
+final class CH implements SerialForm {
+ private static final long serialVersionUID = 1L;
+
+ private LocalHistoryIdentifier identifier;
+ private byte[] bytes;
+
+ @SuppressWarnings("checkstyle:RedundantModifier")
+ public CH() {
+ // For Externalizable
+ }
+
+ CH(final byte[] bytes) {
+ this.bytes = requireNonNull(bytes);
+ }
+
+ @Override
+ public byte[] bytes() {
+ return bytes;
+ }
+
+ @Override
+ public void readExternal(final byte[] newBytes) throws IOException {
+ bytes = requireNonNull(newBytes);
+ identifier = verifyNotNull(LocalHistoryIdentifier.readFrom(ByteStreams.newDataInput(newBytes)));
+ }
+
+ @Override
+ public Object readResolve() {
+ return new CreateLocalHistoryPayload(identifier, bytes);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. 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.datastore.persisted;
+
+import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.StreamCorruptedException;
+import org.opendaylight.controller.cluster.datastore.persisted.CommitTransactionPayload.Chunked;
+import org.opendaylight.controller.cluster.datastore.persisted.CommitTransactionPayload.Simple;
+import org.opendaylight.controller.cluster.io.ChunkedByteArray;
+
+/**
+ * Serialization proxy for {@link CommitTransactionPayload}.
+ */
+final class CT implements Externalizable {
+ private static final long serialVersionUID = 1L;
+
+ private CommitTransactionPayload payload;
+
+ @SuppressWarnings("checkstyle:RedundantModifier")
+ public CT() {
+ // For Externalizable
+ }
+
+ CT(final CommitTransactionPayload payload) {
+ this.payload = requireNonNull(payload);
+ }
+
+ @Override
+ public void writeExternal(final ObjectOutput out) throws IOException {
+ out.writeInt(payload.size());
+ payload.writeBytes(out);
+ }
+
+ @Override
+ public void readExternal(final ObjectInput in) throws IOException {
+ final int length = in.readInt();
+ if (length < 0) {
+ throw new StreamCorruptedException("Invalid payload length " + length);
+ } else if (length < CommitTransactionPayload.MAX_ARRAY_SIZE) {
+ final byte[] serialized = new byte[length];
+ in.readFully(serialized);
+ payload = new Simple(serialized);
+ } else {
+ payload = new Chunked(ChunkedByteArray.readFrom(in, length, CommitTransactionPayload.MAX_ARRAY_SIZE));
+ }
+ }
+
+ private Object readResolve() {
+ return verifyNotNull(payload);
+ }
+}
private static final Logger LOG = LoggerFactory.getLogger(CommitTransactionPayload.class);
private static final long serialVersionUID = 1L;
- private static final int MAX_ARRAY_SIZE = ceilingPowerOfTwo(Integer.getInteger(
+ static final int MAX_ARRAY_SIZE = ceilingPowerOfTwo(Integer.getInteger(
"org.opendaylight.controller.cluster.datastore.persisted.max-array-size", 256 * 1024));
private volatile Entry<TransactionIdentifier, DataTreeCandidateWithVersion> candidate = null;
return new Proxy(this);
}
- private static final class Simple extends CommitTransactionPayload {
+ static final class Simple extends CommitTransactionPayload {
private static final long serialVersionUID = 1L;
private final byte[] serialized;
}
}
- private static final class Chunked extends CommitTransactionPayload {
+ static final class Chunked extends CommitTransactionPayload {
private static final long serialVersionUID = 1L;
@SuppressFBWarnings(value = "SE_BAD_FIELD", justification = "Handled via serialization proxy")
--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. 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.datastore.persisted;
+
+import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.io.ByteStreams;
+import java.io.IOException;
+import org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifier;
+import org.opendaylight.controller.cluster.datastore.persisted.AbstractIdentifiablePayload.SerialForm;
+
+/**
+ * Serialization proxy for {@link CloseLocalHistoryPayload}.
+ */
+final class DH implements SerialForm {
+ private static final long serialVersionUID = 1L;
+
+ private LocalHistoryIdentifier identifier;
+ private byte[] bytes;
+
+ @SuppressWarnings("checkstyle:RedundantModifier")
+ public DH() {
+ // For Externalizable
+ }
+
+ DH(final byte[] bytes) {
+ this.bytes = requireNonNull(bytes);
+ }
+
+ @Override
+ public byte[] bytes() {
+ return bytes;
+ }
+
+ @Override
+ public void readExternal(final byte[] newBytes) throws IOException {
+ bytes = requireNonNull(newBytes);
+ identifier = verifyNotNull(LocalHistoryIdentifier.readFrom(ByteStreams.newDataInput(newBytes)));
+ }
+
+ @Override
+ public Object readResolve() {
+ return new CloseLocalHistoryPayload(identifier, bytes);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. 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.datastore.persisted;
+
+import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Serialization proxy for {@link DatastoreSnapshot}.
+ */
+final class DS implements DatastoreSnapshot.SerialForm {
+ private static final long serialVersionUID = 1L;
+
+ private DatastoreSnapshot datastoreSnapshot;
+
+ @SuppressWarnings("checkstyle:RedundantModifier")
+ public DS() {
+ // For Externalizable
+ }
+
+ DS(final DatastoreSnapshot datastoreSnapshot) {
+ this.datastoreSnapshot = requireNonNull(datastoreSnapshot);
+ }
+
+ @Override
+ public DatastoreSnapshot datastoreSnapshot() {
+ return datastoreSnapshot;
+ }
+
+ @Override
+ public void resolveTo(final DatastoreSnapshot newDatastoreSnapshot) {
+ datastoreSnapshot = requireNonNull(newDatastoreSnapshot);
+ }
+
+ @Override
+ public Object readResolve() {
+ return verifyNotNull(datastoreSnapshot);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. 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.datastore.persisted;
+
+import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
+
+import org.opendaylight.controller.cluster.datastore.persisted.DatastoreSnapshot.ShardSnapshot;
+import org.opendaylight.controller.cluster.raft.persisted.Snapshot;
+
+/**
+ * Serialization proxy for {@link ShardDataTreeSnapshot}.
+ */
+final class DSS implements ShardSnapshot.SerialForm {
+ private static final long serialVersionUID = 1L;
+
+ private ShardSnapshot shardSnapshot;
+
+ @SuppressWarnings("checkstyle:RedundantModifier")
+ public DSS() {
+ // For Externalizable
+ }
+
+ DSS(final ShardSnapshot shardSnapshot) {
+ this.shardSnapshot = requireNonNull(shardSnapshot);
+ }
+
+ @Override
+ public ShardSnapshot shardSnapshot() {
+ return shardSnapshot;
+ }
+
+ @Override
+ public void resolveTo(final String name, final Snapshot snapshot) {
+ shardSnapshot = new ShardSnapshot(name, snapshot);
+ }
+
+ @Override
+ public Object readResolve() {
+ return verifyNotNull(shardSnapshot);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. 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.datastore.persisted;
+
+import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.io.ByteStreams;
+import java.io.IOException;
+import org.opendaylight.controller.cluster.access.concepts.ClientIdentifier;
+import org.opendaylight.controller.cluster.datastore.persisted.AbstractIdentifiablePayload.SerialForm;
+
+/**
+ * Serialization proxy for {@link DisableTrackingPayload}.
+ */
+final class DT implements SerialForm {
+ private static final long serialVersionUID = 1L;
+
+ private ClientIdentifier identifier;
+ private byte[] bytes;
+
+ @SuppressWarnings("checkstyle:RedundantModifier")
+ public DT() {
+ // For Externalizable
+ }
+
+ DT(final byte[] bytes) {
+ this.bytes = requireNonNull(bytes);
+ }
+
+ @Override
+ public byte[] bytes() {
+ return bytes;
+ }
+
+ @Override
+ public void readExternal(final byte[] newBytes) throws IOException {
+ bytes = requireNonNull(newBytes);
+ identifier = verifyNotNull(ClientIdentifier.readFrom(ByteStreams.newDataInput(newBytes)));
+ }
+
+ @Override
+ public Object readResolve() {
+ return new DisableTrackingPayload(identifier, bytes);
+ }
+}
*/
package org.opendaylight.controller.cluster.datastore.persisted;
+import static com.google.common.base.Verify.verifyNotNull;
import static java.util.Objects.requireNonNull;
import com.google.common.collect.ImmutableList;
* @author Thomas Pantelis
*/
public final class DatastoreSnapshot implements Serializable {
- private static final class Proxy implements Externalizable {
- private static final long serialVersionUID = 1L;
+ interface SerialForm extends Externalizable {
- private DatastoreSnapshot datastoreSnapshot;
+ DatastoreSnapshot datastoreSnapshot();
- // 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() {
- // For Externalizable
- }
+ Object readResolve();
- Proxy(final DatastoreSnapshot datastoreSnapshot) {
- this.datastoreSnapshot = datastoreSnapshot;
+ void resolveTo(@NonNull DatastoreSnapshot newDatastoreSnapshot);
+
+ @Override
+ default void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ final var type = (String)in.readObject();
+ final var snapshot = (ShardManagerSnapshot) in.readObject();
+
+ final int size = in.readInt();
+ var localShardSnapshots = new ArrayList<ShardSnapshot>(size);
+ for (int i = 0; i < size; i++) {
+ localShardSnapshots.add((ShardSnapshot) in.readObject());
+ }
+
+ resolveTo(new DatastoreSnapshot(type, snapshot, localShardSnapshots));
}
@Override
- public void writeExternal(ObjectOutput out) throws IOException {
+ default void writeExternal(ObjectOutput out) throws IOException {
+ final var datastoreSnapshot = datastoreSnapshot();
out.writeObject(datastoreSnapshot.type);
out.writeObject(datastoreSnapshot.shardManagerSnapshot);
out.writeObject(shardSnapshot);
}
}
+ }
- @Override
- public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
- String localType = (String)in.readObject();
- ShardManagerSnapshot localShardManagerSnapshot = (ShardManagerSnapshot) in.readObject();
+ private static final class Proxy implements SerialForm {
+ private static final long serialVersionUID = 1L;
- int size = in.readInt();
- List<ShardSnapshot> localShardSnapshots = new ArrayList<>(size);
- for (int i = 0; i < size; i++) {
- localShardSnapshots.add((ShardSnapshot) in.readObject());
- }
+ private DatastoreSnapshot datastoreSnapshot;
+
+ // 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() {
+ // For Externalizable
+ }
- datastoreSnapshot = new DatastoreSnapshot(localType, localShardManagerSnapshot, localShardSnapshots);
+ Proxy(final DatastoreSnapshot datastoreSnapshot) {
+ this.datastoreSnapshot = requireNonNull(datastoreSnapshot);
}
- private Object readResolve() {
+ @Override
+ public DatastoreSnapshot datastoreSnapshot() {
return datastoreSnapshot;
}
+
+ @Override
+ public void resolveTo(DatastoreSnapshot newDatastoreSnapshot) {
+ datastoreSnapshot = requireNonNull(newDatastoreSnapshot);
+ }
+
+ @Override
+ public Object readResolve() {
+ return verifyNotNull(datastoreSnapshot);
+ }
}
private static final long serialVersionUID = 1L;
- private final String type;
+ private final @NonNull String type;
private final ShardManagerSnapshot shardManagerSnapshot;
- private final List<ShardSnapshot> shardSnapshots;
+ private final @NonNull ImmutableList<ShardSnapshot> shardSnapshots;
public DatastoreSnapshot(@NonNull String type, @Nullable ShardManagerSnapshot shardManagerSnapshot,
@NonNull List<ShardSnapshot> shardSnapshots) {
}
public static final class ShardSnapshot implements Serializable {
- private static final long serialVersionUID = 1L;
+ interface SerialForm extends Externalizable {
+
+ ShardSnapshot shardSnapshot();
+
+ Object readResolve();
- private static final class Proxy implements Externalizable {
+ void resolveTo(String name, Snapshot snapshot);
+
+ @Override
+ default void writeExternal(ObjectOutput out) throws IOException {
+ final var shardSnapshot = shardSnapshot();
+ out.writeObject(shardSnapshot.name);
+ out.writeObject(shardSnapshot.snapshot);
+ }
+
+ @Override
+ default void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ resolveTo((String) in.readObject(), (Snapshot) in.readObject());
+ }
+ }
+
+ private static final class Proxy implements SerialForm {
private static final long serialVersionUID = 1L;
private ShardSnapshot shardSnapshot;
}
@Override
- public void writeExternal(ObjectOutput out) throws IOException {
- out.writeObject(shardSnapshot.name);
- out.writeObject(shardSnapshot.snapshot);
+ public ShardSnapshot shardSnapshot() {
+ return shardSnapshot;
}
@Override
- public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
- shardSnapshot = new ShardSnapshot((String)in.readObject(), (Snapshot) in.readObject());
+ public void resolveTo(final String name, final Snapshot snapshot) {
+ shardSnapshot = new ShardSnapshot(name, snapshot);
}
- private Object readResolve() {
- return shardSnapshot;
+ @Override
+ public Object readResolve() {
+ return verifyNotNull(shardSnapshot);
}
}
+ private static final long serialVersionUID = 1L;
+
private final @NonNull String name;
private final @NonNull Snapshot snapshot;
--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. 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.datastore.persisted;
+
+import com.google.common.collect.ImmutableList;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.List;
+
+/**
+ * Externalizable proxy for {@link FrontendShardDataTreeSnapshotMetadata}.
+ */
+final class FM implements Externalizable {
+ private static final long serialVersionUID = 1L;
+
+ private List<FrontendClientMetadata> clients;
+
+ @SuppressWarnings("checkstyle:RedundantModifier")
+ public FM() {
+ // For Externalizable
+ }
+
+ FM(final FrontendShardDataTreeSnapshotMetadata metadata) {
+ clients = metadata.getClients();
+ }
+
+ @Override
+ public void writeExternal(final ObjectOutput out) throws IOException {
+ out.writeInt(clients.size());
+ for (var c : clients) {
+ c.writeTo(out);
+ }
+ }
+
+ @Override
+ public void readExternal(final ObjectInput in) throws IOException {
+ final int size = in.readInt();
+ final var builder = ImmutableList.<FrontendClientMetadata>builderWithExpectedSize(size);
+ for (int i = 0; i < size ; ++i) {
+ builder.add(FrontendClientMetadata.readFrom(in));
+ }
+ clients = builder.build();
+ }
+
+ private Object readResolve() {
+ return new FrontendShardDataTreeSnapshotMetadata(clients);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. 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.datastore.persisted;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import com.google.common.collect.ImmutableMap;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Map;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.codec.binfmt.NormalizedNodeDataInput;
+import org.opendaylight.yangtools.yang.data.codec.binfmt.NormalizedNodeStreamVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Externalizable proxy for {@link MetadataShardDataTreeSnapshot}.
+ */
+final class MS implements Externalizable {
+ private static final Logger LOG = LoggerFactory.getLogger(MS.class);
+ private static final long serialVersionUID = 1L;
+
+ private Map<Class<? extends ShardDataTreeSnapshotMetadata<?>>, ShardDataTreeSnapshotMetadata<?>> metadata;
+ private NormalizedNodeStreamVersion version;
+ private NormalizedNode rootNode;
+
+ @SuppressWarnings("checkstyle:RedundantModifier")
+ public MS() {
+ // For Externalizable
+ }
+
+ MS(final MetadataShardDataTreeSnapshot snapshot) {
+ rootNode = snapshot.getRootNode().orElseThrow();
+ metadata = snapshot.getMetadata();
+ version = snapshot.version().getStreamVersion();
+ }
+
+ @Override
+ public void writeExternal(final ObjectOutput out) throws IOException {
+ out.writeInt(metadata.size());
+ for (var m : metadata.values()) {
+ out.writeObject(m);
+ }
+ try (var stream = version.newDataOutput(out)) {
+ stream.writeNormalizedNode(rootNode);
+ }
+ }
+
+ @Override
+ public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
+ final int metaSize = in.readInt();
+ checkArgument(metaSize >= 0, "Invalid negative metadata map length %s", metaSize);
+
+ // Default pre-allocate is 4, which should be fine
+ final var metaBuilder = ImmutableMap
+ .<Class<? extends ShardDataTreeSnapshotMetadata<?>>, ShardDataTreeSnapshotMetadata<?>>builder();
+ for (int i = 0; i < metaSize; ++i) {
+ final var m = (ShardDataTreeSnapshotMetadata<?>) in.readObject();
+ if (m != null) {
+ metaBuilder.put(m.getType(), m);
+ } else {
+ LOG.warn("Skipping null metadata");
+ }
+ }
+ metadata = metaBuilder.build();
+
+ final var stream = NormalizedNodeDataInput.newDataInput(in);
+ version = stream.getVersion();
+ rootNode = stream.readNormalizedNode();
+ }
+
+ private Object readResolve() {
+ return new MetadataShardDataTreeSnapshot(rootNode, metadata);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. 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.datastore.persisted;
+
+import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.io.ByteStreams;
+import java.io.IOException;
+import org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifier;
+import org.opendaylight.controller.cluster.datastore.persisted.AbstractIdentifiablePayload.SerialForm;
+
+/**
+ * Serialization proxy for {@link PurgeLocalHistoryPayload}.
+ */
+final class PH implements SerialForm {
+ private static final long serialVersionUID = 1L;
+
+ private LocalHistoryIdentifier identifier;
+ private byte[] bytes;
+
+ @SuppressWarnings("checkstyle:RedundantModifier")
+ public PH() {
+ // For Externalizable
+ }
+
+ PH(final byte[] bytes) {
+ this.bytes = requireNonNull(bytes);
+ }
+
+ @Override
+ public byte[] bytes() {
+ return bytes;
+ }
+
+ @Override
+ public void readExternal(final byte[] newBytes) throws IOException {
+ bytes = requireNonNull(newBytes);
+ identifier = verifyNotNull(LocalHistoryIdentifier.readFrom(ByteStreams.newDataInput(newBytes)));
+ }
+
+ @Override
+ public Object readResolve() {
+ return new PurgeLocalHistoryPayload(identifier, bytes);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. 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.datastore.persisted;
+
+import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.io.ByteStreams;
+import java.io.IOException;
+import org.opendaylight.controller.cluster.access.concepts.TransactionIdentifier;
+import org.opendaylight.controller.cluster.datastore.persisted.AbstractIdentifiablePayload.SerialForm;
+
+/**
+ * Serialization proxy for {@link PurgeTransactionPayload}.
+ */
+final class PT implements SerialForm {
+ private static final long serialVersionUID = 1L;
+
+ private TransactionIdentifier identifier;
+ private byte[] bytes;
+
+ @SuppressWarnings("checkstyle:RedundantModifier")
+ public PT() {
+ // For Externalizable
+ }
+
+ PT(final byte[] bytes) {
+ this.bytes = requireNonNull(bytes);
+ }
+
+ @Override
+ public byte[] bytes() {
+ return bytes;
+ }
+
+ @Override
+ public void readExternal(final byte[] newBytes) throws IOException {
+ bytes = requireNonNull(newBytes);
+ identifier = verifyNotNull(TransactionIdentifier.readFrom(ByteStreams.newDataInput(newBytes)));
+ }
+
+ @Override
+ public Object readResolve() {
+ return new PurgeTransactionPayload(identifier, bytes);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. 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.datastore.persisted;
+
+import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
+
+import java.util.List;
+
+/**
+ * Serialization proxy for {@link ShardManagerSnapshot}.
+ */
+final class SM implements ShardManagerSnapshot.SerializedForm {
+ private static final long serialVersionUID = 1L;
+
+ private ShardManagerSnapshot snapshot;
+
+ @SuppressWarnings("checkstyle:RedundantModifier")
+ public SM() {
+ // For Externalizable
+ }
+
+ SM(final ShardManagerSnapshot snapshot) {
+ this.snapshot = requireNonNull(snapshot);
+ }
+
+ @Override
+ public List<String> shardNames() {
+ return snapshot.getShardList();
+ }
+
+ @Override
+ public void resolveTo(final ShardManagerSnapshot newSnapshot) {
+ snapshot = requireNonNull(newSnapshot);
+ }
+
+ @Override
+ public Object readResolve() {
+ return verifyNotNull(snapshot);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. 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.datastore.persisted;
+
+import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Serialization proxy for {@link ShardSnapshotState}.
+ */
+final class SS implements ShardSnapshotState.SerialForm {
+ private static final long serialVersionUID = 1L;
+
+ private ShardSnapshotState snapshotState;
+
+ @SuppressWarnings("checkstyle:RedundantModifier")
+ public SS() {
+ // For Externalizable
+ }
+
+ SS(final ShardSnapshotState snapshotState) {
+ this.snapshotState = requireNonNull(snapshotState);
+ }
+
+ @Override
+ public ShardSnapshotState snapshotState() {
+ return snapshotState;
+ }
+
+ @Override
+ public void resolveTo(final ShardSnapshotState newSnapshotState) {
+ snapshotState = requireNonNull(newSnapshotState);
+ }
+
+ @Override
+ public Object readResolve() {
+ return verifyNotNull(snapshotState);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. 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.datastore.persisted;
+
+import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.io.ByteStreams;
+import java.io.IOException;
+import org.opendaylight.controller.cluster.access.concepts.LocalHistoryIdentifier;
+import org.opendaylight.controller.cluster.datastore.persisted.AbstractIdentifiablePayload.SerialForm;
+import org.opendaylight.controller.cluster.datastore.utils.ImmutableUnsignedLongSet;
+
+/**
+ * Serialization proxy for {@link SkipTransactionsPayload}.
+ */
+final class ST implements SerialForm {
+ private static final long serialVersionUID = 1L;
+
+ private ImmutableUnsignedLongSet transactionIds;
+ private LocalHistoryIdentifier identifier;
+ private byte[] bytes;
+
+ @SuppressWarnings("checkstyle:RedundantModifier")
+ public ST() {
+ // For Externalizable
+ }
+
+ ST(final byte[] bytes) {
+ this.bytes = requireNonNull(bytes);
+ }
+
+ @Override
+ public byte[] bytes() {
+ return bytes;
+ }
+
+ @Override
+ public void readExternal(final byte[] newBytes) throws IOException {
+ bytes = requireNonNull(newBytes);
+
+ final var in = ByteStreams.newDataInput(newBytes);
+ identifier = LocalHistoryIdentifier.readFrom(in);
+ transactionIds = verifyNotNull(ImmutableUnsignedLongSet.readFrom(in));
+ }
+
+ @Override
+ public Object readResolve() {
+ return new SkipTransactionsPayload(identifier, bytes, transactionIds);
+ }
+}
*/
package org.opendaylight.controller.cluster.datastore.persisted;
+import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
+
import com.google.common.collect.ImmutableList;
import java.io.Externalizable;
import java.io.IOException;
* @author Thomas Pantelis
*/
public final class ShardManagerSnapshot implements Serializable {
- private static final class Proxy implements Externalizable {
+ interface SerializedForm extends Externalizable {
+ /**
+ * Return the serial form of this object contents, corresponding to {@link ShardManagerSnapshot#shardList}.
+ *
+ * @return List of shards names.
+ */
+ List<String> shardNames();
+
+ /**
+ * Resolve this proxy to an actual {@link ShardManagerSnapshot}. Implementations can rely on the object to be
+ * set via {@link #resolveTo(ShardManagerSnapshot)}.
+ *
+ * @return A snapshot
+ */
+ Object readResolve();
+
+ /**
+ * Set this proxy to return {@code snapshot} on next {@link #readResolve()}.
+ *
+ * @param newSnapshot Snapshot to set
+ */
+ void resolveTo(@NonNull ShardManagerSnapshot newSnapshot);
+
+ @Override
+ default void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
+ final int size = in.readInt();
+ final var shardList = new ArrayList<String>(size);
+ for (int i = 0; i < size; i++) {
+ shardList.add((String) in.readObject());
+ }
+ resolveTo(new ShardManagerSnapshot(shardList));
+ }
+
+ @Override
+ default void writeExternal(final ObjectOutput out) throws IOException {
+ final var shardList = shardNames();
+ out.writeInt(shardList.size());
+ for (var shardName : shardList) {
+ out.writeObject(shardName);
+ }
+ }
+ }
+
+ private static final class Proxy implements SerializedForm {
private static final long serialVersionUID = 1L;
private ShardManagerSnapshot snapshot;
}
@Override
- public void writeExternal(final ObjectOutput out) throws IOException {
- out.writeInt(snapshot.shardList.size());
- for (String shard: snapshot.shardList) {
- out.writeObject(shard);
- }
+ public List<String> shardNames() {
+ return snapshot.getShardList();
}
@Override
- public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
- int size = in.readInt();
- List<String> localShardList = new ArrayList<>(size);
- for (int i = 0; i < size; i++) {
- localShardList.add((String) in.readObject());
- }
-
- snapshot = new ShardManagerSnapshot(localShardList);
+ public void resolveTo(final ShardManagerSnapshot newSnapshot) {
+ snapshot = requireNonNull(newSnapshot);
}
- private Object readResolve() {
- return snapshot;
+ @Override
+ public Object readResolve() {
+ return verifyNotNull(snapshot);
}
}
*/
package org.opendaylight.controller.cluster.datastore.persisted;
+import static com.google.common.base.Verify.verifyNotNull;
import static java.util.Objects.requireNonNull;
import com.google.common.annotations.VisibleForTesting;
* @author Thomas Pantelis
*/
public final class ShardSnapshotState implements Snapshot.State {
- private static final class Proxy implements Externalizable {
+ interface SerialForm extends Externalizable {
+
+ ShardSnapshotState snapshotState();
+
+ void resolveTo(@NonNull ShardSnapshotState newSnapshotState);
+
+ Object readResolve();
+
+ @Override
+ default void readExternal(final ObjectInput in) throws IOException {
+ resolveTo(ShardDataTreeSnapshot.deserialize(in));
+ }
+
+ @Override
+ default void writeExternal(final ObjectOutput out) throws IOException {
+ snapshotState().getSnapshot().serialize(out);
+ }
+ }
+
+ private static final class Proxy implements SerialForm {
private static final long serialVersionUID = 1L;
private ShardSnapshotState snapshotState;
}
@Override
- public void writeExternal(final ObjectOutput out) throws IOException {
- snapshotState.snapshot.serialize(out);
+ public ShardSnapshotState snapshotState() {
+ return snapshotState;
}
@Override
- public void readExternal(final ObjectInput in) throws IOException {
- snapshotState = ShardDataTreeSnapshot.deserialize(in);
+ public void resolveTo(final ShardSnapshotState newSnapshotState) {
+ snapshotState = requireNonNull(newSnapshotState);
}
- private Object readResolve() {
- return snapshotState;
+ @Override
+ public Object readResolve() {
+ return verifyNotNull(snapshotState);
}
}
@SuppressFBWarnings(value = "SE_BAD_FIELD", justification = "Handled via externalizable proxy")
private final @NonNull ImmutableUnsignedLongSet transactionIds;
- private SkipTransactionsPayload(final @NonNull LocalHistoryIdentifier historyId,
+ SkipTransactionsPayload(final @NonNull LocalHistoryIdentifier historyId,
final byte @NonNull [] serialized, final ImmutableUnsignedLongSet transactionIds) {
super(historyId, serialized);
this.transactionIds = requireNonNull(transactionIds);