--- /dev/null
+/*
+ * Copyright (c) 2016 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.cluster.access.concepts;
+
+import com.google.common.base.Verify;
+import java.io.DataInput;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.concepts.WritableIdentifier;
+import org.opendaylight.yangtools.concepts.WritableObjects;
+
+/**
+ * Abstract Externalizable proxy for use with {@link Message} subclasses.
+ *
+ * @author Robert Varga
+ *
+ * @param <T> Target identifier type
+ * @param <C> Message class
+ */
+abstract class AbstractMessageProxy<T extends WritableIdentifier, C extends Message<T, C>> implements Externalizable {
+ private static final long serialVersionUID = 1L;
+ private T target;
+ private long sequence;
+ private long retry;
+
+ protected AbstractMessageProxy() {
+ // For Externalizable
+ }
+
+ AbstractMessageProxy(final @Nonnull C message) {
+ this.target = message.getTarget();
+ this.sequence = message.getSequence();
+ this.retry = message.getRetry();
+ }
+
+ @Override
+ public void writeExternal(final ObjectOutput out) throws IOException {
+ target.writeTo(out);
+ WritableObjects.writeLongs(out, sequence, retry);
+ }
+
+ @Override
+ public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
+ target = Verify.verifyNotNull(readTarget(in));
+
+ final byte header = WritableObjects.readLongHeader(in);
+ sequence = WritableObjects.readFirstLong(in, header);
+ retry = WritableObjects.readSecondLong(in, header);
+ }
+
+ protected final Object readResolve() {
+ return Verify.verifyNotNull(createMessage(target, sequence, retry));
+ }
+
+ protected abstract @Nonnull T readTarget(@Nonnull DataInput in) throws IOException;
+ abstract @Nonnull C createMessage(@Nonnull T target, long sequence, long retry);
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2016 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.cluster.access.concepts;
+
+import com.google.common.annotations.Beta;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.concepts.WritableIdentifier;
+
+/**
+ * Abstract Externalizable proxy for use with {@link RequestFailure} subclasses.
+ *
+ * @author Robert Varga
+ *
+ * @param <T> Target identifier type
+ */
+@Beta
+public abstract class AbstractRequestFailureProxy<T extends WritableIdentifier, C extends RequestFailure<T, C>>
+ extends AbstractResponseProxy<T, C> {
+ private static final long serialVersionUID = 1L;
+ private RequestException cause;
+
+ protected AbstractRequestFailureProxy() {
+ // For Externalizable
+ }
+
+ protected AbstractRequestFailureProxy(final @Nonnull C failure) {
+ super(failure);
+ this.cause = failure.getCause();
+ }
+
+ @Override
+ public void writeExternal(final ObjectOutput out) throws IOException {
+ super.writeExternal(out);
+ out.writeObject(cause);
+ }
+
+ @Override
+ public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
+ super.readExternal(in);
+ cause = (RequestException) in.readObject();
+ }
+
+ @Override
+ final C createResponse(final T target, final long sequence, final long retry) {
+ return createFailure(target, sequence, retry, cause);
+ }
+
+ protected abstract @Nonnull C createFailure(@Nonnull T target, long sequence, long retry,
+ @Nonnull RequestException cause);
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2016 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.cluster.access.concepts;
+
+import akka.actor.ActorRef;
+import akka.serialization.JavaSerializer;
+import akka.serialization.Serialization;
+import com.google.common.annotations.Beta;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.concepts.WritableIdentifier;
+
+/**
+ * Abstract Externalizable proxy for use with {@link Request} subclasses.
+ *
+ * @author Robert Varga
+ *
+ * @param <T> Target identifier type
+ */
+@Beta
+public abstract class AbstractRequestProxy<T extends WritableIdentifier, C extends Request<T, C>>
+ extends AbstractMessageProxy<T, C> {
+ private static final long serialVersionUID = 1L;
+ private ActorRef replyTo;
+
+ protected AbstractRequestProxy() {
+ // For Externalizable
+ }
+
+ protected AbstractRequestProxy(final @Nonnull C request) {
+ super(request);
+ this.replyTo = request.getReplyTo();
+ }
+
+ @Override
+ public void writeExternal(final ObjectOutput out) throws IOException {
+ super.writeExternal(out);
+ out.writeUTF(Serialization.serializedActorPath(replyTo));
+ }
+
+ @Override
+ public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
+ super.readExternal(in);
+ replyTo = JavaSerializer.currentSystem().value().provider().resolveActorRef(in.readUTF());
+ }
+
+ @Override
+ protected final C createMessage(final T target, final long sequence, final long retry) {
+ return createRequest(target, sequence, retry, replyTo);
+ }
+
+ protected abstract @Nonnull C createRequest(@Nonnull T target, long sequence, long retry, @Nonnull ActorRef replyTo);
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2016 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.cluster.access.concepts;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.concepts.WritableIdentifier;
+
+/**
+ * Abstract Externalizable proxy class to use with {@link Response} subclasses.
+ *
+ * @author Robert Varga
+ *
+ * @param <T> Target identifier type
+ * @param <C> Message class
+ */
+abstract class AbstractResponseProxy<T extends WritableIdentifier, C extends Response<T, C>>
+ extends AbstractMessageProxy<T, C> {
+ private static final long serialVersionUID = 1L;
+
+ AbstractResponseProxy() {
+ // for Externalizable
+ }
+
+ AbstractResponseProxy(final @Nonnull C response) {
+ super(response);
+ }
+
+ @Override
+ final C createMessage(final T target, final long sequence, final long retry) {
+ return createResponse(target, sequence, retry);
+ }
+
+ abstract @Nonnull C createResponse(@Nonnull T target, long sequence, long retry);
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.cluster.access.concepts;
+
+import com.google.common.annotations.Beta;
+import java.io.Externalizable;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.concepts.WritableIdentifier;
+
+/**
+ * Abstract Externalizable proxy for use with {@link RequestSuccess} subclasses.
+ *
+ * @author Robert Varga
+ *
+ * @param <T> Target identifier type
+ */
+@Beta
+public abstract class AbstractSuccessProxy<T extends WritableIdentifier, C extends RequestSuccess<T, C>>
+ extends AbstractResponseProxy<T, C> implements Externalizable {
+ private static final long serialVersionUID = 1L;
+
+ protected AbstractSuccessProxy() {
+ // For Externalizable
+ }
+
+ protected AbstractSuccessProxy(final @Nonnull C success) {
+ super(success);
+ }
+
+ @Override
+ final C createResponse(final T target, final long sequence, final long retry) {
+ return createSuccess(target, sequence, retry);
+ }
+
+ protected abstract @Nonnull C createSuccess(@Nonnull T target, long sequence, long retry);
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2016 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.cluster.access.concepts;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Verify;
+import java.io.Serializable;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.cluster.access.ABIVersion;
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.concepts.WritableIdentifier;
+
+/**
+ * An abstract concept of a Message. This class cannot be instantiated directly, use its specializations {@link Request}
+ * and {@link Response}.
+ *
+ * Messages have a target and a sequence number. Sequence numbers are expected to be assigned monotonically on a
+ * per-target basis, hence two targets can observe the same sequence number.
+ *
+ * This class includes explicit versioning for forward- and backward- compatibility of serialization format. This is
+ * achieved by using the serialization proxy pattern. Subclasses are in complete control of what proxy is used to
+ * serialize a particular object on the wire. This class can serve as an explicit version marker, hence no further
+ * action is necessary in the deserialization path.
+ *
+ * For the serialization path an explicit call from the user is required to select the appropriate serialization
+ * version. This is done via {@link #toVersion(ABIVersion)} method, which should return a copy of this object with
+ * the requested ABI version recorded and should return the appropriate serialization proxy.
+ *
+ * This workflow allows least disturbance across ABI versions, as all messages not affected by a ABI version bump
+ * will remain working with the same serialization format for the new ABI version.
+ *
+ * Note that this class specifies the {@link Immutable} contract, which means that all subclasses must follow this API
+ * contract.
+ *
+ * @author Robert Varga
+ *
+ * @param <T> Target identifier type
+ * @param <C> Message type
+ */
+@Beta
+public abstract class Message<T extends WritableIdentifier, C extends Message<T, C>> implements Immutable,
+ Serializable {
+ private static final long serialVersionUID = 1L;
+ private final T target;
+ private final long sequence;
+ private final ABIVersion version;
+ private final long retry;
+
+ private Message(final ABIVersion version, final T target, final long sequence, final long retry) {
+ this.target = Preconditions.checkNotNull(target);
+ this.version = Preconditions.checkNotNull(version);
+ this.sequence = sequence;
+ this.retry = retry;
+ }
+
+ Message(final T target, final long sequence, final long retry) {
+ this(ABIVersion.current(), target, sequence, retry);
+ }
+
+ Message(final C msg, final ABIVersion version) {
+ this(version, msg.getTarget(), msg.getSequence(), msg.getRetry());
+ }
+
+ Message(final C msg, final long retry) {
+ this(msg.getVersion(), msg.getTarget(), msg.getSequence(), retry);
+ }
+
+ /**
+ * Get the target identifier for this message.
+ *
+ * @return Target identifier
+ */
+ public final @Nonnull T getTarget() {
+ return target;
+ }
+
+ /**
+ * Get the message sequence of this message.
+ *
+ * @return Message sequence
+ */
+ public final long getSequence() {
+ return sequence;
+ }
+
+ @VisibleForTesting
+ public final ABIVersion getVersion() {
+ return version;
+ }
+
+ /**
+ * Get the message retry counter.
+ *
+ * @return Retry counter
+ */
+ public final long getRetry() {
+ return retry;
+ }
+
+ /**
+ * Return a message which will end up being serialized in the specified {@link ABIVersion}.
+ *
+ * @param version Request {@link ABIVersion}
+ * @return A new message which will use ABIVersion as its serialization.
+ */
+ @SuppressWarnings("unchecked")
+ public final @Nonnull C toVersion(final @Nonnull ABIVersion version) {
+ if (this.version == version) {
+ return (C)this;
+ }
+
+ switch (version) {
+ case BORON:
+ return Verify.verifyNotNull(cloneAsVersion(version));
+ case TEST_PAST_VERSION:
+ case TEST_FUTURE_VERSION:
+ // Fall-through to throw
+ break;
+ }
+
+ throw new IllegalArgumentException("Unhandled ABI version " + version);
+ }
+
+ /**
+ * Create a copy of this message which will serialize to a stream corresponding to the specified method. This
+ * method should be implemented by the concrete final message class and should invoke the equivalent of
+ * {@link #Message(Message, ABIVersion)}.
+ *
+ * @param version target ABI version
+ * @return A message with the specified serialization stream
+ * @throws IllegalArgumentException if this message does not support the target ABI
+ */
+ protected abstract @Nonnull C cloneAsVersion(@Nonnull ABIVersion version);
+
+ /**
+ * Return a message which will have the retry counter incremented by one.
+ *
+ * @return A message with the specified retry counter
+ */
+ public final @Nonnull C incrementRetry() {
+ return Verify.verifyNotNull(cloneAsRetry(retry +1));
+ }
+
+ /**
+ * Create a copy of this message which will have its retry count bumped. This method should be implemented by
+ * the concrete final message class and should invoked the equivalent of {@link #Message(Message, long)}.
+ *
+ * @param retry new retry count
+ * @return A message with the specified retry counter
+ */
+ protected abstract @Nonnull C cloneAsRetry(long retry);
+
+ @Override
+ public final String toString() {
+ return addToStringAttributes(MoreObjects.toStringHelper(this).omitNullValues()).toString();
+ }
+
+ /**
+ * Add attributes to the output of {@link #toString()}. Subclasses wanting to contribute additional information
+ * should override this method. Any null attributes will be omitted from the output.
+ *
+ * @param toStringHelper a {@link ToStringHelper} instance
+ * @return The {@link ToStringHelper} passed in as argument
+ * @throws NullPointerException if toStringHelper is null
+ */
+ protected @Nonnull ToStringHelper addToStringAttributes(final @Nonnull ToStringHelper toStringHelper) {
+ return toStringHelper.add("target", target).add("sequence", Long.toUnsignedString(sequence, 16));
+ }
+
+ /**
+ * Instantiate a serialization proxy for this object for the target ABI version. Implementations should return
+ * different objects for incompatible {@link ABIVersion}s. This method should never fail, as any compatibility
+ * checks should have been done by {@link #cloneAsVersion(ABIVersion)}.
+ *
+ * @param version Requested ABI version
+ * @return Proxy for this object
+ */
+ abstract @Nonnull AbstractMessageProxy<T, C> externalizableProxy(@Nonnull ABIVersion version);
+
+ protected final Object writeReplace() {
+ return externalizableProxy(version);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.cluster.access.concepts;
+
+import akka.actor.ActorRef;
+import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects.ToStringHelper;
+import com.google.common.base.Preconditions;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.cluster.access.ABIVersion;
+import org.opendaylight.yangtools.concepts.WritableIdentifier;
+
+/**
+ * A request message concept. Upon receipt of this message, the recipient will respond with either
+ * a {@link RequestSuccess} or a {@link RequestFailure} message.
+ *
+ * @author Robert Varga
+ *
+ * @param <T> Target identifier type
+ * @param <C> Message type
+ */
+@Beta
+public abstract class Request<T extends WritableIdentifier, C extends Request<T, C>> extends Message<T, C> {
+ private static final long serialVersionUID = 1L;
+ private final ActorRef replyTo;
+
+ protected Request(final @Nonnull T target, final long sequence, final long retry, final @Nonnull ActorRef replyTo) {
+ super(target, sequence, retry);
+ this.replyTo = Preconditions.checkNotNull(replyTo);
+ }
+
+ protected Request(final @Nonnull C request, final @Nonnull ABIVersion version) {
+ super(request, version);
+ this.replyTo = Preconditions.checkNotNull(request.getReplyTo());
+ }
+
+ protected Request(final C request, final long retry) {
+ super(request, retry);
+ this.replyTo = Preconditions.checkNotNull(request.getReplyTo());
+ }
+
+ /**
+ * Return the return address where responses to this request should be directed to.
+ *
+ * @return Original requestor
+ */
+ public final @Nonnull ActorRef getReplyTo() {
+ return replyTo;
+ }
+
+ /**
+ * Return a {@link RequestFailure} for this request, caused by a {@link RequestException}.
+ *
+ * @param cause Failure cause
+ * @return {@link RequestFailure} corresponding to this request
+ */
+ public abstract @Nonnull RequestFailure<T, ?> toRequestFailure(final @Nonnull RequestException cause);
+
+ @Override
+ protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
+ return super.addToStringAttributes(toStringHelper).add("replyTo", replyTo);
+ }
+
+ @Override
+ protected abstract AbstractRequestProxy<T, C> externalizableProxy(@Nonnull ABIVersion version);
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.cluster.access.concepts;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import javax.annotation.Nonnull;
+
+/**
+ * A failure cause behind a {@link RequestFailure} to process a {@link Request}.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public abstract class RequestException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ protected RequestException(final @Nonnull String message) {
+ super(Preconditions.checkNotNull(message));
+ }
+
+ protected RequestException(final @Nonnull String message, final @Nonnull Exception cause) {
+ super(Preconditions.checkNotNull(message), Preconditions.checkNotNull(cause));
+ }
+
+ public abstract boolean isRetriable();
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.cluster.access.concepts;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects.ToStringHelper;
+import com.google.common.base.Preconditions;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.cluster.access.ABIVersion;
+import org.opendaylight.yangtools.concepts.WritableIdentifier;
+
+/**
+ * A failure response to a {@link Request}. Contains a {@link RequestException} detailing the cause for this failure.
+ *
+ * @author Robert Varga
+ *
+ * @param <T> Target identifier type
+ * @param <C> Message class
+ */
+@Beta
+public abstract class RequestFailure<T extends WritableIdentifier, C extends RequestFailure<T, C>> extends Response<T, C> {
+ private static final long serialVersionUID = 1L;
+ private final RequestException cause;
+
+ protected RequestFailure(final @Nonnull C failure, final @Nonnull ABIVersion version) {
+ super(failure, version);
+ this.cause = Preconditions.checkNotNull(failure.getCause());
+ }
+
+ protected RequestFailure(final @Nonnull T target, final long sequence, final long retry,
+ final @Nonnull RequestException cause) {
+ super(target, sequence, retry);
+ this.cause = Preconditions.checkNotNull(cause);
+ }
+
+ /**
+ * Return the failure cause.
+ *
+ * @return Failure cause.
+ */
+ public final @Nonnull RequestException getCause() {
+ return cause;
+ }
+
+ /**
+ * Return an indication of whether this a hard failure. Hard failures must not be retried but need to be treated
+ * as authoritative response to a request.
+ *
+ * @return True if this represents a hard failure, false otherwise.
+ */
+ public final boolean isHardFailure() {
+ return !cause.isRetriable();
+ }
+
+ @Override
+ protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
+ return super.addToStringAttributes(toStringHelper).add("cause", cause);
+ }
+
+ @Override
+ protected abstract AbstractRequestFailureProxy<T, C> externalizableProxy(@Nonnull ABIVersion version);
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.cluster.access.concepts;
+
+import com.google.common.annotations.Beta;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.cluster.access.ABIVersion;
+import org.opendaylight.yangtools.concepts.WritableIdentifier;
+
+/**
+ * A successful reply to a {@link Request}.
+ *
+ * @author Robert Varga
+ *
+ * @param <T> Target identifier type
+ */
+@Beta
+public abstract class RequestSuccess<T extends WritableIdentifier, C extends RequestSuccess<T, C>> extends
+ Response<T, C> {
+ private static final long serialVersionUID = 1L;
+
+ protected RequestSuccess(final @Nonnull C success, final @Nonnull ABIVersion version) {
+ super(success, version);
+ }
+
+ protected RequestSuccess(final @Nonnull T target, final long sequence, final long retry) {
+ super(target, sequence, retry);
+ }
+
+ @Override
+ protected abstract AbstractSuccessProxy<T, C> externalizableProxy(@Nonnull ABIVersion version);
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.cluster.access.concepts;
+
+import com.google.common.annotations.Beta;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.cluster.access.ABIVersion;
+import org.opendaylight.yangtools.concepts.WritableIdentifier;
+
+/**
+ * Abstract counterpart to a {@link Request}. This class should not be instantiated directly, but rather through
+ * {@link RequestFailure} and {@link RequestSuccess}, which provide appropriate specialization. It is visible purely for
+ * the purpose of allowing to check if an object is either of those specializations with a single instanceof check.
+ *
+ * @author Robert Varga
+ *
+ * @param <T> Target identifier type
+ * @param <C> Message type
+ */
+@Beta
+public abstract class Response<T extends WritableIdentifier, C extends Response<T, C>> extends Message<T, C> {
+ private static final long serialVersionUID = 1L;
+
+ Response(final @Nonnull C response, final @Nonnull ABIVersion version) {
+ super(response, version);
+ }
+
+ Response(final @Nonnull T target, final long sequence, final long retry) {
+ super(target, sequence, retry);
+ }
+
+ @Override
+ protected final C cloneAsRetry(final long retry) {
+ throw new UnsupportedOperationException("Responses do not support retries");
+ }
+
+ @Override
+ abstract AbstractResponseProxy<T, C> externalizableProxy(@Nonnull ABIVersion version);
+}