From 3ebd44f9b7a4a217222036c2889d2a04b4f1eb30 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Fri, 27 May 2016 17:24:20 +0200 Subject: [PATCH] BUG-5280: define RetiredGenerationException This defines the error reported by the backend whenever it sees a request coming from an outdated client generation. The client behavior handles these failures by invoking an upcall to the subclass and initiate shutdown. Change-Id: Iea1e04e3754fdc09fbdd9c6dc0d420a05145791c Signed-off-by: Robert Varga --- .../concepts/RetiredGenerationException.java | 30 +++++++++++++++++++ .../DistributedDataStoreClientBehavior.java | 7 ++++- .../actors/client/ClientActorBehavior.java | 27 +++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/concepts/RetiredGenerationException.java diff --git a/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/concepts/RetiredGenerationException.java b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/concepts/RetiredGenerationException.java new file mode 100644 index 0000000000..219f2819dc --- /dev/null +++ b/opendaylight/md-sal/cds-access-api/src/main/java/org/opendaylight/controller/cluster/access/concepts/RetiredGenerationException.java @@ -0,0 +1,30 @@ +/* + * 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; + +/** + * General error raised when the recipient of a {@link Request} determines that the request contains + * a {@link ClientIdentifier} which corresponds to an outdated generation. + * + * @author Robert Varga + */ +@Beta +public final class RetiredGenerationException extends RequestException { + private static final long serialVersionUID = 1L; + + public RetiredGenerationException(final long newGeneration) { + super("Originating generation was superseded by " + Long.toUnsignedString(newGeneration)); + } + + @Override + public boolean isRetriable() { + return false; + } +} diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/actors/dds/DistributedDataStoreClientBehavior.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/actors/dds/DistributedDataStoreClientBehavior.java index 2b5e6753be..917e759a98 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/actors/dds/DistributedDataStoreClientBehavior.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/actors/dds/DistributedDataStoreClientBehavior.java @@ -64,6 +64,11 @@ final class DistributedDataStoreClientBehavior extends ClientActorBehavior imple // // + @Override + protected void haltClient(final Throwable cause) { + // FIXME: Add state flushing here once we have state + } + private void createLocalHistory(final CreateLocalHistoryCommand command) { final CompletableFuture future = command.future(); final LocalHistoryIdentifier historyId = new LocalHistoryIdentifier(getIdentifier(), nextHistoryId++); @@ -80,7 +85,7 @@ final class DistributedDataStoreClientBehavior extends ClientActorBehavior imple } else if (command instanceof GetClientRequest) { ((GetClientRequest) command).getReplyTo().tell(new Status.Success(this), ActorRef.noSender()); } else if (SHUTDOWN.equals(command)) { - // Add shutdown procedures here + // FIXME: Add shutdown procedures here return null; } else { LOG.warn("{}: ignoring unhandled command {}", persistenceId(), command); diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/actors/client/ClientActorBehavior.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/actors/client/ClientActorBehavior.java index b770b99871..1d812b7590 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/actors/client/ClientActorBehavior.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/actors/client/ClientActorBehavior.java @@ -11,7 +11,12 @@ import com.google.common.annotations.Beta; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opendaylight.controller.cluster.access.concepts.ClientIdentifier; +import org.opendaylight.controller.cluster.access.concepts.RequestException; +import org.opendaylight.controller.cluster.access.concepts.RequestFailure; +import org.opendaylight.controller.cluster.access.concepts.RetiredGenerationException; import org.opendaylight.yangtools.concepts.Identifiable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A behavior, which handles messages sent to a {@link AbstractClientActor}. @@ -23,12 +28,24 @@ import org.opendaylight.yangtools.concepts.Identifiable; @Beta public abstract class ClientActorBehavior extends RecoveredClientActorBehavior implements Identifiable { + private static final Logger LOG = LoggerFactory.getLogger(ClientActorBehavior.class); + protected ClientActorBehavior(final @Nonnull ClientActorContext context) { super(context); } @Override final ClientActorBehavior onReceiveCommand(final Object command) { + if (command instanceof RequestFailure) { + final RequestFailure failure = (RequestFailure) command; + final RequestException cause = failure.getCause(); + if (cause instanceof RetiredGenerationException) { + LOG.error("{}: current generation {} has been superseded", persistenceId(), getIdentifier(), cause); + haltClient(cause); + return null; + } + } + // TODO: any client-common logic (such as validation and common dispatch) needs to go here return onCommand(command); } @@ -38,6 +55,16 @@ public abstract class ClientActorBehavior extends RecoveredClientActorBehavior